December 2008 - Posts
In Tip of the Day #77 I explored using DoubleAnimation to animate a given controls property value using the From/To method. In this tip we will be exploring DoubleAnimationUsingKeyFrames. Unlike DoubleAnimation which goes from one value to another, DoubleAnimationUsingKeyFrames is a container for a set of key frames that will determine the properties value at a given set of points along a time line.
There are three different key frame types available:
- LinearDoubleKeyFrame – Animates a double value using linear interpolation. This means the animation will smoothly transition between values.
- DiscreteDoubleKeyFrame – Animates a double value using discrete values. This means the animation will jump between positions.
- SplineDoubleKeyFrame – Animates a double value using splined interpolation. This key frame makes use of a KeySpline. To understand better how this works I would recommend reviewing how cubic Bezier curves work. Essentially it has a start point (always 0), an end point (always 1) and two control points. You set the two control points using the KeySpline. The result is a curve that represents the rate of change for the animation.
To demonstrate this functionality we will create an animation timeline of a image of a mage walking in a square using as seen in this demo below. Each direction uses a different type of key frame.
Looking at the XAML below you will see we use LinearDoubleKeyFrame to animate the images left property from the timeline of seconds 0 to 2 moving the image to the right. Than, using SplineDoubleKeyFrame the top property gets animated from seconds 2 to 4 where I move the image down the screen. You will see it start off slow, the rapidly speed up as it follows the curve set. Next, using SplineDoubleKeyFrame again the left property animation kicks in again from seconds 4 to 6 moving the mage back to the left. Notice no KeySpline was set so it essentially did what the LinearDoubleKeyFrame would have done. Finally, the top property kicks in at second 7 causing the image to jump to Top=0 since we used DiscreteDoubleAnimation.
I have set the RepeatBehavior = “Forever” which will cause the animation to repeat non-stop.
And the source in Page.xaml:
<Storyboard x:Name="MageSB" RepeatBehavior="Forever" >
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Canvas.Left)"
Storyboard.TargetName="MyMage">
<LinearDoubleKeyFrame KeyTime="00:00:00" Value="0"></LinearDoubleKeyFrame>
<LinearDoubleKeyFrame KeyTime="00:00:02" Value="120"></LinearDoubleKeyFrame>
<SplineDoubleKeyFrame KeyTime="00:00:04" Value="120"></SplineDoubleKeyFrame>
<SplineDoubleKeyFrame KeyTime="00:00:06" Value="0"></SplineDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Canvas.Top)"
Storyboard.TargetName="MyMage">
<SplineDoubleKeyFrame KeyTime="00:00:02" Value="0"></SplineDoubleKeyFrame>
<SplineDoubleKeyFrame KeySpline="1.0,0.0 1.0,0.00" KeyTime="00:00:04" Value="80"></SplineDoubleKeyFrame>
<DiscreteDoubleKeyFrame KeyTime="00:00:07" Value="0"></DiscreteDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
Thank you,
--Mike Snow
Subscribe in a reader
In some of my older posts I was creating a separate random generator for each object. However, the documentation on Random states:
"The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers. This problem can be avoided by using a single Random object to generate all random numbers."
As a result I created a single random generator class and I put it in a new static class called Utils where it could be globally referenced.
public class Utils
{
static Random _random;
static Utils()
{
_random = new Random();
}
public static int RndGen(int min, int max)
{
return _random.Next(min, max);
}
}
To make a call now from one of your classes such as your Page class you simply make a call like this to get a random number:
int value = Utils.RndGen(1, 50);
The first parameter is the minimum value you want, the second is the maximum.
I updated Tip of the Day #43 - Snowflake scene - to use this implementation.
Thank you,
--Mike Snow
Subscribe in a reader
In Silverlight you can use the Storyboard control to animate properties of an object. It can be used against properties of type double, Color or Point. For example, you can animate changing the double type property Opacity of a Rectangle over time. A Storyboard can be declared in your XAML but it must be placed as a resource. For example, the following Storyboard is declared as a resource of the Canvas object:
<Canvas>
<Canvas.Resources>
<Storyboard x:Name="MyRect">
</Storyboard>
</Canvas.Resources>
</Canvas>
The Storyboard control provides the user with two options for animating:
- DoubleAnimation - Uses a From/To direction.
- DoubleAnimationUsingKeyFrames - This is a container for a set of key frames that will determine the value at a given set of points along a time line. We will look at this option in our next tip of the day.
DoubleAnimation.
As stated above, this uses a From/To direction that takes the targeting property from one value to another. Let's take a close look at some of the properties DoubleAnimation provides:
- Storyboard.TargetProperty - Use this to target the property you wish to animate. In should be in the format UIElement.Property.
- Storyboard.TargetName - Use this to target the object you want to animate.
- Duration - Use this property to specify how long the animation should take. Format = [days.]hours:minutes:seconds.
- From/To - The start and end values you want the property to be set to. By Default From = 1.0 and does not have to be set unless you want it to be a different value.
- AutoReverse - This will cause the animation to reverse course once it's completed.
- RepeatBehavior - Set this to "Forever" to cause it to repeat non-stop. You can also set this to a duration (format = [days.]hours:minutes:seconds) or an iteration count.
The following below is an example of a DoubleAnimation where we target an image's opacity fading the image in and out non-stop.
<Canvas>
<Canvas.Resources>
<Storyboard x:Name="CatSB">
<DoubleAnimation Storyboard.TargetName="MyCat" Storyboard.TargetProperty="UIElement.Opacity"
Duration="00:00:02" From="1.0" To="0.0"
AutoReverse="True" RepeatBehavior="Forever">
</DoubleAnimation>
</Storyboard>
</Canvas.Resources>
<Image Source="cat.jpg" x:Name="MyCat" >
</Image>
</Canvas>
To start the Storyboard we call CatSB.Begin(); from our code.
Live Demo:
Thank you,
--Mike Snow
Subscribe in a reader