--- title: "Custom Animations Overview" ms.date: "03/30/2017" helpviewer_keywords: - "custom classes [WPF], animation" - "key frames [WPF], custom" - "custom key frames [WPF]" - "animation [WPF], custom classes" - "custom animation classes [WPF]" ms.assetid: 9be69d50-3384-4938-886f-08ce00e4a7a6 --- # Custom Animations Overview This topic describes how and when to extend the [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] animation system by creating custom key frames, animation classes, or by using per-frame callback to bypass it. ## Prerequisites To understand this topic, you should be familiar with the different types of animations provided by the [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)]. For more information, see the From/To/By Animations Overview, the [Key-Frame Animations Overview](key-frame-animations-overview.md), and the [Path Animations Overview](path-animations-overview.md). Because the animation classes inherit from the class, you should be familiar with objects and how to inherit from . For more information, see the [Freezable Objects Overview](../advanced/freezable-objects-overview.md). ## Extending the Animation System There are a number of ways to extend the [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] animation system, depending on the level of built-in functionality you want to use. There are three primary extensibility points in the [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] animation engine: - Create a custom key frame object by inheriting from one of the *\*KeyFrame classes, such as . This approach uses most of the built-in functionality of the [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] animation engine. - Create your own animation class by inheriting from or one of the *\*AnimationBase classes. - Use per-frame callback to generate animations on a per-frame basis. This approach completely bypasses the animation and timing system. The following table describes some the scenarios for extending the animation system. |When you want to...|Use this approach| |-------------------------|-----------------------| |Customize the interpolation between values of a type that has a corresponding *\*AnimationUsingKeyFrames|Create a custom key frame. For more information, see the [Create a Custom Key Frame](#createacustomkeyframe) section.| |Customize more than just the interpolation between values of a type that has a corresponding *\*Animation.|Create a custom animation class that inherits from the *\*AnimationBase class that corresponds to the type you want to animate. For more information, see the [Create a Custom Animation Class](#createacustomanimationtype) section.| |Animate a type that has no corresponding [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] animation|Use an or create a class that inherits from . For more information, see the [Create a Custom Animation Class](#createacustomanimationtype) section.| |Animate multiple objects with values that are computed each frame and are based on the last set of object interactions|Use per-frame callback. For more information, see the [Create a Use Per-Frame Callback](#useperframecallback) section.| ## Create a Custom Key Frame Creating a custom key frame class is the simplest way to extend the animation system. Use this approach when you want to a different interpolation method for a key-frame animation. As described in the [Key-Frame Animations Overview](key-frame-animations-overview.md), a key-frame animation uses key frame objects to generate its output values. Each key frame object performs three functions: - Specifies a target value using its property. - Specifies the time at which that value should be reached using its property. - Interpolates between the value of the previous key frame and its own value by implementing the InterpolateValueCore method. **Implementation Instructions** Derive from the *\*KeyFrame abstract class and implement the InterpolateValueCore method. The InterpolateValueCore method returns the current value of the key frame. It takes two parameters: the value of the previous key frame and a progress value that ranges from 0 to 1. A progress of 0 indicates the key frame has just started, and a value of 1 indicates that the key frame has just completed and should return the value specified by its property. Because the *\*KeyFrame classes inherit from the class, you must also override core to return a new instance of your class. If the class does not use dependency properties to store its data or it requires extra initialization after creation, you might need to override additional methods; see the [Freezable Objects Overview](../advanced/freezable-objects-overview.md) for more information. After you've created your custom *\*KeyFrame animation, you can use it with the *\*AnimationUsingKeyFrames for that type. ## Create a Custom Animation Class Creating your own animation type gives you more control over how an object in animated. There are two recommended ways to create your own animation type: you can derive from the class or the *\*AnimationBase class. Deriving from the *\*Animation or *\*AnimationUsingKeyFrames classes is not recommended. ### Derive from \AnimationBase Deriving from a *\*AnimationBase class is the simplest way to create a new animation type. Use this approach when you want to create a new animation for type that already has a corresponding *\*AnimationBase class. **Implementation Instructions** Derive from a *\*Animation class and implement the GetCurrentValueCore method. The GetCurrentValueCore method returns the current value of the animation. It takes three parameters: a suggested starting value, a suggested ending value, and an , which you use to determine the progress of the animation. Because the *\*AnimationBase classes inherit from the class, you must also override core to return a new instance of your class. If the class does not use dependency properties to store its data or it requires extra initialization after creation, you might need to override additional methods; see the [Freezable Objects Overview](../advanced/freezable-objects-overview.md) for more information. For more information, see the GetCurrentValueCore method documentation for the *\*AnimationBase class for the type that you want to animate. For an example, see the [Custom Animation Sample](https://github.com/Microsoft/WPF-Samples/tree/master/Animation/CustomAnimation) **Alternative Approaches** If you simply want to change how animation values are interpolated, considering deriving from one of the *\*KeyFrame classes. The key frame you create can be used with the corresponding *\*AnimationUsingKeyFrames provided by [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)]. ### Derive from AnimationTimeline Derive from the class when you want to create an animation for a type that doesn't already have a matching [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] animation, or you want to create an animation that is not strongly typed. **Implementation Instructions** Derive from the class and override the following members: - – If your new class is concrete, you must override to return a new instance of your class. - – Override this method to return the current value of your animation. It takes three parameters: a default origin value, a default destination value, and an . Use the to obtain the current time or progress for the animation. You can choose whether to use the default origin and destination values. - – Override this property to indicate whether your animation uses the default destination value specified by the method. - – Override this property to indicate the of output your animation produces. If the class does not use dependency properties to store its data or it requires extra initialization after creation, you might need to override additional methods; see the [Freezable Objects Overview](../advanced/freezable-objects-overview.md) for more information. The recommended paradigm (used by [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] animations) is to use two inheritance levels: 1. Create an abstract *\*AnimationBase class that derives from . This class should override the method. It should also introduce a new abstract method, GetCurrentValueCore, and override so that it validates the types of the default origin value and default destination value parameters, then calls GetCurrentValueCore. 2. Create another class that inherits from your new *\*AnimationBase class and overrides the method, the GetCurrentValueCore method that you introduced, and the property. **Alternative Approaches** If you want to animate a type that has no corresponding From/To/By animation or key-frame animation, consider using an . Because it is weakly typed, an can animate any type of value. The drawback to this approach is that only supports discrete interpolation. ## Use Per-Frame Callback Use this approach when you need to completely bypass the [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] animation system. One scenario for this approach is physics animations, where at each animation step a new direction or position of animated objects needs to be recomputed based on the last set of object interactions. **Implementation Instructions** Unlike the other approaches described in this overview, to use per-frame callback you don't need to create a custom animation or key frame class. Instead, you register for the event of the object that contains the objects you want to animate. This event handler method gets called once per frame. Each time that [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] marshals the persisted rendering data in the visual tree across to the composition tree, your event handler method is called. In your event handler, perform your whatever calculations necessary for your animation effect and set the properties of the objects you want to animate with these values. To obtain the presentation time of the current frame, the associated with this event can be cast as , which provide a property that you can use to obtain the current frame's rendering time. For more information, see the page. ## See also - - - [Property Animation Techniques Overview](property-animation-techniques-overview.md) - [Freezable Objects Overview](../advanced/freezable-objects-overview.md) - [Key-Frame Animations Overview](key-frame-animations-overview.md) - [Path Animations Overview](path-animations-overview.md) - [Animation Overview](animation-overview.md) - [Animation and Timing System Overview](animation-and-timing-system-overview.md) - [Custom Animation Sample](https://github.com/Microsoft/WPF-Samples/tree/master/Animation/CustomAnimation)