Key-Frame Animations
Microsoft Silverlight will reach end of support after October 2021. Learn more.
This topic introduces you to key-frame animations in Silverlight. Key-frame animations enable you to animate using more than two target values, and control an animation's interpolation method.
This topic contains the following sections.
- Prerequisites
- What Is a Key-Frame Animation?
- Key-Frame Animation Types
- Target Values (Key Frames) and Key Times
- Interpolation Methods
- Easing Functions
- Related Topics
Prerequisites
To understand this overview, you should be familiar with Silverlight animations. For an introduction to animations, see Animation Overview.
What Is a Key-Frame Animation?
Like a From/To/By animation, a key-frame animation animates the value of a target property. It creates a transition among its target values over its Duration. However, a From/To/By animation creates a transition between two values, but a single key-frame animation can create transitions among any number of target values.
Unlike a From/To/By animation, a key-frame animation has no From, To, or By properties with which to set its target values. Instead, you describe a key-frame animation's target values by using key-frame objects. To specify the animation's target values, you create key-frame objects and add them to the animation's KeyFrames property. When the animation runs, it transitions between the frames you specified.
In addition to supporting multiple target values, some key-frame methods even support multiple interpolation methods. An animation's interpolation method defines how it transitions from one value to the next. There are three types of interpolations: discrete, linear, and splined.
To animate with a key-frame animation, you complete the following steps:
Declare the animation and specify its Duration, as you would for a From/To/By animation.
For each target value, create a key frame of the appropriate type, set its value and KeyTime, and add it to the animation's KeyFrames collection.
Associate the animation with a property, as you would with a From/To/By animation.
The following example uses a DoubleAnimationUsingKeyFrames object to animate a Rectangle element across the screen.
<Canvas>
<Canvas.Resources>
<Storyboard x:Name="myStoryboard">
<!-- Animate the TranslateTransform's X property
from 0 to 350, then 50, then 200 over 10 seconds. -->
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="MyAnimatedTranslateTransform"
Storyboard.TargetProperty="X"
Duration="0:0:10">
<!-- Using a LinearDoubleKeyFrame, the rectangle moves
steadily from its starting position to 500 over
the first 3 seconds. -->
<LinearDoubleKeyFrame Value="500" KeyTime="0:0:3" />
<!-- Using a DiscreteDoubleKeyFrame, the rectangle suddenly
appears at 400 after the fourth second of the animation. -->
<DiscreteDoubleKeyFrame Value="400" KeyTime="0:0:4" />
<!-- Using a SplineDoubleKeyFrame, the rectangle moves
back to its starting point. The animation starts out slowly at
first and then speeds up. This KeyFrame ends after the 6th
second. -->
<SplineDoubleKeyFrame KeySpline="0.6,0.0 0.9,0.00" Value="0" KeyTime="0:0:6" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Canvas.Resources>
<Rectangle MouseLeftButtonDown="Mouse_Clicked" Fill="Blue"
Width="50" Height="50">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="MyAnimatedTranslateTransform" X="0" Y="0" />
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
' When the user clicks the Rectangle, the animation
' begins.
Private Sub Mouse_Clicked(ByVal sender As Object, ByVal e As MouseEventArgs)
myStoryboard.Begin()
End Sub
// When the user clicks the Rectangle, the animation
// begins.
private void Mouse_Clicked(object sender, MouseEventArgs e)
{
myStoryboard.Begin();
}
As in a From/To/By animation, you use a Storyboard object to apply a key-frame animation to a property.
Key-Frame Animation Types
There are different animation types for different property types. To animate a property that takes a Double (such as an element's Width property), you use an animation that produces Double values. To animate a property that takes a Point, you use an animation that produces Point values, and so on.
The key-frame animation classes adhere to the following naming convention:
type_AnimationUsingKeyFrames
where type_ is the type of value that the class animates.
Silverlight provides the following key-frame animation classes.
Property type |
Corresponding key-frame animation class |
Interpolation methods supported |
---|---|---|
Discrete, Linear, Splined |
||
Discrete, Linear, Splined |
||
Discrete, Linear, Splined |
||
Discrete |
Target Values (Key Frames) and Key Times
The primary purpose of a key frame is to specify a KeyTime and a target Value. Every key-frame type (the abstract types that type the value, and the derived types that define the interpolation technique) provides these two properties.
The Value property specifies the target value for that key frame.
The KeyTime property specifies when (within the animation's Duration) a key frame's Value is reached.
When a key-frame animation begins, it iterates through its key frames in the order defined by its KeyTime properties.
If there is no key frame at time 0, the animation creates a transition between the target property's current value and the Value of the first key frame; otherwise, the animation's output value becomes the value of the first key frame.
The animation creates a transition between the Value of the first and second key frames by using the interpolation method specified by the second key frame. The transition starts at the first key frame's KeyTime and ends when the second key frame's KeyTime is reached.
The animation continues, creating transitions between each subsequent key frame and its preceding key frame.
Finally, the animation transitions to the value of the key frame with the greatest key time that is equal to or smaller than the animation's Duration.
If the animation's Duration is Automatic or its Duration is equal to the time of the last key frame, the animation ends. If the animation's Duration is greater than the key time of the last key frame, the animation holds the key-frame value until it reaches the end of its Duration. If the animation's Duration is shorter than the latest key frame, the animation enters its fill period as soon as its duration is reached.
Like all animations, a key-frame animation uses its FillBehavior property to determine whether it holds its final value when it reaches the end of its active period.
Types of Key Frames
Just as there are different types of key-frame animations for animating different property types, there are also different types of key-frame objects: one for each type of value animated and interpolation method supported. Key-frame types adhere to the following naming convention:
_interpolationMethod_typeKeyFrame
where _interpolationMethod is the interpolation method the key frame uses and _type is the type of value that the class animates.
A key-frame animation that supports all three interpolation methods will have three key-frame types that you can use. For example, you can use three key-frame types with a DoubleAnimationUsingKeyFrames: DiscreteDoubleKeyFrame, LinearDoubleKeyFrame, and SplineDoubleKeyFrame. (Interpolation methods are described in detail in Interpolation Methods.)
Target Values and Key Times Example
The following example uses the DoubleAnimationUsingKeyFrames object defined in the preceding example to demonstrate how the Value and KeyTime properties work.
The first key frame immediately sets the animation's output value to 0.
The second key frame animates from 0 to 350. It starts after the first key frame ends (at time = 0 seconds) and plays for 2 seconds, ending at time = 0:0:2.
The third key frame animates from 350 to 50. It starts when the second key frame ends (at time = 2 seconds) and plays for 5 seconds, ending at time = 0:0:7.
The fourth key frame animates from 50 to 200. It starts when the third key frame ends (at time = 7 seconds) and plays for 1 second, ending at time = 0:0:8.
Because the Duration property of the animation is set to 10 seconds, the animation holds its final value for two seconds before ending at time = 0:0:10. Because the FillBehavior property is set to Stop, when the time ends the rectangle returns to its original location.
<Canvas>
<Canvas.Resources>
<Storyboard x:Name="myStoryboard">
<!-- Animate the TranslateTransform's X property
from 0 to 350, then 50,
then 200 over 10 seconds. -->
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="MyAnimatedTranslateTransform"
Storyboard.TargetProperty="X"
Duration="0:0:10" FillBehavior="Stop">
<LinearDoubleKeyFrame Value="0" KeyTime="0:0:0" />
<LinearDoubleKeyFrame Value="350" KeyTime="0:0:2" />
<LinearDoubleKeyFrame Value="50" KeyTime="0:0:7" />
<LinearDoubleKeyFrame Value="200" KeyTime="0:0:8" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Canvas.Resources>
<Rectangle MouseLeftButtonDown="Mouse_Clicked"
Fill="Blue" Width="50" Height="50">
<Rectangle.RenderTransform>
<TranslateTransform
x:Name="MyAnimatedTranslateTransform"
X="0" Y="0" />
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
// When the user clicks the Rectangle, the animation begins.
public void Mouse_Clicked(object sender, MouseEventArgs e)
{
myStoryboard.Begin();
}
Interpolation Methods
As mentioned previously, some key-frame animations support multiple interpolation methods. An animation's interpolation describes how an animation transitions between values over its duration. By selecting which key-frame type you use with your animation, you can define the interpolation method for that key-frame segment. There are three different types of interpolation methods: linear, discrete, and splined.
Linear Interpolation
With linear interpolation, the animation progresses at a constant rate of the segment duration. For example, if a key-frame segment transitions from 0 to 10 over a duration of 5 seconds, the animation produces the values shown in the following table at the specified times.
Time |
Output value |
---|---|
0 |
0 |
1 |
2 |
2 |
4 |
3 |
6 |
4 |
8 |
4.25 |
8.5 |
4.5 |
9 |
5 |
10 |
Discrete Interpolation
With discrete interpolation, the animation function jumps from one value to the next without interpolation. If a key-frame segment transitions from 0 to 10 over a duration of 5 seconds, the animation produces the values shown in the following table at the specified times.
Time |
Output value |
---|---|
0 |
0 |
1 |
0 |
2 |
0 |
3 |
0 |
4 |
0 |
4.25 |
0 |
4.5 |
0 |
5 |
10 |
Notice how the animation does not change its output value until the very end of the segment duration.
Splined interpolation is more complex. It is described in the next section.
Splined Interpolation
Splined interpolation can be used to achieve more realistic timing effects. Because animations are so often used to imitate effects that occur in the real world, you might need fine control of the acceleration and deceleration of objects, and close manipulation of timing segments. Spline key frames enable you to animate with splined interpolation. With other key frames, you specify a Value and KeyTime. With a spline key frame, you also specify a KeySpline. The following example shows a single spline key frame for a DoubleAnimationUsingKeyFrames. Notice the KeySpline property; this property distinguishes a spline key frame from the other types of key frames.
<SplineDoubleKeyFrame Value="500"
KeyTime="0:0:7" KeySpline="0.0,1.0 1.0,0.0" />
A cubic Bezier curve is defined by a start point, an end point, and two control points. The KeySpline property of a spline key frame defines the two control points of a Bezier curve that extends from (0,0) to (1,1). The first control point controls the curve factor of the first half of the Bezier curve, and the second control point controls the curve factor of the second half of the Bezier segment. The resulting curve describes the rate of change for that spline key frame. The steeper the curve, the faster the key frame changes its values. As the curve gets flatter, the key frame changes its values more slowly.
Run the sample below to see how changing the KeySpline value effects the interpolation of the animation. Also, this sample demonstrates the effect of the KeySpline on the Bezier curve which represents the interpolation.
You might use KeySpline to simulate physical trajectories such as falling water or bouncing balls, or apply other "ease in" and "ease out" effects to motion animations. For user interaction effects like background fades or control button rebound, you might apply splined interpolation to speed up or slow down the rate of change for an animation in a specific way.
The following example specifies a KeySpline of 0,1 1,0.
<SplineDoubleKeyFrame Value="500"
KeyTime="0:0:7" KeySpline="0.0,1.0 1.0,0.0" />
The following illustration shows the Bezier curve spline.
The preceding key frame animates rapidly when it begins, slows down, and then speeds up again before it ends.
The following example specifies a KeySpline of 0.5,0.25 0.75,1.0.
<SplineDoubleKeyFrame Value="350"
KeyTime="0:0:15" KeySpline="0.25,0.5 0.75,1" />
The following illustration shows the Bezier curve.
Because the curvature of the Bezier curve changes very little, this key frame animates at an almost constant rate; it slows down somewhat toward its very end.
The following example uses a DoubleAnimationUsingKeyFrames to animate the position of rectangle. Because the DoubleAnimationUsingKeyFrames uses SplineDoubleKeyFrame objects, the transition between each key-frame value uses splined interpolation.
<Canvas>
<Canvas.Resources>
<Storyboard x:Name="myStoryboard">
<!-- Animate the TranslateTransform's X property
from its base value (0) to 500, then 200,
then 350 over 15 seconds. -->
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="SplineAnimatedTranslateTransform"
Storyboard.TargetProperty="X"
Duration="0:0:15">
<SplineDoubleKeyFrame Value="500"
KeyTime="0:0:7" KeySpline="0.0,1.0 1.0,0.0" />
<SplineDoubleKeyFrame Value="200"
KeyTime="0:0:10" KeySpline="0.0,0.0 1.0,0.0" />
<SplineDoubleKeyFrame Value="350"
KeyTime="0:0:15" KeySpline="0.25,0.5 0.75,1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Canvas.Resources>
<Rectangle MouseLeftButtonDown="Mouse_Clicked" Fill="Blue"
Width="50" Height="50">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="SplineAnimatedTranslateTransform"
X="0" Y="0" />
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
' When the user clicks the Rectangle, the animation
' begins.
Private Sub Mouse_Clicked(ByVal sender As Object, ByVal e As MouseEventArgs)
myStoryboard.Begin()
End Sub
// When the user clicks the Rectangle, the animation
// begins.
private void Mouse_Clicked(object sender, MouseEventArgs e)
{
myStoryboard.Begin();
}
Splined interpolation can be difficult to understand; experimenting with different settings can help.
Combining Interpolation Methods
You can use key frames with different interpolation types in a single key-frame animation. When two key-frame animations with different interpolations follow each other, the interpolation method of the second key frame is used to create the transition from the first value to the second. For an example that uses linear, splined, and discrete interpolation in one key-frame animation, see What Is a Key-Frame Animation?.
More About Duration and Key Times
Like other animations, key-frame animations have a Duration property. In addition to specifying the animation's Duration, you have to specify which portion of that duration is reserved for each key frame. You do this by describing a KeyTime for each of the animation's key frames. Each key frame's KeyTime specifies when that key frame ends.
The KeyTime property does not specify how long the key frame plays. The amount of time a key frame plays is determined by when the key frame ends, when the previous key frame ended, and the animation's duration.
You may use time values to specify a KeyTime. The value should be greater than or equal to 0. The following example shows an animation with a duration of 10 seconds and four key frames whose key times are specified as time values.
The first key frame animates from the base value to 100 over the first 3 seconds, ending at time = 0:0:03.
The second key frame animates from 100 to 200. It starts after the first key frame ends (at time = 3 seconds) and plays for 5 seconds, ending at time = 0:0:8.
The third key frame animates from 200 to 500. It starts when the second key frame ends (at time = 8 seconds) and plays for 1 second, ending at time = 0:0:9.
The fourth key frame animates from 500 to 600. It starts when the third key frame ends (at time = 9 seconds) and plays for 1 second, ending at time = 0:0:10.
<Canvas>
<Canvas.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="MyAnimatedTranslateTransform"
Storyboard.TargetProperty="X"
Duration="0:0:10">
<!-- KeyTime properties are expressed as TimeSpan values. -->
<LinearDoubleKeyFrame Value="100" KeyTime="0:0:3" />
<LinearDoubleKeyFrame Value="200" KeyTime="0:0:8" />
<LinearDoubleKeyFrame Value="500" KeyTime="0:0:9" />
<LinearDoubleKeyFrame Value="600" KeyTime="0:0:10" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Canvas.Resources>
<Rectangle MouseLeftButtonDown="Mouse_Clicked" Fill="Blue"
Width="50" Height="50">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="MyAnimatedTranslateTransform"
X="0" Y="0" />
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
' When the user clicks the Rectangle, the animation
' begins.
Private Sub Mouse_Clicked(ByVal sender As Object, ByVal e As MouseEventArgs)
myStoryboard.Begin()
End Sub
// When the user clicks the Rectangle, the animation
// begins.
private void Mouse_Clicked(object sender, MouseEventArgs e)
{
myStoryboard.Begin();
}
Easing Functions
Easing functions allow you to apply custom mathematical formulas to your animations. For example, you may want an object to realistically bounce or behave as though it were on a spring. You could use Key-Frame or even From/To/By animations to approximate these effects but it would take a significant amount of work and the animation would be less accurate than using a mathematical formula. You can apply easing functions to key-frame animations. For more information, see Animation Overview.
See Also