Animating visuals

Animation is a first-class citizen in Silverlight. In LOB type of applications, animations can be used to enhance the user experience. Think about page transitioning in your application. Would users rather have a dull "screen-for-screen" type of transition where the pages just replace one another, or a nice subtle smooth transition where the pages slide, one next to another?

In Silverlight, the animation framework is time based. That means that you set a start and end position, and Silverlight takes care of the interpolation. Animations are best created using Microsoft Expression Blend and not directly with code. Every animation must have a storyboard, which is an object that is responsible for organizing and controlling the animation defined within it. Storyboard is the root of all animations, and for this reason, we will begin our discussion on this subject with it.

Creating storyboards

A Storyboard must contain an animation. Silverlight offers three types of animations we can use—ColorAnimation, DoubleAnimation, and PointAnimation. ColorAnimation is used when you wish to transition colors (the name does suggest that, doesn't it?). For example, if you want a button to transition from blue to red over a period of one second when a user hovers over it, you would use the ColorAnimation object. When you wish to apply an animation for an integer-based or double-based property such as height, width, and so on, you would use the DoubleAnimation object. Lastly, for moving things around using the X and Y values, we can use the PointAnimation object. Let's create our first animation right now. Create a new Silverlight project in Visual Studio 2010, and name it Chapter3-Animations. Once created, add the following code snippet to your MainPage.xaml file:

<Rectangle Height="200" Width="200" Fill="Red" x:Name="myRect" MouseEnter="Rectangle_MouseEnter" MouseLeave="myRect_MouseLeave">
</Rectangle>

This is just a regular rectangle we are used to seeing from other examples, but it has two events attached to it—MouseEnter and MouseLeave. Now, it's time to define the animation itself. Add the following code snippet between the Rectangle opening and closing elements:

<Rectangle.Resources>
<Storyboard x:Name="myColorAnim">
<ColorAnimation Storyboard.TargetName="myRect" Storyboard.TargetProperty="(Fill).(SolidColorBrush.Color)" From="Red" To="Green" Duration="0:0:0.5" />
</Storyboard>
<Storyboard x:Name="myColorAnimRev">
<ColorAnimation Storyboard.TargetName="myRect" Storyboard.TargetProperty="(Fill).(SolidColorBrush.Color)" From="Green" To="Red" Duration="0:0:0.5" />
</Storyboard>
</Rectangle.Resources>

We have defined two storyboards for this rectangle. The first goes from red to green, and the other goes back from green to red. The important things to notice in this code are the Storyboard.TargetName and Storyboard.TargetProperty properties. The first one defines which element the ColorAnimation is aimed at, myRect Rectangle in our case. The second property defines what we are animating. We want to animate the color of the fill the rectangle has. We can't simply input Fill as the property, because it is not true. We don't want to modify the Fill property; we want to modify the color of the Fill property, and as the color in our case is a solid color (red), we use the (Fill).(SolidColorBrush.Color) value. If you run the application now, you'll notice the color still hasn't changed. The reason for that is because we never told the animation when to start. This is exactly why we have defined the MouseEnter and MouseLeave events for our Rectangle. Switch over to the MainPage.xaml.cs file, and add the following event handlers:

private void Rectangle_MouseEnter(object sender, MouseEventArgs e)
{
myColorAnim.Begin();
}
private void myRect_MouseLeave(object sender, MouseEventArgs e)
{
myColorAnimRev.Begin();
}

All that the event handler is doing is using the Begin method of the desired Storyboard to start the animation. Build and run your application now, and you should see the rectangle changing its color when you hover over and out of it.

Another option to trigger an animation is to use the Triggers attached property of the element we wish to animate. This method supports only the Loaded event and as such is perfect to use when you wish to start an animation as soon as an object is loaded.

Let's alter our rectangle to load the animation with Triggers instead of event handlers. Change your Rectangle code as follows:

<Rectangle Height="200" Width="200" Fill="Red" x:Name="myRect">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard x:Name="myColorAnim">
<ColorAnimation Storyboard.TargetName="myRect" Storyboard.TargetProperty="(Fill).(SolidColorBrush.Color)" From="Red" To="Green" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>

By using the EventTrigger element, we can specify an event to catch. Currently, only the Loaded event is supported so we chose to use it. Right below it, we use the BeginStoryboard element, and from there, it's business as usual. You will add a regular Storyboard to hold your animation.

Build and run your application now, and you'll see that the rectangle has instantly turned green.

Here's a little challenge for you. Try to switch ColorAnimation we defined in Storyboard with DoubleAnimation, which changes the size of the rectangle from 200 by 200 pixels to 400 by 400 pixels on mouse enter and back to 200 by 200 pixels on mouse leave. The solution will be added to the Appendix of this book.

Controlling the storyboard

Controlling your storyboard is as simple as it gets. While you have the usual stop, play, pause, and resume, you can also react when a storyboard ends.

Controlling the storyboard is done via code behind. By using the name of the Storyboard object, you can call the Stop, Begin, Pause, and Resume methods. We have already seen how to use the Begin method in the previous topic where we wanted to start the animation in the event handlers.

If you wish to perform an action when the animation is finished, simply attach the Completed event to your Storyboard either by code or XAML. To demonstrate the use of the Completed event, change your myColorAnim element as follows:

<Storyboard x:Name="myColorAnim" Completed="myColorAnim_Completed">

In your MainPage.xaml.cs file, add the following event handler:

private void myColorAnim_Completed(object sender, EventArgs e)
{
myColorAnimRev.Begin();
}

If you build and run your application now, you'll see that as soon as the first animation has finished playing, the second one (the one that reverses the color back to red) kicks in.

Repeating and reversing storyboards

Having to call an event receiver and fire up another storyboard, just so that we can reverse the animation we've created, looks a little downing. For this exact case, we have a special property called AutoReverse for our storyboard. If you set the AutoReverse property to True on any Storyboard element, the animation will automatically play back once done! Change your Storyboard element as follows:

<Storyboard x:Name="myColorAnim" AutoReverse="True" >

Hover over your rectangle now, and you'll see that the animation plays and reverses back to where it started.

Now comes the question of repeating. What if I want to repeat my animation over and over again? This is where the RepeatBehavior property comes to your aid. This property allows you to set how many times you wish your animation to repeat (for example, 1, 5, 100 times). If you want it to just keep on going, you can set this property to Forever. Again, change your storyboard as follows:

<Storyboard x:Name="myColorAnim" AutoReverse="True" RepeatBehavior="Forever" >

Run your application now, and you should see that your animation plays, then reverses, and then repeats itself over and over again until you close the browser window.

Implementing easing functions

As cool as Silverlight animations are, they do seem unnatural at times. The reason for that is the lack of easing. Easing provides a way to make your animation less "flat" and boring. Using the easing functions provides your animation with acceleration and deceleration, or even a bouncy behavior. Easing functions have three modes of use—EaseIn, EaseOut, and EaseInOut. These modes determine how the easing function will be applied to the animation over the course of time. EaseIn and EaseOut are the exact opposites. While EaseIn affects the beginning of the animation, EaseOut affects the ending of it. Easing functions are better seen than read about and, thus, I strongly recommend that you visit Silverlight.net's demo application for easing functions over at http://www.silverlight.net/learn/creating-ui/animation-and-easing/animations-%28silverlight-quickstart%29#easing_functions.

Applying easing functions to your animation is best done via Microsoft Expression Blend 4, as it provides a graphical environment for creating and editing animations. However, it is perfectly ok to add them directly using XAML as well. Let's add CubicEase to our rectangle animation. First, change the animation duration from half a second to a second by replacing the value of the ColorAnimation Duration property to 0:0:1.

Now, inside your ColorAnimation element, add the following code snippet:

<ColorAnimation.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</ColorAnimation.EasingFunction>

We used the EasingMode property to set the mode to EaseInOut. Feel free to change it to EaseIn or EaseOut if you wish.

Build and run your application, and you should notice the animation looks much more natural. Try to play with the different easing functions to get a feel of the difference they make.

Configuring bitmap caching

Bitmap catching is one of the most requested features of Silverlight. This feature was introduced in Silverlight 3 and continued to exist in Silverlight 4. This feature's main use is for performance enhancement, by allowing visual elements to be cached as bitmaps once they have been rendered for the first time. Just like browser cache, once the visuals are cached, the framework will display them straight from cache instead of going through the entire rendering phase. To use bitmap caching, you have to first enable it on the Silverlight plugin level. We will discuss the plugin in details in the last chapter of the book, but for now you should know that Silverlight is rendered to an HTML page using an object tag (<object>) and that it is possible to add parameters to it. If you take a look at the last project we worked on, there are two projects in the solution—the Silverlight and the ASP.NET web project. Under the ASP.NET project (Chapter3-Animations.Web), open the Chapter3-AnimationsTestPage.aspx file and look for the object tag. Once found, locate the following line of code:

<param name="background" value="white" />

This is a parameter added to the plugin that defines the background color of the plugin area.

We will now add the bitmap catching parameter below it:

<param name="EnableGPUAcceleration" value="true" />

By adding this parameter, we are enabling the GPU acceleration feature of Silverlight and opening the way for the bitmap caching mechanism.

Now all we have to do is specify to Silverlight what we want to cache. To specify this requirement, all we have to do is set a property called CacheMode on the object we wish to cache. Let's cache our rectangle. Add the following property to the Rectangle element:

CacheMode="BitmapCache"

That's it. The rectangle is now cached. A few things to remember when using the bitmap caching mechanism are as follows:

  • Currently, only the BitmapCache cache mode is supported.
  • When applying a cache mode to an element, it not only caches the element itself but all its child elements as well.
  • Caching is best used when you are using transformations on elements.

Try playing around with caching by adding more elements to the page, and then add and remove the caching mechanism. You'll see how caching affects performance in no time!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.21.158