WynApse Home Page
Home    Blog    About    Contact       
Latest Article:


My Tags:
My Sponsors:







Lifetime Member:

Silverlight With Java Script Tutorial 06 - Basic Non-interactive Animation



Overview

As promised in Tutorial 05, I'm going to discuss animation this time. Animation is a huge part of Silverlight, and would take many pages to 'cover' it, so that's not my intent. As with other topics, I want to give a simple introduction to the subject at first so that you won't be afraid to try it yourself. Because there are two major types of animation in Silverlight at the time of this writing, I'm going to mention them both here, and then talk about only one of them in the rest of this Tutorial. Tutorial 07 will then introduce you to the second type.

Because animation is by nature complex, this is a longer write-up than I'd like. I think the explanation of some of the pieces is worth the time spent at least once.

One last thing before we begin, and that is a reference to the Microsoft Silverlight SDK Online. Don't be a stranger to the SDK! Some of the pieces in the SDK have great examples and animation is one of them.


Interactive Animations or not

Prior to Beta 01, there was only one type of animation... it's not that hard to do some basic animation with it once you've seen it, but is is a little involved. This animation runs from the time the xaml is loaded, and takes a little creative programming to make it not appear so. With Beta 01, we were given 'Interactive' animation. This involves putting our animation into a 'resource' object and interacting with it as we need it.

I'm going to discuss the non-interactive type first, not because it's easier, but because once you see the interactive way, you might not want to see this one :)

They both have their uses, and I will discuss the interactive version in Tutorial 07.


Our XAML

Here is the XAML for the canvas above:

<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded" >
<BeginStoryboard>
<Storyboard x:Name="animation" Storyboard.TargetProperty="(Canvas.Left)" AutoReverse="true" RepeatBehavior="Forever" >
<DoubleAnimation Storyboard.TargetName="Hello" From="-110" To="300" Duration="0:0:10" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>

<TextBlock x:Name="Hello" Canvas.Left="0" Canvas.Top="50" Foreground="Blue" Text="Hello Silverlight" />

</Canvas>



Our HTML

Here is the HTML to run this page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Silverlight With Java Script Tutorial 6</title>
<script src="js/Silverlight.js" type="text/javascript"></script>
</head>

<body bgcolor="white">

<br />
<center>
<div id="Ag1Host" style="background:#FFFFFF">
<script type="text/javascript">
var pe1 = document.getElementById("Ag1Host");
</script>
</div>
</center>

<script type="text/javascript">
Silverlight.createObjectEx({source: 'xaml/SilverlightWithJSTutorial06.xml', parentElement:pe1, id:'Ag1', properties:{width:'300', height:'100', background:'#00FFFFFF', isWindowless:'true', framerate:'24', version:'0.90.0'}, events:{onError:null, onLoad:null}, context:null});
</script>

</body>
</html>



Non-Interactive Animation

When you look at Silverlight applications on the web, or think about animations you'd like to do, the options are so many that there's a natural hesitation to begin, because there's not only so much available, but so much to learn! I had the same problem getting this tutorial started, because I had lots of ideas, but don't want to lose people in the details, particularly discussing Triggers and Storybaords! So I settled for our standard "Hello Silverlight" TextBlock moving across the canvas as you can see. If you start to get bogged down in the details, just copy the code and play with it, then come back later to read the rest of this.

It takes some xaml to get down into the real part of the animation code, so let's take it a step at a time, and refer back to the XAML displayed above for reference.

<Canvas.Triggers>

There are as many different types of triggers as there are objects. Actually they're all the same, it just defines where you place it in the xaml. I chose to use <Canvas.Triggers>, and placed it just inside the outer Canvas. This should lead you to believe that you could have sub canvases with their own triggers, and that is true. We also could have just as easily attached this Trigger to our TextBlock object directly as a <TextBlock.Triggers>.

Don't let this confuse you because there are other things we are going to see in later tutorials that are object-specific. You can think of them as a 'modifier' of sorts (my word) that modifes the object it's attached to. In this case, our Trigger is on our outer canvas, the least common denominator, and the one with the greatest reach, so we can then animate anything on our canvas... my whole reason for choosing this :)

Strictly-speaking, a Triggers object contains a collection of Triggers. In our case, we have only 1 trigger, I just wanted to mention there could be more.

<EventTrigger>

Excitement mounts when you first look up Event Trigger in the SDK. You find out it has properties "Actions", "Name", and "RoutedEvent". "Name" we know... this is tne EventTrigger's name. "Actions" are what is going to happen in this Trigger, and "RoutedEvent" is how this is going to be executed. It's the "RoutedEvent" name that is the cause for excitement, because you start to envision kicking this animation off on a button click, or maybe when another animation finishes. But then you take the RoutedEvent link and find "only the loaded" event is supported :( ... well ok, we can deal with that then.

Because the Trigger is associated with an object, that automatically defines for us what our RoutedEvent becomes. Since we have <Canvas.Triggers>, we then have RoutedEvent="Canvas.Loaded".

I don't know if this will change in later releases, but it made sense to me that if that's how it was, then maybe I didn't need the RoutedEvent= parameter, and testing showed I could safely remove it. I'm going to leave them in though, in case it becomes important later :)

<BeginStoryboard>
<Storyboard>

Next in the xaml file is BeginStoryboard followed by Storyboard. A Storyboard defines the individual actions that make up the animation controlled by the Trigger, and finally is down to the point of having important parameters to populate, some of which are detailed here:
x:Name
Normal naming convention
Storyboard.TargetName
This is the name of the object that is animated by this Storyboard. If multiple objects are contained in this storyboard, the first one can be listed here, or it can also be listed in the DoubleAnimation section (next).
Storyboard.TargetProperty
This defines the property of the animation target that is being animated. The target could be the Canvas.Top or Canvas.Left for animating things horizontally or vertically. The target could be the Fill value of the object, or many other properties. This parameter may also be defined in the DoubleAnimation discussed next.
AutoReverse
true/false ... does this animation automatically reverse when it completes
RepeatBehavior
This parameter is defined as being the value "Forever" or "seconds". I've tried using seconds and have had no luck with any combination, but "Forever" works fine as is shown above.
FillBehavior
This parameter defines what happens at the end of the animation, and is obviously used when AutoReverse and Repeat values are not. "HoldEnd" causes the animation to retain the ending state of whatever the animation is. "Stop" causes the animation to go into a stopped state and revert to the initial state. The default is "HoldEnd".
<DoubleAnimation>

The innermost xaml element for this type of animation is the DoubleAnimation object, and there can be multiples of these per Storyboard. If the TargetProperty for the animation is the same in all Storyboard objects, it can be listed in the Storyboard. If they are different, they can be listed in the DoubleAnimation. . This defines at least an ending position of the Storyboard TargetProperty, and the duration of the animation. A starting position as well as other parameters may be defined. I'm restricting my animation to those three:
Storyboard.TargetName
This is the name of the object that is animated by this Storyboard. If this DoubleAnimation TargetName is the same as the containing Storyboard, it can be left off here.
Storyboard.TargetProperty
This defines the property of the animation target that is being animated, as in the Storyboard, and once again, if this is the same as the Storybaord, it can be lef out of the DoubleAnimation.
From
Double value for the starting location of the Storyboard.TargetProperty.
To
Doublt value for the ending location of the Storyboard.TargetProperty.
Duration
This property defines, in Hours:Minutes:Seconds how long the animation is to take going from start to end.
I know this is a LOT of material to try to absorb, so don't even try. Take the animation xaml as-is, and play with it, refer back to this and then the SDK as you get more familiar with it.


Summary

I hope i've not 'lost' you in this discussion. I started out with just this simple animation and over the course of a couple days I added in some things that I thought would be fun to show. The text got longer and longer, and I realized I was making it overly complex for an introduction to animation, so I've pared it back down to just the one object moving.

At some later point, we'll add multiple animated objects on the same canvas, but that's it for now, and next time we'll do Interactive Animation.

Keep Having (Silverlight) Fun!


Microsoft MVP

Member of WPF and Silverlight Insiders
Silverlight Control
Creative Commons License

Copyright © 2006-2014, WynApse