Silverlight sports a rich animation system that is surprisingly easy to use. The animation model in Silverlight is time based, meaning that movements occur based on a set timeline. At the heart of every animation is a StoryBoard, which contains all the animation data and independent timeline. Silverlight controls can contain any number of Storyboards.
StoryBoards contain one or more Key frame elements, which are responsible for making objects on screen change position, color, or any number of properties. There are four general types of Key frames in Silverlight 4: Linear, Discrete, Spline, and Easing. The table below illustrates what each one does:
Very different than Flash
The animation model in Silverlight is markedly different than the one found in Adobe Flash. Animations in Flash are frame-based, whereas in Silverlight they are time-based. The term StoryBoard comes from the motion picture industry, where scenes are drawn out before they are filmed.
Time for action – animation time
The client would like to transform their text-only logo into something a little more elaborate. The designers have once again given us a XAML snippet of code exported from their graphic design tool. We will need to do the following:
- Open up the CakeORama logo project in Blend.
- Blend should have automatically loaded the MainControl.xaml file and your screen should look like this:
- In the Objects and Timeline tab, you’ll see a list of objects that make up this vector drawing. There is Path object for every character.
- Let’s add an animation. On the Object and Timeline tab, click the plus sign (+) to create a new StoryBoard.
- In the Create Storyboard Resource dialog, type introAnimationStoryboard into the text box and click OK.
- You’ll notice a couple of changes to your screen. For one, the art board is surrounded by a red border and a notification that: intoAnimationStoryboard timeline recording is on just like in this screenshot:
- If you take a look at the Objects and Timeline tab, you’ll see the timeline for our newly created introAnimationStoryboard:
- Let’s add a key frame at the very beginning. The vertical yellow line is the play head, which marks where you currently are in the timeline. Select the canvas1 object.
- Click on the square icon with a green plus sign to create a new Key frame here at position 0. A white oval appears representing the Key frame that you just created. It should look similar to the following screenshot:
- Move the play head to 0.7 seconds, by clicking on the tick mark to the immediate left of the number 1.
- Click the same button you did in step 9 to create a new key frame here so that your timeline looks like this:
- Move the play head back to zero.
- Make sure the canvas1 object is still selected, click and drag the logo graphic up, so that all of it is in the grey area. This moves the logo “off stage”.
- Hit the play button highlighted in the below screenshot, to preview the animation and enjoy the show!
- Now all we need to do is tell Silverlight to run the animation when our control loads, but first we need to get out of recording mode. To do this, click the x button on the Objects and Timeline tab.
- Click on [UserControl] in the Objects and Timeline tab.
- On the Properties tab, you’ll see an icon with a lightning bolt on it. Click on it to see the events associated with a UserControl object:
- To wire up an event handler for the Loaded event, type UserControl_Loaded in the text box next to Loaded, as shown in the next screenshot:
- Once you hit Enter, the code behind will immediately pop up with your cursor inside the event handler method.
- Add this line of code to the method:
You can switch to the Animation Workspace in Blend by pressing F6.
Run the solution via the menu bar or by pressing F5. You should see the logo graphic smoothly and evenly animate into view. If for some reason the animation doesn’t get displayed, refresh the page in your browser. You should see it now.
What just happened?
You just created your first animation in Silverlight. First you created a Storyboard and then added a couple of Key frames. You changed the properties of the canvas on one key frame and Silverlight automatically interpolated them in between points to create a nice smooth animation. If your animation didn’t show up on the initial page load but did when you reloaded the page, then you’ve just experienced how seriously the Silverlight animation engine respects time. Since our animation length is relatively short (0.7 seconds) it’s possible that more than that amount of time elapsed from the call of the Begin method, to the amount of time it took for your computer to render it. Silverlight noticed that and “jumped” ahead to that part of the timeline to keep everything on schedule.
Just like we did before, let’s take a look at the XAML to get a better feel of what’s really going on. You’ll find the Storyboard XAML in the UserControl.Resources section towards the top of the document. Don’t worry if the values are slightly different in your project:
There are a couple of things going on here, so let’s dissect the animation XAML starting with the Storyboard declaration which creates a Storyboard and assigns the name we gave it in the dialog box:
That’s easy enough, but what about the next node? This line tells the Storyboard that we will be modifying a Double value starting at 0 seconds. It also further specifies a target for our animation: canvas1 and a property on our target:
Clear enough, but what does the TargetProperty value mean? Here is that value highlight below.
We know that the net effect of the animation is that the logo moves from above the visible area back to its original position. If we’re familiar with X, Y coordinates, where X represents a horizontal coordinate and Y a vertical coordinate, then the TranslateTransform.Y part makes sense. We are changing or, in Silverlight terms, transforming the Y property of the canvas. But what’s all this TransformGroup about?
Take a look at our canvas1 node further down in the XAML. You should see the following lines of XAML that weren’t there earlier:
Blend automatically inserted them into the Canvas when we created the animation. They have no properties. Think of them as stubbed declarations of these objects. If you remove them, Silverlight will throw an exception at runtime like the one below complaining about not being able to resolve TargetProperty:
Clearly this code is important, but what’s really going on here? The TranslateTransform object is a type of Transform object which determines how an object can change in Silverlight. They are packaged in a TransformGroup, which can be set in the RenderTransform property on any object descending from UIElement, which is the base class for any kind of visual element.
With that bit of knowledge, we now see that (TransformGroup.Children) refers to the fourth element in a zero-based collection. Not so coincidentally, the TranslateTransform node is the fourth item inside the TransformGroup in our XAML. Changing the order of the transforms in the XAML will also cause an exception at runtime.
That line of XAML just tells the Silverlight runtime that we’re going to animation, now we tell it how and when with our two EasingDoubleKeyFrame nodes:
The first EasingDoubleKeyFrame node tells Silverlight that, at zero seconds, we want the value to be -229. This corresponds to when the logo was above the visible area. The second EasingDoubleKeyFrame node tells Silverlight that at 0.7 seconds, we want the value of the property to be 0. This corresponds to the initial state of the logo, where it was before any transformations were applied.
Silverlight handles all changes to the value in between the start and the end point. Silverlight’s default frame rate is 60 frames per second, but Silverlight will adjust its frame rate based on the hardware that it is running on. Silverlight can adjust the amount by which it changes the values to keep the animation on schedule. If you had to reload the web page to see the animation run, then you’ve already experienced this. Once again, notice how few lines (technically only one line) of procedural code you had to write.