Silverlight - Simple Animation
Sunday, March 23, 2008 2:12 AM
Seems I've fallen way behind on my Silverlight blogging as of late. A few weeks ago, I managed to get some simple animation working. So, I guess I should blog about it.
Animation is done by transforming your object. Each graphic element has a RenderTransform property to which you can assign a Transform object to modify your element in some way. The different types of Transform objects include RotateTransform, SkewTransform, ScaleTransform, and TranslateTransform. Let's look at an example.
<Ellipse MouseLeftButtonDown="EllipseClick" Height="50" Width="100" Canvas.Top="50" Canvas.Left="50" Fill="Black">
<RotateTransform x:Name="EllipseXForm" Angle="90" />
This example is pretty boring - it just renders a 50 pixel high and 100 pixel wide ellipse, rotated 90 degrees (so that it instead appears 100 pixels high and 50 pixels wide). However, it illustrates the effect that a RotateTransform will have on an object. Also note that I have named the transform (the x:Name attribute). The purpose of that will soon become apparent.
Animations are defined within objects called Storyboards. Basically, a Storyboard defines a timeline of changes that should occur to properties of objects. For my example, I want to change the Angle property of the RotateTransform object over time (so that the Ellipse rotates slowly as we watch). Here is the Storyboard I have defined:
<DoubleAnimation Storyboard.TargetName="EllipseXForm" Storyboard.TargetProperty="Angle" To="0" Duration="00:00:05" />
For this example, I have used a DoubleAnimation. This is because the property I want to change ("Angle") is of type double. There are many other animation objects available such as DecimalAnimation, Int32Animation, and ColorAnimation. The Storyboard.Targetname attribute tells the animation which object it is changing (here's where I use the name I gave my transform earlier) and Storyboard.TargetProperty indicates what property will be changed. The To attribute is the value the animation should end with and the Duration should be self-explanatory. Note again, I have named my Storyboard so that I can reference it later. Oh yeah, and the Storyboard is a resource, so it's defined inside the <Canvas.Resources /> element.
I'm going to need something to trigger the animation to begin. I've chosen to do it using a mouse click on the ellipse. So, I will need to add a MouseLeftButtonDown handler to the Ellipse. Now it looks like this:
<Ellipse MouseLeftButtonDown="EllipseClick" Height="50" Width="100" Canvas.Top="50" Canvas.Left="50" Fill="Black">...
function EllipseClick( sender, args )
I placed this directly in my .aspx file for this example. I don't think I've blogged about findName() before, but Silverlight elements define this method and it allows you to get a reference to any other Silverlight element by name. Here, I am using it to get the "EllipseStoryboard" Storyboard and executing it's Begin() method.
You can see this example in action at http://www.killeverything.com/zak/Silverlight1/EllipseRotate1.aspx
It's not quite what I wanted, though. The rotation is happening around the top left corner of the ellipse instead of the center. Luckily, this was easy to fix - the RotateTransform has CenterX and CenterY properties that allow you to define the point around which the object rotates. Knowing that the ellipse is 100 wide and 50 tall, this is what I changed the transform to look like:
<RotateTransform x:Name="EllipseXForm" Angle="90" CenterX="50" CenterY="25" />
You can see the finished example at http://www.killeverything.com/zak/Silverlight1/EllipseRotate2.aspx
I've also attached a ZIP with the files needed for these examples in case you want to play with them yourself.