Animaciones con guion gráfico

Animaciones de guión gráfico (XAML)

[ Este artículo está destinado a desarrolladores de Windows 8.x y Windows Phone 8.x que escriben aplicaciones de Windows en tiempo de ejecución. Si estás desarrollando para Windows 10, consulta la documentación más reciente

Las animaciones de guión gráfico no son solo animaciones en un sentido visual. Una animación de guión gráfico es una forma de cambiar el valor de una propiedad de dependencia como una función de tiempo. Una de las razones principales por las que quizás necesites una animación de guión gráfico que no provenga de la Biblioteca de animaciones es para definir el estado visual de un control, como parte de una plantilla de control o una definición de página.

Guía básica: Relación de este tema con los demás. Consulta:

Diferencias con Silverlight y WPF

Si estás familiarizado con Microsoft Silverlight o Windows Presentation Foundation (WPF), lee esta sección; si no, puedes saltártela.

En general, la creación de animaciones de guión gráfico en una aplicación de Windows en tiempo de ejecución es como Silverlight o WPF. Aunque existe una serie de diferencias importantes:

  • Las animaciones de guión gráfico no son la única forma de animar visualmente una interfaz de usuario para una aplicación. Tampoco representan la forma de animación más sencilla para los desarrolladores de aplicaciones. En lugar de usar animaciones de guión gráfico, muchas veces un procedimiento de diseño más recomendado es usar animaciones de tema y animaciones de transición. Estas animaciones pueden crear rápidamente animaciones recomendadas para la interfaz de usuario sin necesidad de meterse en la complejidad que implica la selección de propiedades de animación como destino. Para más información, consulta el tema de inicio rápido: animación de la interfaz de usuario con animaciones de la biblioteca.
  • En Windows en tiempo de ejecución, muchos controles XAML incluyen animaciones de tema y animaciones de transición como parte de su comportamiento integrado. Para la mayoría, los controles de WPF y Silverlight no tenían un comportamiento de animación predeterminado.
  • No todas las animaciones personalizadas que creas pueden ejecutarse de forma predeterminada en una aplicación de Windows en tiempo de ejecución, si el sistema de animación determina que la animación puede provocar un mal rendimiento en la interfaz de usuario. Las animaciones que según el sistema pueden afectar al rendimiento se llaman animaciones dependientes. Son dependientes porque la temporización de tu animación funciona directamente en contra del subproceso de la interfaz de usuario, que además es donde la entrada del usuario activo y otras actualizaciones intentan aplicar los cambios en tiempo de ejecución a la interfaz de usuario. Una animación dependiente que consuma muchos recursos del sistema en el subproceso de la interfaz de usuario puede hacer que la aplicación parezca que no responde en ciertas situaciones. Si tu animación produce un cambio en el diseño o tiene el potencial para afectar al rendimiento del subproceso de la interfaz de usuario, tendrás que habilitar de forma explícita la animación para poder verla en ejecución. Ese es precisamente el cometido de la propiedad EnableDependentAnimation en clases de animación específicas. Consulta Animaciones dependientes e independientes para obtener más información.
  • Actualmente no se admiten funciones de aceleración personalizadas en Windows en tiempo de ejecución.

Definir de animaciones de guion gráfico

Una animación de guion gráfico es una forma de cambiar el valor de una propiedad de dependencia como una función de tiempo. La propiedad que estás animando no siempre es una propiedad que afecta directamente la interfaz de usuario de tu aplicación. Pero dado que XAML está relacionado con la definición de la interfaz de usuario para una aplicación, por lo general, se trata de una propiedad que está relacionada con la interfaz de usuario que estás animando. Por ejemplo, puedes animar el ángulo de RotateTransform o el valor de color de fondo de un botón.

Una de las razones principales por la que quizás quieras definir una animación de guión gráfico es porque eres un autor de control o deseas realizar nuevamente la plantilla de un control, y estás definiendo estados visuales. Para obtener más información, consulta el tema sobre animaciones de guión gráfico para estados visuales.

Ya sea que quieras definir estados visuales o una animación personalizada para una aplicación, los conceptos y las API para las animaciones de guión gráfico que se describen en este tema se aplican para ambos casos.

Para que pueda ser animada, la propiedad que estás seleccionando como destino con una animación de guion gráfico debe ser una propiedad de dependencia. Una propiedad de dependencia es una función clave de la implementación XAML de Windows en tiempo de ejecución. Las propiedades que se pueden escribir de los elementos más comunes de la interfaz de usuario se implementan generalmente como propiedades de dependencia, de modo que puedas animarlas, aplicar valores de enlazado a datos, o aplicar un Style y seleccionar como destino la propiedad con un Setter. Si quieres obtener más información sobre cómo funcionan las propiedades de dependencia, consulta Introducción a las propiedades de dependencia.

La mayoría de las veces, defines una animación de guión gráfico al escribir XAML. Si usas una herramienta como Microsoft Visual Studio, generará el XAML para ti. También es posible definir una animación de guión gráfico mediante código, pero no es tan común.

Veamos un ejemplo simple. En este ejemplo de XAML, la propiedad Opacity se anima en un objeto Rectangle determinado.



        <!-- Animates the rectangle's opacity. -->
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimation
              Storyboard.TargetName="MyAnimatedRectangle"
              Storyboard.TargetProperty="Opacity"
              From="1.0" To="0.0" Duration="0:0:1"/>
        </Storyboard>
// a different area of the XAML
    <Rectangle x:Name="MyAnimatedRectangle"
      Width="300" Height="200" Fill="Blue"/>

Identificar el objeto que se va a animar

En el ejemplo anterior, el guión gráfico animaba la propiedad Opacity de un Rectangle. No debes declarar las animaciones en el objeto en sí. En cambio, tienes que hacerlo dentro de la definición de animación de un guión gráfico. Los guiones gráficos, por lo general, se definen en el XAML que no está junto a la definición de interfaz de usuario de XAML del objeto que quieres animar. En cambio, normalmente se establecen como un recurso XAML.

Para conectar una animación a un destino, debes hacer referencia al destino mediante su nombre de programación de identificación. Siempre debes aplicar el atributo x:Name en la definición de interfaz de usuario de XAML para nombrar el objeto que quieres animar. Luego, debes seleccionar como destino el objeto que quieres animar mediante la configuración de Storyboard.TargetName dentro de la definición de animación. Para el valor de Storyboard.TargetName, usa la cadena de nombre del objeto de destino, que es el que estableciste antes en otra parte con el atributo x:Name.

Seleccionar como destino la propiedad de dependencia que se va a animar

Establece un valor para Storyboard.TargetProperty en la animación. De esta forma, se determina qué propiedad específica del objeto de destino se anima.

A veces debes seleccionar como destino una propiedad que no es una propiedad inmediata del objeto de destino, pero que se anida más profundamente en una relación de objeto-propiedad. Muchas veces debes hacer esto para explorar en profundidad un conjunto de objetos de contribución y valores de propiedades hasta que puedas hacer referencia a un tipo de propiedad que se pueda animar (Double, Point, Color). Este concepto se denomina selección indirecta de destino y la sintaxis para seleccionar una propiedad como destino de esta manera se conoce como ruta de propiedad.

Observa el siguiente ejemplo. Un escenario común para una animación de guión gráfico es cambiar el color de una parte de la interfaz de usuario o el control de una aplicación para representar que el control tiene un estado en particular. Supongamos que quieres animar el Foreground de un TextBlock, de modo que cambie de rojo a verde. Seguro que esperas que aparezca ColorAnimation. Estás en lo cierto. Sin embargo, ninguna de las propiedades de los elementos de la interfaz de usuario que afectan el color del objeto son realmente del tipo Color. Por el contrario, son del tipo Brush. Por lo tanto, lo que en realidad debes seleccionar como destino para la animación es la propiedad Color de la clase SolidColorBrush, que es un tipo derivado de Brush que se usa normalmente para estas propiedades de interfaz de usuario relacionadas con color. Este es el aspecto en términos de formación de una ruta de acceso de propiedades para la selección de propiedad de tu animación:


    <Storyboard x:Name="myStoryboard">
    <ColorAnimation Storyboard.TargetName="tb1" From="Red" To="Green"
      Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
   />
    </Storyboard>

Aquí te mostramos lo que debes tener en cuenta en la sintaxis en cuanto a sus partes:

  • Cada conjunto de paréntesis () encierra el nombre de una propiedad.
  • Dentro del nombre de la propiedad, hay un punto, y ese punto separa un nombre de tipo y un nombre de propiedad, para que la propiedad que estás identificando no sea ambigua.
  • El punto del medio, el que está fuera de los paréntesis, es un paso. Lo que la sintaxis interpreta es tomar el valor de la primera propiedad (que es un objeto), meterse en el modelo de su objeto y seleccionar como destino una subpropiedad específica del valor de la primera propiedad.

Aquí hay una lista de escenarios de selección de destino de animaciones en los que probablemente uses la selección indirecta de destino de propiedades y algunas cadenas de rutas de acceso de propiedades que se aproximan a la sintaxis que debes usar:

Notarás que en algunos de estos ejemplos se usan corchetes para encerrar los números. Es un indizador. Indica que el nombre de la propiedad que precede tiene una colección como valor y que quieres un elemento (identificado por un índice basado en cero) de la colección.

También puedes animar propiedades adjuntas de XAML. Siempre encierra el nombre completo de la propiedad adjunta entre paréntesis, por ejemplo, (Canvas.Left). Para obtener más información, consulta Animación de propiedades adjuntas de XAML.

Para obtener más información sobre cómo usar una ruta de propiedad para la selección indirecta como destino de la propiedad que deseas animar, consulta Sintaxis de property-path o Storyboard.TargetProperty attached property.

Tipos de animación

El sistema de animación de Windows en tiempo de ejecución tiene tres tipos específicos a los que se pueden aplicar animaciones de guión gráfico:

También hay un tipo de animación Object generalizada para los valores de referencia del objeto, que analizaremos más adelante.

Especificar los valores animados

Hasta el momento te hemos mostrado cómo seleccionar como destino el objeto y la propiedad que quieras animar, pero aún no hemos descrito qué hace la animación en el valor de la propiedad cuando se ejecuta.

Los tipos de animación que hemos descrito muchas veces se conocen como animaciones From/To/By. Esto significa que la animación cambia el valor de una propiedad, a lo largo del tiempo, con una o varias de las entradas que provienen de la definición de la animación:

  • El valor comienza en el valor From. Si no especificas un valor From, el valor inicial es cualquier valor que la propiedad animada tenga en el momento anterior a que se ejecute la animación. Puede ser un valor predeterminado, un valor de un estilo o una plantilla, o un valor específicamente aplicado por código de aplicación o una definición de interfaz de usuario de XAML.
  • Al final de la animación, el valor es To.
  • O bien, para especificar un valor final relativo al valor inicial, configura la propiedad By. Deberías configurar esto en lugar de la propiedad To.
  • Si no especificas un valor To o un valor By, el valor final es cualquier valor que la propiedad animada tenga en el momento anterior a que se ejecute la animación. En este caso, es mejor tener un valor From porque, de lo contrario, la animación no cambiará el valor. Los valores iniciales y finales son los mismos.
  • Generalmente, una animación tiene al menos uno de los valores From, By o To, pero nunca los tres juntos.

Volvamos al ejemplo de XAML anterior y observemos nuevamente los valores From y To, y Duration. En el ejemplo se está animando la propiedad Opacity, y el tipo de propiedad de Opacity es Double. Entonces, la animación que debemos usar aquí es DoubleAnimation.

From="1.0" To="0.0" especifica que cuando la animación se ejecuta, la propiedad Opacity comienza con el valor 1 y anima hasta el 0. En otras palabras, en términos de lo que estos valores Double representan para la propiedad Opacity, la animación provocará que el objeto comience siendo opaco y después se atenúe hasta convertirse en transparente.


...
    <Storyboard x:Name="myStoryboard">
    <DoubleAnimation
    Storyboard.TargetName="MyAnimatedRectangle"
    Storyboard.TargetProperty="Opacity"
    From="1.0" To="0.0" Duration="0:0:1"/>
    </Storyboard>
...

Duration="0:0:1" especifica la duración de la animación, es decir, la rapidez con la que se atenúa el rectángulo. Se especifica una propiedad Duration en la forma de hours:minutes:seconds. La duración en este ejemplo es de un segundo.

Para obtener más información sobre los valores Duration y la sintaxis XAML, consulta Duration.

Nota  En el ejemplo que mostramos, si estuvieras seguro de que el estado inicial del objeto que se está animando tiene siempre el valor Opacity establecido en 1, ya sea a través de un conjunto explícito o predeterminado, podrías omitir el valor From, la animación usaría el valor inicial implícito y resultado sería el mismo.
 

From/To/By pueden tener valores null

Antes mencionamos que puedes omitir From, To o By y, por ende, usar los valores actuales no aminados como sustitutos para un valor que falta. Las propiedades From, To o By de una animación no son del tipo que puedas adivinar. Por ejemplo, el tipo de la propiedad DoubleAnimation.To no es Double. En cambio, es un Nullable para Double. Y su valor predeterminado es null, no 0. Ese valor null es la forma en la que el sistema de animación distingue que no has establecido específicamente un valor para una propiedad From, To o By. Las extensiones del componente Visual C++ (C++/CX) no tienen un tipo Nullable, por lo que usan IReference en su lugar.

Otras propiedades de una animación

Las próximas propiedades que se describen en esta sección son todas opcionales, ya que tienen valores predeterminados que son adecuados para la mayoría de las animaciones.

AutoReverse

Si no especificas AutoReverse o RepeatBehavior en una animación, la animación se ejecutará una vez y se ejecutará durante el tiempo especificado en Duration.

La propiedad AutoReverse especifica si se reproduce la escala de tiempo a la inversa después de que llega al final de su Duration. Si lo estableces como true, la animación se invierte después de que llega al final del valor de Duration declarado, y cambia el valor de su valor final (To) nuevamente a su valor inicial (From). Esto significa que la animación se ejecuta de manera eficaz durante el doble de tiempo de su Duration.

RepeatBehavior

La propiedad RepeatBehavior especifica cuántas veces se reproduce una escala de tiempo, o una duración más prolongada dentro de la cual debe repetirse la escala de tiempo. De manera predeterminada, una escala de tiempo tiene un recuento de iteraciones de "1x", lo que significa que se reproduce una vez para su Duration y no se repite.

Puedes lograr que la animación ejecute varias iteraciones, por ejemplo, un valor de "3x" provoca que la animación se ejecute tres veces. O bien, puedes especificar una Duration diferente para RepeatBehavior. Esa Duration no debe ser mayor que la Duration de la animación en sí para que sea eficaz. Por ejemplo, si especificas un RepeatBehavior de "0:0:10", para una animación que tiene una Duration de "0:0:2", la animación se repite cinco veces. Si no se dividen en partes iguales, la animación se trunca en el momento en que se alcanza el tiempo de RepeatBehavior, que puede ser en la mitad. Por último, puedes especificar el valor especial "Forever", que provoca que la animación se ejecute de manera indefinida hasta que se la detenga.

Para obtener más información sobre los valores RepeatBehavior y la sintaxis XAML, consulta RepeatBehavior.

FillBehavior="Stop"

De manera predeterminada, cuando una animación finaliza, la animación deja el valor de la propiedad como el valor To final o el valor modificado por By incluso después de que se supere su duración. Pero, si estableces el valor de la propiedad FillBehavior en FillBehavior.Stop, el valor del valor animado se revierte al valor que estaba antes de que se aplique la animación o, más precisamente, al valor actual eficaz determinado por el sistema de propiedades de dependencia (para obtener más información sobre esta distinción, consulta Introducción a las propiedades de dependencia).

BeginTime

De manera predeterminada, el BeginTime de una animación es "0:0:0", para que comience ni bien se ejecuta el Storyboard que contiene. Puedes cambiar esto, si el Storyboard contiene más de una animación y quieres escalonar las horas de inicio de las otras animaciones contra una animación inicial, o para crear una breve demora deliberada.

SpeedRatio

Si tienes más de una animación en un Storyboard, puedes cambiar la frecuencia de tiempo de una o varias de las animaciones relativas al Storyboard. Es el Storyboard principal que controla en última instancia de qué manera transcurre el tiempo de la Duration mientras se ejecutan las animaciones. Esta propiedad no se usa con mucha frecuencia. Para obtener más información, consulta SpeedRatio.

Definir más de una animación en un Storyboard

El contenido de un Storyboard puede comprender más de una definición de animación. Es posible que tengas más de una animación si estás aplicando animaciones relacionadas a dos propiedades del mismo objeto de destino. Por ejemplo, puedes cambiar las propiedades TranslateX y TranslateY de TranslateTransform utilizadas como RenderTransform de un elemento de interfaz de usuario. Esto generará que el elemento se traduzca diagonalmente. Para lograrlo, necesitas dos animaciones diferentes. Es posible que quieras que las animaciones formen parte del mismo Storyboard porque siempre quieres que esas dos animaciones se ejecuten juntas.

No es necesario que las animaciones sean del mismo tipo o seleccionen como destino el mismo objeto. Pueden tener distintas duraciones y no compartir ningún valor de las propiedades.

Cuando se ejecuta el Storyboard principal, se ejecutarán también cada una de las animaciones.

La clase Storyboard, en realidad, tiene muchas propiedades de animación iguales que los tipos de animación, ya que ambas comparten la clase base de la Timeline. De este modo, un Storyboard puede tener RepeatBehavior o BeginTime. Por lo general, estos valores no se configuran en un Storyboard a menos que quieras que todas las animaciones tengan ese comportamiento. Como una regla general, cualquier propiedad Timeline configurada en un Storyboard se aplica a todas sus animaciones secundarias. Si lo dejas sin configurar, el Storyboard tiene una duración implícita que se calcula desde el valor Duration de las animaciones contenidas. Una Duration configurada explícitamente en un Storyboard que es más breve que la de sus animaciones secundarias provocará que la animación se corte, algo que nadie quiere.

Un guion gráfico no puede contener dos animaciones que intenten seleccionar como destino y animar la misma propiedad en el mismo objeto. Si lo intentas, obtendrás un error en tiempo de ejecución cuando el guion gráfico intente ejecutarse. Esta restricción se aplica aunque las animaciones no se superpongan en tiempo debido a distintas duraciones y valores BeginTime deliberados. Si realmente quieres aplicar una escala de tiempo de animación más compleja a la misma propiedad en un solo guión gráfico, la forma de hacerlo es usar una animación de fotograma clave. Consulta Animaciones de fotograma clave y animaciones de función de aceleración.

El sistema de animación puede aplicar más de una animación al valor de una propiedad, si dichas entradas provienen de varios guiones gráficos. Usar este comportamiento de manera deliberada para ejecutar simultáneamente guiones gráficos no es común. Sin embargo, es posible que una animación definida por la aplicación que aplicaste a una propiedad de control modifique el valor HoldEnd de una animación que se ejecutó previamente como parte del modelo de estado visual del control.

Definir un guión gráfico como un recurso

Un Storyboard es el contenedor en el que colocas los objetos de la animación. Por lo general, defines el Storyboard como un recurso que está disponible en el objeto que quieres animar, ya sea en Resources de nivel de página o Application.Resources.

En el ejemplo siguiente se muestra de qué manera el ejemplo anterior el Storyboard formaría parte de una definición de Resources de nivel de página, donde el Storyboard es un recurso con clave de la raíz Page. Observa el atributo x:Name. Este atributo indica cómo defines un nombre de variable para el Storyboard, para que otros elementos de XAML así como el código puedan hacer referencia al Storyboard más adelante.


<Page ...>
  <Page.Resources>
        <!-- Storyboard resource: Animates a rectangle's opacity. -->
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimation
              Storyboard.TargetName="MyAnimatedRectangle"
              Storyboard.TargetProperty="Opacity"
              From="1.0" To="0.0" Duration="0:0:1"/>
        </Storyboard>
  </Page.Resources>
  <!--Page root element, UI definition-->
  <StackPanel>
    <Rectangle x:Name="MyAnimatedRectangle"
      Width="300" Height="200" Fill="Blue"/>
  </StackPanel>
</Page>

Definir recursos en la raíz XAML de un archivo XAML como page.xaml o app.xaml es una práctica común para organizar recursos con clave en tu XAML. También puedes incluir recursos en archivos independientes y combinarlos en aplicaciones o páginas. Para obtener más información, consulta Referencias a ResourceDictionary y a recursos XAML.

Nota  El XAML de Windows en tiempo de ejecución admite la identificación de recursos con el atributo x:Key o el atributo x:Name. Usar el atributo x:Name es más común para un Storyboard, porque posiblemente quieras hacer referencia a él eventualmente por un nombre de variable, y llamar a su método Begin y ejecutar las animaciones. Si usas el atributo x:Key, deberás usar los métodos ResourceDictionary como el indizador Item para recuperarlo como un recurso con clave y después convertir el objeto recuperado en Storyboard para usar los métodos Storyboard.
 

También puedes colocar tus animaciones en una unidad del Storyboard cuando declares las animaciones de estado visual para la apariencia visual de un control. En ese caso, los elementos de Storyboard que definas irán en un contenedor de VisualState anidado más profundamente en un Style (el Style que es el recurso con clave). No necesitas una clave o un nombre para tu Storyboard en este caso porque es el VisualState quien tiene un nombre de destino al que puede invocar el VisualStateManager. Los estilos para los controles a menudo se incluyen en archivos ResourceDictionary XAML separados en vez de colocarse en una colección de Resources de una página o aplicación. Para obtener más información, consulta el tema sobre animaciones de guión gráfico para estados visuales.

Animaciones dependientes e independientes

En este punto debemos introducir algunas cuestiones importantes sobre el funcionamiento del sistema de animación. En particular, la animación interactúa fundamentalmente con la forma en la que una aplicación de Windows en tiempo de ejecución aparece en la pantalla y la forma en la que esa representación usa subprocesos. Una aplicación de Windows en tiempo de ejecución siempre tiene un subproceso de interfaz de usuario principal y este subproceso es responsable de actualizar la pantalla con la información actual. Además, una aplicación de Windows en tiempo de ejecución tiene un subproceso de composición, que se usa para precalcular los diseños inmediatamente antes de que se muestren. Cuando animas la interfaz de usuario, existe un potencial de generar mucho trabajo para el subproceso de la interfaz de usuario. El sistema debe volver a dibujar grandes áreas de la pantalla usando intervalos de tiempo bastante cortos entre cada actualización. Esto es necesario para capturar el último valor de propiedad de la propiedad animada. Si no eres cuidadoso, hay riesgos de que una animación pueda hacer que la interfaz de usuario tenga menos capacidad de respuesta o impacte en el rendimiento de las demás funciones de la aplicación que se encuentran en el mismo subproceso de la interfaz de usuario.

La variedad de animación que está determinada por imponer cierto riesgo de ralentizar el subproceso de la interfaz de usuario se denomina animación dependiente. Una animación que no está sujeta a este riesgo es una animación independiente. La distinción entre animaciones dependientes e independientes no está determinada solamente por los tipos de animación (DoubleAnimation, etc.) tal como describimos anteriormente. Más bien, está determinada por las propiedades específicas que se animan y otros factores como la herencia y la composición de controles. Hay circunstancias en las que aunque una animación cambie la interfaz de usuario, la animación puede tener un impacto mínimo en el subproceso de la interfaz de usuario y, en cambio, puede controlarse con el subproceso de composición como una animación independiente.

Una animación es independiente si presenta alguna de estas características:

Precaución  Para que la animación se trate como independiente, debes establecer explícitamente Duration="0". Por ejemplo, si quitas Duration="0" de este XAML, la animación se trata como dependiente, aunque el KeyTime del marco es "0:0:0".
 

<Storyboard>
    <DoubleAnimationUsingKeyFrames
         Duration="0"
         Storyboard.TargetName="Button2"
         Storyboard.TargetProperty="Width">
         <DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="200" />
     </DoubleAnimationUsingKeyFrames>
</Storyboard>

Si tu animación no cumple con estos criterios, probablemente sea una animación dependiente. De manera predeterminada, el sistema de animación no ejecutará una animación dependiente. Por lo tanto, durante el proceso de desarrollo y prueba, es posible que no veas tu animación en ejecución. De todos modos, puedes usar este tipo de animación, pero debes habilitar de manera específica cada animación dependiente. Para habilitar una animación, establece la propiedad EnableDependentAnimation en el objeto de la animación como true. (Cada subclase de Timeline que representa una animación tiene una implementación diferente de la propiedad, pero todas se llaman EnableDependentAnimation).

El requisito de habilitar animaciones dependientes que recae sobre el desarrollador de la aplicación es un aspecto de diseño consciente del sistema de animación y la experiencia de desarrollo. Queremos que los desarrolladores estén al tanto de que las animaciones tienen un costo de rendimiento para la capacidad de respuesta de la interfaz de usuario. Las animaciones con un rendimiento pobre son difíciles de aislar y depurar en una aplicación de escala total. Por lo tanto, es mejor activar solo las animaciones dependientes que realmente necesitas para la experiencia de interfaz de usuario de tu aplicación. No queremos que sea tan fácil comprometer el rendimiento de tu aplicación por el solo hecho de incluir animaciones decorativas que usan muchos ciclos. Para obtener más información sobre sugerencias de rendimiento para la animación, consulta el tema sobre cómo suavizar las animaciones.

Como desarrollador de una aplicación, también puedes optar por aplicar una configuración en toda la aplicación que siempre deshabilite las animaciones dependientes, incluso aquellas que tienen la opción EnableDependentAnimation establecida como true. Consulta Timeline.AllowDependentAnimations.

Sugerencia  Si estás componiendo estados visuales para un control con Visual Studio, el diseñador producirá advertencias cada vez que intentes aplicar una animación dependiente a una propiedad de estado visual.
 

Iniciar y controlar una animación

Todo lo que te hemos mostrado hasta el momento no sirve en realidad para ejecutar o aplicar una animación. Hasta que la animación no se inicie y esté en ejecución, los cambios de valor que declara una animación en XAML están latentes y no se producen. Debes iniciar explícitamente una animación de alguna forma que esté relacionada con la vigencia de la aplicación o la experiencia del usuario. En el nivel más simple, inicia una animación al llamar el método Begin en el Storyboard que sea el elemento principal para la animación. No puedes llamar los métodos de XAML directamente, por lo que todo lo que hagas para habilitar las animaciones, lo estarás haciendo desde el código. Será el código que se encuentra detrás de las páginas o los componentes de tu aplicación, o quizás la lógica de tu control si estás definiendo una clase de control personalizada.

Normalmente, llamas a Begin y dejas que la animación se ejecute hasta completar su duración. Sin embargo, también puedes usar los métodos Pause, Resume y Stop para controlar el Storyboard en el tiempo de ejecución, así como otras API que se usan para escenarios de control de animación más avanzados.

Cuando llamas a Begin en un guión gráfico que contiene animaciones que se repiten indefinidamente (RepeatBehavior="Forever"), esa animación se ejecuta hasta que la página que la contiene se descarga o llamas, de manera específica, a Pause o Stop.

Iniciar una animación desde el código de la aplicación

Puedes iniciar las animaciones automáticamente o en respuesta a acciones de los usuarios. En el caso automático, generalmente usas un evento de vigencia del objeto como Loaded para que actúe como el desencadenador de la animación. El evento Loaded es un buen evento para usarlo porque en este momento la interfaz de usuario está lista para la interacción, y la animación no se cortará al comienzo porque otra parte de la interfaz de usuario ya se estaba cargando.

En este ejemplo, el evento PointerPressed está adjunto al rectángulo por lo que, cuando el usuario hace clic en el rectángulo, empieza la animación.



<Rectangle PointerPressed="Rectangle_Tapped"
  x:Name="MyAnimatedRectangle"
  Width="300" Height="200" Fill="Blue"/>

El controlador de eventos inicia el Storyboard (la animación) mediante el uso del método Begin del Storyboard.


myStoryboard.Begin();


Puedes controlar el evento Completed si quieres que se ejecute otra lógica después de que la animación haya terminado de aplicar valores. De igual modo, el método GetAnimationBaseValue resulta útil para solucionar problemas de interacción entre animaciones y sistema de propiedades.

Sugerencia  Cada vez que codifiques para un escenario de aplicaciones en el que estás iniciando una animación desde un código de aplicación, es posible que quieras revisar nuevamente si ya existe una animación o una transición en la biblioteca de animaciones para tu escenario de interfaz de usuario. Las animaciones de la biblioteca permiten una experiencia de interfaz de usuario más coherente en todas las aplicaciones de Windows en tiempo de ejecución y son más fáciles de usar.
 

Animaciones para estados visuales

El comportamiento de ejecución para un Storyboard que se usa para definir un estado visual del control difiere de cómo puede ejecutar una aplicación un guión gráfico directamente. Tal como se aplica a una definición de estado visual en XAML, el Storyboard es un elemento del VisualState que lo contiene y el estado en su totalidad está controlado mediante la API de VisualStateManager. Las animaciones se ejecutarán de acuerdo con sus valores de animación y las propiedades Timeline cuando se use el VisualState que lo contiene mediante un control. Para obtener más información, consulta el tema sobre guiones gráficos para estados visuales. Para los estados visuales, el FillBehavior aparente es diferente. Si un estado visual se cambia a otro estado, todos los cambios de propiedades aplicados por el estado visual anterior y sus animaciones se cancelan, incluso si el nuevo estado visual no aplica específicamente una nueva animación a una propiedad.

Storyboard y EventTrigger

Hay una forma de iniciar una animación que se pueda declarar completamente en XAML. Pero, esta técnica ya no se usa tanto. Es una sintaxis heredada de WPF y las versiones anteriores de Silverlight antes de admitir VisualStateManager. Esta sintaxis EventTrigger aún funciona en XAML de Windows en tiempo de ejecución por razones de importación/compatibilidad, pero solo funciona para un comportamiento desencadenador en función del evento FrameworkElement.Loaded; intentar desencadenar otros eventos arrojará excepciones o impedirá la compilación. Para obtener más información, consulta EventTrigger o BeginStoryboard.

Animación de propiedades adjuntas de XAML

No es algo habitual, pero puedes aplicar un valor animado a una propiedad adjunta XAML. Si quieres obtener más información sobre propiedades adjuntas y cómo funcionan, consulta Introducción a las propiedades adjuntas. Para seleccionar una propiedad adjunta como destino hace falta una sintaxis de property-path que incluya el nombre de la propiedad entre paréntesis. Puedes animar las propiedades adjuntas integradas tales como Canvas.ZIndex con un ObjectAnimationUsingKeyFrames que aplique valores enteros discretos. Sin embargo, existe una limitación en la implementación XAML de Windows en tiempo de ejecución y es que no puedes animar una propiedad adjunta personalizada.

Más tipos de animaciones y los pasos que deben seguirse para obtener información sobre la animación de la interfaz de usuario

Hasta ahora, hemos mostrado las animaciones personalizadas que se animan entre dos valores y después cómo interpolar de forma lineal los valores según sea necesario mientras se ejecuta la animación. Estas se denominan animaciones From/To/By. Hay otro tipo de animación que permite declarar valores intermedios que se encuentran entre el inicio y el final. Estas se denominan animaciones de fotograma clave. También hay una forma de alterar la lógica de interpolación en una animación From/To/By o una animación de fotograma clave. Esto comprende aplicar una función de aceleración. Para obtener más información sobre estos conceptos, consulta Animaciones de fotograma clave y animaciones de función de aceleración.

Temas relacionados

Guía básica para crear aplicaciones con C# y VB
Sintaxis de property-path
Introducción a las propiedades de dependencia
Animaciones de fotograma clave y animaciones de función de aceleración
Animaciones con guion gráfico para estados visuales
Inicio rápido: Plantillas de control
Storyboard
Storyboard.TargetProperty

 

 

Mostrar:
© 2017 Microsoft