With WPF and Silverlight dependency properties can be animated using an animation to define a start and endpoint, e.g. DoubleAnimation to animate a property of type double.
If the animation shouldn’t be done in a linear fashion, a key-frame animation such as DoubleAnimationUsingKeyFrame can be used. With a key-frame animation interim points must be defined. Instead of defining key-frame animations, non-linear animations can also be defined with the DoubleAnimation type. WPF supports the AccelerationRatio and DecelerationRatio properties that define a percentage value in the timespan to be used with acceleration and deceleration. The sum of both AccelerationRatio and DecelerationRation may not exceed 1 and allow for a faster or slower start and end of the animation. There’s a restriction regarding Silverlight as these properties are not available there.
Silverlight 3 and WPF 4 have an even better story to influence the animation. With WPF 4 the animation classes support easing functions to change the animated values. The animation classes now defines the EasingFunction property of type IEasingFunction that allows assigning any object that implements this interface.
The following code snippets animates an ellipse using the easing function from the ElasticEase class. The ElasticEase class defines Springiness and Oscillations properties to change the elastic behavior.
<Ellipse x:Name="myEllipse" Fill="Red" Width="30" Height="30"
Canvas.Left="100" Canvas.Top="150">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation From="30" To="500" Duration="00:00:4"
Storyboard.TargetName="myEllipse"
Storyboard.TargetProperty="(Canvas.Left)">
<DoubleAnimation.EasingFunction>
<ElasticEase x:Name="myElasticEase" Oscillations="3"
Springiness="1" EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
.NET offers several different easing functions to influence the animation. ElasticEase creates an animation that looks like a spring oscillating back and forth.
Classes that offer easing functionality implement the interface IEasingFunction. IEasingFunction defines the method Ease. Ease receives a time from the animation and returns the value that the animation should have that point in time. Usually there’s no need to implement the interface IEasingFunction directly but derive from the base class EasingFunctionBase instead. The method EaseInCore needs to be overridden deriving from this base class.
All the classes that derive from EasingFunctionBase contain the EasingMode property of type EasingMode. EasingMode allows setting if the easing function should influence in special the in, out, or both in and out of the animation by setting the enumeration values EaseIn, EaseOut, or EaseInOut.
Other classes available that offer easing functionality are BounceEase that animates a bouncing effect. The formulas of some of the easing functions are listed here.
Ease function | Formula |
BackEase | f(t) = t³ – t * a * sin(t * π) |
SineEase | f(t) = 1 - [sin(1-t) * π/2] |
QuadraticEase | f(t) = t2 |
CubicEase | f(t) = t3 |
QuarticEase | f(t) = t4 |
QuinticEase | f(t) = t5 |
PowerEase | f(t) = t * power |
You can compare the different easing functions with my Silverlight easing animation sample application. Here you can select the different easing functions and configure the easing function if applicable, and animate an ellipse from one line of the screen to another one.
More information on WPF and Silverlight in my Silverlight and WPF workshops and in my new book Professional C# 4 with .NET 4.
Christian
Nice Demo!
There is also another way to easily add easing in the code behind. Check out Artefact Animator - http://artefactanimator.codeplex.com/. It doesn't use storyboards but it gives you a simple syntax that mimics Tweener for Flash. It also uses the same code for the Silverlight and WPF version.
For Example:
ArtefactAnimator.AddEase(element, Canvas.LeftProperty, 250, .7, AnimationTransitions.CubicEaseOut, 0);
Posted by: Jesse Graupman | 04/03/2010 at 11:44 PM
That's also a nice sample, Jesse :-)
Posted by: Christian | 04/06/2010 at 12:33 AM
hey, man, thanks!
You spared me from a lot of try and error coding!
World is better having people like you!
Posted by: Jack | 07/08/2012 at 07:35 PM