Modifying Animations using C# - Page 3
       by kirupa  |  14 May 2008

In the previous page, I described the problem and why it is necessary to modify this animation using code. In this page, we'll look at the problem in greater detail.

Download Sample Project
To help you out, I've created a sample project that represents our problem:

Download Sample Project

Download the above file, extract it to your hard drive, and open Window1.xaml in Expression Blend 2. Hit F5 to run your application. What you will see is the application I described in the previous page - animation and all.

What I am going to do in this page is describe the XAML that defines the animation where the circle oscillates from one edge of the window to the other. The reason is that, in order to manipulate this animation using C#, knowing the basic structure of your animation in XAML is quite handy.

In Blend 2, hit the XAML tab and scroll to the top of your code where you see the Window.Resources node. It's child is the animation that I have pasted below for your reference:

<Storyboard x:Key="Oscillate">
<DoubleAnimationUsingKeyFrames
   BeginTime="00:00:00"
   RepeatBehavior="Forever"
   Storyboard.TargetName="ellipse"
   Storyboard.TargetProperty="(UIElement.RenderTransform).
          (TransformGroup.Children)[3].(TranslateTransform.X)"
>
 
<SplineDoubleKeyFrame
KeySpline="1,0,1,1"
KeyTime="00:00:00"
Value="0"/>
<SplineDoubleKeyFrame
KeySpline="0,1,1,1"
KeyTime="00:00:01"
Value="-130"/>
<SplineDoubleKeyFrame
KeySpline="1,0,1,1"
KeyTime="00:00:02"
Value="0"/>
<SplineDoubleKeyFrame
KeySpline="0,1,1,1"
KeyTime="00:00:03"
Value="140"/>
<SplineDoubleKeyFrame
KeySpline="1,0,1,1"
KeyTime="00:00:04"
Value="0"/>
 
</DoubleAnimationUsingKeyFrames>
</Storyboard>

Animations in WPF and Silverlight
Animations in WPF and Silverlight are defined by three things - Storyboards, Animations, and Keyframes. Let's look at each one in greater detail by using our above XAML as reference.

Storyboards
A storyboard primarily acts a container for your animations. While it can do more such as specify which elements and properties to target, our storyboard only contains an x:Key reference that will prove useful when calling this storyboard via code:

<Storyboard x:Key="Oscillate">
<DoubleAnimationUsingKeyFrames
   BeginTime="00:00:00"
   RepeatBehavior="Forever"
   Storyboard.TargetName="ellipse"
   Storyboard.TargetProperty="(UIElement.RenderTransform).
          (TransformGroup.Children)[3].(TranslateTransform.X)"
>
 
<SplineDoubleKeyFrame
KeySpline="1,0,1,1"
KeyTime="00:00:00"
Value="0"/>
<SplineDoubleKeyFrame
KeySpline="0,1,1,1"
KeyTime="00:00:01"
Value="-130"/>
<SplineDoubleKeyFrame
KeySpline="1,0,1,1"
KeyTime="00:00:02"
Value="0"/>
<SplineDoubleKeyFrame
KeySpline="0,1,1,1"
KeyTime="00:00:03"
Value="140"/>
<SplineDoubleKeyFrame
KeySpline="1,0,1,1"
KeyTime="00:00:04"
Value="0"/>
 
</DoubleAnimationUsingKeyFrames>
</Storyboard>

The main thing to note in the context of this example is that our storyboard's x:Key value is Oscillate.

Animations
Inside your storyboard, you will find animations. There are numerous (I believe 22) animation base types that you can use, and they are all designed for whatever type of property you are modifying:

<Storyboard x:Key="Oscillate">
<DoubleAnimationUsingKeyFrames
   BeginTime="00:00:00"
   RepeatBehavior="Forever"
   Storyboard.TargetName="ellipse"
   Storyboard.TargetProperty="(UIElement.RenderTransform).
          (TransformGroup.Children)[3].(TranslateTransform.X)"
>
 
<SplineDoubleKeyFrame
KeySpline="1,0,1,1"
KeyTime="00:00:00"
Value="0"/>
<SplineDoubleKeyFrame
KeySpline="0,1,1,1"
KeyTime="00:00:01"
Value="-130"/>
<SplineDoubleKeyFrame
KeySpline="1,0,1,1"
KeyTime="00:00:02"
Value="0"/>
<SplineDoubleKeyFrame
KeySpline="0,1,1,1"
KeyTime="00:00:03"
Value="140"/>
<SplineDoubleKeyFrame
KeySpline="1,0,1,1"
KeyTime="00:00:04"
Value="0"/>
 
</DoubleAnimationUsingKeyFrames>
</Storyboard>

Our animation is of type DoubleAnimationUsingKeyframes because, we are using keyframes as you will see later, but more importantly, because the property we are modifying - TranslateTransform.X - is of type Double.

Notice that we set some basic properties such as BeginTime and RepeatBehavior which specify when your animation begins and what it will do when it reaches the end. In our case, the animation begins at time 0, and when it reaches the end, it loops forever.

What is interesting to note is the value for your TargetProperty. Notice that it seems pretty big, but if you look through it, the property that you are targeting is the TranslateTransform.X property of your RenderTransform on the ellipse element. In Blend, you can find that property by using the Properties Inspector and navigating to the Transform category:

[ the property that your animation is targeting ]

I'm showing this to let you know that your animation has its sights on the X value of your RenderTransform. You will see why that is important in the next section when I describe keyframes.

KeyFrames
Animations often contain keyframes. Keyframes are like a stake in the ground where a property promises to be at a particular value at the time the keyframe is in. In our example, we have five keyframes of type SplineDoubleKeyFrame:

<Storyboard x:Key="Oscillate">
<DoubleAnimationUsingKeyFrames
   BeginTime="00:00:00"
   RepeatBehavior="Forever"
   Storyboard.TargetName="ellipse"
   Storyboard.TargetProperty="(UIElement.RenderTransform).
          (TransformGroup.Children)[3].(TranslateTransform.X)"
>
 
<SplineDoubleKeyFrame
KeySpline="1,0,1,1"
KeyTime="00:00:00"
Value="0"/>
<SplineDoubleKeyFrame
KeySpline="0,1,1,1"
KeyTime="00:00:01"
Value="-130"/>
<SplineDoubleKeyFrame
KeySpline="1,0,1,1"
KeyTime="00:00:02"
Value="0"/>
<SplineDoubleKeyFrame
KeySpline="0,1,1,1"
KeyTime="00:00:03"
Value="140"/>
<SplineDoubleKeyFrame
KeySpline="1,0,1,1"
KeyTime="00:00:04"
Value="0"/>
 
</DoubleAnimationUsingKeyFrames>
</Storyboard>

You can visualize these keyframes by simply opening the Oscillate storyboard in Blend:

[ your five keyframes displayed at times 0, 1, 2, 4, and 5 second marks ]

Notice that there are five keyframes, and if you select the keyframe, you will see your Properties Inspector update to display the keyframe and the type it is, and more importantly, its value:

[ selecting a keyframe will display it's type plus a field for its value ]

Anyway, but now I am digressing. If you look at the XAML, the KeyTime is specified, but so is the Value. This Value is channeled to the TargetProperty your animation is targeting. For example, at the 3 second mark, your KeyFrame's Value is 140. That means that our ellipse's TranslateTransform.X value is going to be 140 as well.

In case I didn't mention it earlier, the animation system in WPF and Silverlight is really designed to take a property and change it over a period of time. In our case, we are changing the horizontal position of our circle (ellipse element) via the TranslateTransform.X property as defined by our animation, and the actual value of that property at a given time is specified by our keyframes.


All right, now you have a good idea of what our XAML is actually doing by analyzing our animation. As you will see in the next page, this knowledge will come in quite handy.

Onwards to the next page!

1 | 2 | 3 | 4 | 5




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.