Información general sobre animaciones personalizadas

En este tema se describe cómo y cuándo extender el sistema de animación de WPF creando fotogramas clave personalizados o clases de animación, o utilizando la devolución de llamada por fotograma para omitirlo.

Requisitos previos

Para entender este tema, debe estar familiarizado con los distintos tipos de animación que ofrece WPF. Para más información, consulte From/To/By Animations Overview (Información general sobre animaciones From/To/By), Key-Frame Animations Overview (Información general sobre animaciones de fotogramas clave) e Información general sobre animaciones en trazados.

Dado que las clases de animación heredan de la clase Freezable, debe estar familiarizado con los objetos Freezable y con cómo heredar de Freezable. Para más información, consulte Freezable Objects Overview (Información general sobre objetos Freezable).

Extender el sistema de animación

Hay varias maneras de extender el sistema de animación de WPF, dependiendo del nivel de funcionalidad integrada que se desee utilizar. Existen tres puntos principales de extensibilidad en el motor de animación de WPF:

  • Crear un objeto de fotograma clave personalizado heredando de una de las clases *<Type>*KeyFrame, como DoubleKeyFrame. En este enfoque se utiliza la mayoría de la funcionalidad integrada del motor de animación de WPF.

  • Crear su propia clase de animación heredando de AnimationTimeline o de una de las clases *<Type>*AnimationBase.

  • Utilizar la devolución de llamada por fotograma para generar animaciones fotograma a fotograma. En este enfoque se omite completamente el sistema de animación y control de tiempo.

En la tabla siguiente se describen algunos de los escenarios para extender el sistema de animación.

Si desea... Utilice este enfoque
Personalizar la interpolación entre valores de un tipo que tiene un *<Type>*AnimationUsingKeyFrames correspondiente Crear un fotograma clave personalizado. Para más información, consulte la sección Crear un fotograma clave personalizado.
Personalizar algo más que la interpolación entre valores de un tipo que tiene una clase *<Type>*Animation correspondiente. Crear una clase de animación personalizada que herede de la clase *<Type>*AnimationBase correspondiente al tipo que desee animar. Para más información, consulte la sección Crear una clase de animación personalizada.
Animar un tipo que no tenga una animación de WPF correspondiente Usar un AnimationTimelineo crear una clase que herede de ObjectAnimationUsingKeyFrames. Para más información, consulte la sección Crear una clase de animación personalizada.
Animar varios objetos con valores que se calculan para cada fotograma y se basan en el último conjunto de interacciones de objeto Utilizar la devolución de llamada por fotograma. Para más información, consulte la sección Crear una devolución de llamada por fotograma.

Crear un fotograma clave personalizado

Crear una clase de fotograma clave personalizado es la manera más simple de extender el sistema de animación. Utilice este enfoque cuando desee utilizar un método de interpolación diferente para una animación de fotograma clave. Como se describe en Key-Frame Animations Overview (Información general sobre animaciones de fotogramas clave ), una animación de fotograma clave usa objetos de fotograma clave para generar sus valores de salida. Cada objeto de fotograma clave realiza tres funciones:

  • Especifica un valor de destino mediante su propiedad Value.

  • Especifica la hora a la que se alcanzará ese valor mediante la propiedad KeyTime.

  • Interpola entre el valor del fotograma clave anterior y su propio valor implementando el método InterpolateValueCore.

Instrucciones de implementación

Derive de la clase abstracta *<Type>*KeyFrame e implemente el método InterpolateValueCore. El método InterpolateValueCore devuelve el valor actual del fotograma clave. Acepta dos parámetros: el valor del fotograma clave anterior y un valor de progreso que oscila de 0 a 1. Un progreso de 0 indica que el fotograma clave se acaba de iniciar, y un valor de 1 indica que el fotograma clave se acaba de completar y debe devolver el valor especificado por su propiedad Value.

Dado que las clases *<Type>*KeyFrame heredan de la clase Freezable, también debe invalidar el núcleo CreateInstanceCore para devolver una nueva instancia de la clase. Si la clase no utiliza propiedades de dependencia para almacenar sus datos o requiere que se inicialice otra vez después de haberse creado, es posible que tenga que invalidar otros métodos; consulte Freezable Objects Overview (Información general sobre objetos Freezable).

Después de haber creado la animación personalizada *<Type>*KeyFrame, puede usarla con el *<Type>*AnimationUsingKeyFrames correspondiente a ese tipo.

Crear una clase de animación personalizada

Crear su propio tipo de animación le ofrece más control sobre cómo se anima un objeto. Hay dos maneras recomendadas de crear su propio tipo de animación: puede derivar de las clases AnimationTimeline o *<Type>*AnimationBase. No se recomienda derivar de las clases *<Type>*Animation o *<Type>*AnimationUsingKeyFrames.

Derivar de <Type>AnimationBase

Derivar de una clase *<Type>*AnimationBase es la manera más sencilla de crear un nuevo tipo de animación. Utilice este enfoque cuando desee crear una nueva animación para un tipo que ya tiene una clase *<Type>*AnimationBase correspondiente.

Instrucciones de implementación

Derive de una clase *<Type>*Animation e implemente el método GetCurrentValueCore. El método GetCurrentValueCore devuelve el valor actual de la animación. Acepta tres parámetros: un valor inicial sugerido, un valor final sugerido y un AnimationClock, que se utiliza para determinar el progreso de la animación.

Dado que las clases *<Type>*AnimationBase heredan de la clase Freezable, también debe invalidar el núcleo CreateInstanceCore para devolver una nueva instancia de la clase. Si la clase no utiliza propiedades de dependencia para almacenar sus datos o requiere que se inicialice otra vez después de haberse creado, es posible que tenga que invalidar otros métodos; consulte Freezable Objects Overview (Información general sobre objetos Freezable).

Para más información, consulte la documentación del método GetCurrentValueCore para la clase *<Type>*AnimationBase para el tipo que desee animar. Para ver un ejemplo, consulte el ejemplo de animación personalizada

Enfoques alternativos

Si simplemente desea cambiar la forma en que se interpolan los valores de animación, puede que sea conveniente derivar de una de las clases *<Type>*KeyFrame. El fotograma clave que se cree puede usarse con las clases *<Type>*AnimationUsingKeyFrames correspondientes proporcionadas por WPF.

Derivar de AnimationTimeline

Derive de la clase AnimationTimeline cuando desee crear una animación para un tipo que no tenga ya una animación de WPF correspondiente o cuando desee crear una animación que no esté fuertemente tipada.

Instrucciones de implementación

Debe derivar de la clase AnimationTimeline e invalidar los siguientes miembros:

  • CreateInstanceCore: si la nueva clase es concreta, debe invalidar CreateInstanceCore para devolver una nueva instancia de la clase.

  • GetCurrentValue: invalide este método para devolver el valor actual de su animación. Acepta tres parámetros: un valor de origen predeterminado, un valor de destino predeterminado y un AnimationClock. Utilice el AnimationClock para obtener la hora actual o el progreso de la animación. Puede elegir si desea usar los valores de origen y destino predeterminados.

  • IsDestinationDefault: invalide esta propiedad para indicar si la animación usa el valor de destino predeterminado especificado por el método GetCurrentValue.

  • TargetPropertyType: invalide esta propiedad para indicar el Type de salida que produce la animación.

Si la clase no utiliza propiedades de dependencia para almacenar sus datos o requiere que se inicialice otra vez después de haberse creado, es posible que tenga que invalidar otros métodos; consulte Freezable Objects Overview (Información general sobre objetos Freezable).

El paradigma recomendado (utilizado por las animaciones de WPF) es usar dos niveles de herencia:

  1. Cree una clase *<Type>*AnimationBase abstracta que derive de AnimationTimeline. Esta clase debe invalidar el método TargetPropertyType. También debe introducir un nuevo método abstracto, GetCurrentValueCore e invalidar GetCurrentValue para validar el valor de origen y los parámetros de los valores de destino predeterminados; por último, llama a GetCurrentValueCore.

  2. Cree otra clase que herede de la nueva clase *<Type>*AnimationBase e invalide el método CreateInstanceCore, el método GetCurrentValueCore que ha introducido y la propiedad IsDestinationDefault.

Enfoques alternativos

Si desea animar un tipo que no tenga ninguna animación From/To/By ni animación de fotograma clave correspondiente, considere la posibilidad de usar ObjectAnimationUsingKeyFrames. Al no tener establecimiento inflexible de tipos, ObjectAnimationUsingKeyFrames puede animar cualquier tipo de valor. El inconveniente de este enfoque es que ObjectAnimationUsingKeyFrames solo admite la interpolación discreta.

Utilizar la devolución de llamada por fotograma

Utilice este enfoque cuando necesite omitir completamente el sistema de animación de WPF. Un escenario para este enfoque son las animaciones físicas, en las cuales es preciso volver a calcular una nueva dirección o posición de los objetos animados en cada paso de la animación de acuerdo con el último conjunto de interacciones de objeto.

Instrucciones de implementación

Al contrario que los demás enfoques descritos en esta información general, para utilizar la devolución de llamada por fotograma no se necesita crear una clase personalizada de animación o de fotograma clave.

En su lugar, se efectúa el registro para el evento Rendering del objeto que contiene los objetos que se desean animar. Se llama a este método de control de eventos una vez por cada fotograma. Cada vez que WPF serializa los datos de representación conservados en el árbol visual hasta el árbol de composición, se llama a este método de controlador de eventos.

En el controlador de eventos, realice los cálculos necesarios para el efecto de animación y establezca las propiedades de los objetos que desea animar con estos valores.

Para obtener el tiempo de presentación para el fotograma actual, el EventArgs asociado con este evento se puede convertir a RenderingEventArgs, que proporciona una propiedad RenderingTime que puede usar para obtener el tiempo de presentación del fotograma actual.

Para más información, consulte la página sobre Rendering.

Vea también