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.
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 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.
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.
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.
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:
BitmapCache
cache mode is supported.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!
3.145.35.194