agTweener - Updated for Silverlight 2.0

March 23rd, 2008

Thanks all for the responses to my previous post on agTweener - An animation library for Silverlight. The library enables developers to easily integrate complex animation effects in Silverlight with a very small amount of code. It also makes procedural animation a lot simpler. There’s been some encouraging response so far from the community.

Since the release of Silverlight 2.0 I’ve been spending a bit of time getting familiar with the framework changes, and then updated each of the three samples used to demonstrate the agTweener library.

As it turns out, the changes required to the library were very minor, but the samples themselves needed a bit of restructing. Thanks Jose Fajardo for the early analysis and work on the SL2.0 update!. For now I’ll leave it to you to check out the code and start playing while I’m working on a longer tutorial and run through the code.

The code is available at CodePlex, which has now been updated with a Version 2.0 release containing updates to the agTweener library and the three samples, TweenerBlock, TweenerSampleGrid, and TweenerDooby.

With the release of Silverlight 2.0 there’s now a lot more basic elements in the control model that could have their properties attached to the TweenParameter class. Let me know if you’ve got any ideas on what you’d like to be able to Tween.

Here’s the updated versions of each of the samples, now running on SL2.0.

TweenerBlock -shows each of the Penner easing functions with the equation attached to a moving block

TweenerDooby - now we can tween the position, scale, skew, rotation and opacity of a Silverlight control using any of the equations and a defined time for the transition. The transition function is also plotted to help visualise the change in the tween value property over time.

TweenerSampleGrid - shows the effect of using a delay in the TweenParameter and the use of the onStart and onComplete event delegates.

Happy Tweening, MC.

Firefox issues with Silverlight 1.1 ErrorCode: 2252

March 1st, 2008

After getting a few reports of samples on my site not working in Firefox (but fine in IE), I dug a bit further and found out more about an issue that others may be experiencing too.

Thee 2252 Silverlight error is one that can pop up if you haven’t named your assembly or path to the assembly correctly.

ErroCode: 2252
ErrorType: ParserError
Message: AG_E_RUNTIME_MANAGED_ASSEMBLY_DOWNLOAD

For example, in the following Page.xaml file

<Canvas x:Name=parentCanvas
   
xmlns=http://schemas.microsoft.com/client/2007
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
Loaded
=Page_Loaded
    x:Class=SampleProject.Page;assembly=ClientBin/SampleProject.dll
    Width=800
   
Height=“600
>

The SampleProject.dll file should sit in a folder named ClientBin directly under the location of the Page.xaml and HTML host page.

Now, this all worked fine when running on my local machine with different browsers, but when uploaded to my web host Firefox browsers got the good old 2252 error.

It wasn’t a file permissions problem on the host or MIME type problem with the .xaml file as others have experienced in the forum posts linked, since other browsers were fine.

The workaround was to put the Silverlight assembly in the same location as the .xaml files and HTML host page on the server, not in the default ClientBin folder.

agTweener - An animation library for Silverlight

February 29th, 2008

Setting up storyboard animations and manipulating properties of an object in the timeline either in Flash or Blend is a really good visual way to get a feel for how your animation is behaving as it’s being created but there’s a lot of situations where this falls short, either isn’t flexible enough, or can be too complex to achieve the effects required. A scenario I’ve hit in a current Silverlight project is creating a simple elastic effect on a dynamically created user control.

Flash/Flex developers have a number of tools available to them to make animation effects easy, programmable and procedural. Libraries like Tweener, TweenLite and Fuse enable developers to create animation transitions at runtime through code.

A tween library is must have in any developers toolkit so after searching around a bit and realising that there’s nothing widely available in Silverlight yet, I decided to port the Tweener Actionscript library to C# and Silverlight 1.1.

This post gives a high level run through of how to use the library and presents three demos that show the features of the library. By all means contact me with suggestions for improvement or effects that you’re trying to achieve. I haven’t covered all the features in Tweener yet, but the basics are there and it’s now opened up a whole new range of opportunities for development in Silverlight that hopefully you can get something out of.

Firstly a bit of credit to those who have done the ground work already. The awesome Zeh Fernando and Nate Chatellier created the Actionscript versions of Tweener. Yuichi Tateno created the javascript version JSTweener, and Harvey posted source on the Silverlight forum with the beginnings of a Silverlight tweener.

Robert Penner created a whole range of easing equations that have become a standard in transitions, especially in Flash. A graphic representation of each transition is shown here.

XAML supports basic KeySpline animation that lets you define the control points of a transition which gives you control over the acceleration of an easein/easeout transition. My previous post Keyspline animation in Silverlight shows how these control points affect the KeySpline animation.

The main limitations in using these KeySpline animations we’re faced with are:

  • Overshoot, undershoot, elastic and bounce type transitions aren’t supported
  • Preset KeySpline paths (ie. control point combinations) can’t easily be called by name. In Blend or in code I can’t easily select an “EaseOutReallyReallyFast” vs “EaseOutMondayMorningFast” transition.

Let’s take a quick look at what each of the Penner transition functions looks like with the first sample. You’ll need Silverlight 1.1 for this. This is the same moving box sample that Yuichi Tateno put together to demonstrate JSTweener. It’s a good first comparison of what’s needed to use the library in Silverlight.

The code for this sample is available on Codeplex. You’ll need to download the agTweener.zip file and TweenerBlock.zip.

In this sample we define a rectangle in Page.xaml

<Rectangle x:Name=Block Width=50 Height=50 Fill=#F37427 Opacity=0.8/>

In the Page_Loaded handler we call a function that starts off the tween

Tweener.addTween(Block, p, new TweenEvent(Move2), null);

The important point to note is that there is no StoryBoard or DoubleAnimation XAML required at all in Page.xaml. The dynamic creation of this is handled within the Tweener library.

The rectangle to animate is passed as a parameter to the addTween method (can be any FrameworkElement) and the tween parameters are also passed in. The following code block shows how the tween parameters are set.

//set the target tween parameters
TweenParameter
p = new TweenParameter();
p.transition = (TransitionType)Enum.Parse(typeof(TransitionType), _transitionFunction, true);
p.LeftProperty = PATH_TOP_RIGHT_X;
p.TopProperty = PATH_TOP_RIGHT_Y;
p.time = _time;
Tweener
.addTween(Block, p, new TweenEvent(Move2), null);

The x,y coordinates for the target position of the block at the end of it’s motion are set in the p.LeftProperty and p.TopProperty properties. The time for the overall transition is set in p.time and the transition function to use is also set.

The four paths around the rectangle are set up as four separate tweens with the LeftProperty and TopProperty target values as the four corners of the rectangle. Just like the actionsript Tweener library, you can pass in a delegate to a function to call when the current tween is completed. In the code sample above we want the Move2 function called when the tween is finished. In Move2 we set the next end point and call:

Tweener.addTween(Block, p, new TweenEvent(Move3), null);

That’s pretty much it for the basics of Tweener and this sample. Now we’ll dig a bit deeper and go through the full features of what you can do with this version.
In the Flash version of Tweener you can tween any property of a movieclip by passing in a named array of property values

eg, Actionscript code
Tweener.addTween( target, { scaleX:1.5, scaleY:1.5, time:1, transition:”easeoutelastic”, onComplete:all_done } );

In this case the scaleX and scaleY properties on target will be tweened. This is a really flexible way of doing things. Sure it’s a bit prone to design time errors, but that’s the tradeoff. We don’t have the equivalent of named arrays in C#, so the next best thing is to create a parameter class and pass in values to the addTween method this way.

The TweenParameter class currently has the following properties for FrameworkElements. This represents all the properties that can have a tween transition applied to them.

LeftProperty

The Canvas.LeftProperty of the FrameworkElement

TopProperty

The Canvas.TopProperty of the FrameworkElement

Width

The Width of the FrameworkElement

Height

The Height of the FrameworkElement

X

The X property of a TranslateTransform

Y

The Y property of a TranslateTransform

ScaleX

The ScaleX property of a ScaleTransform

ScaleY

The ScaleY property of a ScaleTransform

SkewAngleX

The AngleX property of a SkewTransform

SkewAngleY

The AngleY property of a SkewTransform

RotateAngle

The Angle property of a RotateTransform

Opacity

The Opacity of the FrameworkElement

ZIndex

The Canvas.ZIndex of the FrameworkElement

It’s time to bring back Dooby to demonstrate this. In my previous KeySpline Animation post I used LiquidBoy’s Dooby in the sandpit to try out different keyspline animations. He’s back in the next sample to play around with some Tweener parameters on each of the transforms.

Again, the code for this sample is available on Codeplex. You’ll need to download the agTweener.zip file and TweenerDooby.zip.

Click the “Tween” button see Dooby transition from the reference position in the top left of the screen to the target position that you can define by either dragging Dooby to a new position, or type in the values in the form at the right.

I didn’t go as far as putting scale, rotate and skew controls around Dooby, so those properties are easy enough to just set directly in the HTML form.

I’ve also added in a nice little transition progress chart for each easing function that shows how the target values are being updated over time. The code was pretty simple in the end, check it out in the attachment.
When refreshing the page you may occassionally get a Javascript run time error. It appears to be something to do with the order in which the Silverlight object loads and wiring up the events here

_host.Content.Tweener.DoobyUpdatedEvent = firedFromScriptableEvent;

I haven’t figured that one out yet, so if you see it, just close your browser and load the sample again.

The last sample for this post demonstrates the event model around calling delegates on the onStart, onUpdate and onComplete events, and also using the delay property to set a delay before the tween begins. This sample is based on one of the original Tweener samples, ported across from Actionscript to C#.

20 blocks are dynamically created and added to the parent Canvas. Each block gets a random color from a predefined color palette.

A set of TweenParameter objects are created and the properties of each tween set.

open_tween.ScaleX = 1.5;
open_tween.ScaleY = 1.5;
open_tween.time = 0.5;
open_tween.RotateAngle = 90;
open_tween.Opacity = 0.3;
open_tween.transition = TransitionType.easeOutElastic;

We then attach event handlers to the MouseEnter, MouseLeave and MouseLeftButtonUp events as follows.

// Add some event listeners
b.MouseEnter += new MouseEventHandler(pop_open);
b.MouseLeave += new EventHandler(pop_close);
b.MouseLeftButtonUp += new MouseEventHandler(select_box);

The pop_open casts the sender to a Button class and then passes that the the addTween method to perform the selected tween on the target object.

private void pop_open(Object sender, EventArgs e)
{
Button
target = (Button)sender; // Get the current button
object
[] open_params = { “button open”, target.GetValue(Canvas.LeftProperty)};
Tweener
.addTween(target.Box, open_tween, new TweenEvent(UpdateTotalTweens), null, null, null, new TweenEvent(UpdateTotalTweens), open_params);
The UpdateTotalTweens method is created as a delegate function for the onStart and onComplete events. When the tween starts we want to update the total count, and we it completes we also want to update that value. An object array can also be passed as parameters for each of these tween events and returned as a parameter array to the delegate function.

private void UpdateTotalTweens(params object[] args)
{
string
msg;
if
(args == null)
msg = “”;
else
msg = (string)args[0] + ” “ + args[1].ToString();

this.TotalTweens.Text = “Total active tweens: “ + Tweener.TweenCount + “. Parameter on update: “ + msg;
}

That’s the start of what should hopefully be a useful toolkit for Silveright designers and developers. The similarity to the Tweener interface should make it easier for those coming across from Flash/Flex.

A version compatible with Silverlight 2.0 will be available right after MIX thanks to LiquidBoy’s connections and colloboration on this.

In the mean time let me know what else you’d like to see in here, or if you’d like to contribute to the project at CodePlex.

MC

3D collision detection, the code

December 13th, 2007

Following on from the last post which was an intro to the sample and background on some initial 3D engines being done in Silverlight, this post is a quick run through of the code behind the 3D model.

You can download the Visual Studio solution here. This requires VS2008 and Silverlight 1.1.

As referenced in the previous post this is a straight port of Alexey Gavrilov’s Silverlight 1.0 javascript code to VB.NET, and I’ve also added in a new slider control to adjust the zoom, which is the distance property within the model.

This sample defines a cube in 3D space through the x,y,z points of each vertex and then dynamically adds a predefined number of balls to the scene, each with a starting position and velocity. Five faces of the cube are rendered, each with a different fill colour.

Within the move function in each BallControl the ball position is updated by adding the x,y and z velocity to the current x,y and z positions and if the ball’s current position is on our outside the bounds of the cube then it’s velocity is reversed in the direction of the bounding plane. The doCollide function checks the position of the current ball against the position of a ball passed by reference to the function. If the distance between the two balls centres is less the radius of the balls then a collision has occurred and the velocity of both balls should be reversed.

The Visual Studio solution has the following files

BallControl.xaml
XAML representing a single ball, contains three Path objects
BallControl.xaml.vb
Defines the BallControl class. Constructor takes a reference to the parent Canvas and generates a random starting x,y,z position, ball radius and starting x,y,z velocity. Class contains functions to move the ball between frames, do a collision detection between itself and another ballcontrol passed by reference and also render the ball in 3D space.
Camera.vb
Defines functions to project a 3D x,y,z position to a 2D point on the view port and set the viewer point of view (POV) position.
Face.vb
Defines a single face of a 3D object. Used in this example to represent the face of a cube. Constructor takes an array of vertices that are then projected through the camera class to 2D points which are in turn rendered as a polygon in XAML.
Matrix.vb
Stores values for a 3 x 3 matrix. Used by the projection calculations in the camera class.
Model.vb
Defines the bounds of the cube and other parameters around elasticity, ball radius and speed. The shapes variable stores each face of the cube in an array and the model class contains functions to collectively set the projection properties and render the entire cube.
MousePosition.vb
Class stores the starting point of a mouse click in the model and the rotation and POV distance values of the cube at the time the mouse was clicked. Used as a reference point to determine the delta X and Y positions of the mouse drag and the subsequent rotation to be applied to the cube.
Page.xaml.vb
On the Page_Loaded event the model is initialized and _N BallControls are added to the Canvas. The slider is initialized and the timer started. On the Timer event each ball is moved and then a collision detection is performed between each ball and every other ball. The Page class also contains mouse click and drag handling functions to rotate the cube.
Projection.vb
Class stores the projection properties of a 3D point onto the 2D viewport plane. Properties are x, y, scale and depth, used in the Camera class.

The slider control has been modeled on the iTunes slider. I love the look of iTunes and inspired by LiquidBoy’s Project Silverlight 1.1 I’m also attempting to build some of the controls from iTunes in Silverlight. The slider and scrollbar may be the subject of some upcoming posts.

When dragged, the slider will adjust the distance from the camera property in the POV model. In the Page_Loaded event in Page.xaml.vb the slider ValueChanged event is wired to the UpdateZ method as shown below.

The setPOV function in the Camera class below shows how the R parameter (distance) is used.

The getProjection function in Camera.vb shows how an x,y,z coordinate position is mapped to the 2D viewport plane by calculating x, y, depth and scale variables.

3D collision detection and a simple 3D model

December 6th, 2007

This post takes the 2D collision detection concepts from previous experiments and extends this into 3D. Instead of just detecting collisions in X and Y directions, I show how this can be extended to work in the Z direction, and most importantly represent this model so it can be visualized in 3D, and in Silverlight 1.1 managed code.

The sample here is again based on Alex Gavrilovs work and I’ve converted his Silverlight 1.0 framework 3D engine into a managed code library in Silverlight 1.1.

3D in Silverlight is still in its infancy, but there’s already a few people working on 3D engines and some good stuff happening. There’s a lot to learn from these guys Mark Dawson’s Kit3D , The Balder 3D engine, looks like the start of bigger things to come.

There’s a couple of more mature 3D engines in Flash that have been growing and evolving. Papervision3D (this is a standout) and Sandy3D are two that I’ve taken a close look at in the process of getting familiar with and thinking of what’s going to be possible in Silverlight. I’d love to see someone take on a conversion of the OpenSource Papervision library to a managed C# library. This one’s a bit big for me but I’d contribute to a group effort.

Now back to the sample. Click on the image below to run in Silverlight in a new browser window

The slider control at the bottom adjusts the depth and if you drag your mouse on or around the cube the rotation of the cube can be adjusted. The slider control is my first creation of an iTunes control in Silverlight to be blogged in an upcoming post.

Source code for this sample and a quick run through of the main elements of the project to make all this work, and how this was translated to Silverlight 1.1 from Alex’s javascript library to do all this coming next..

MC

Drag Speed – let it fly

October 19th, 2007

Now that we’re capturing the drag speed of the ball control, the final step in this three part blog post is to show how the velocity of the drag remains with the control after the mouse is released.

I’ve reduced the number of balls in the experiment so we’ve got a bit more space to bounce around, and added back the X Speed and Y Speed indicator bars that we used in the previous post Drag speed and direction. This represents the difference in X position and Y position of the control between each timer event, or delta X and delta Y.

Now if you drag a ball (er bubble) and let it go it will continue on in that direction at that speed. Click the image below to open up the sample in a new window

That’s all kind of neat, but what good is it? Hmm, gets me thinking about scrolling user interfaces and more tactile feedback. Especially once we start to add some intertia to these motion paths. Feel free to take this and run with it, then let me know what you’re doing! There may be a couple more posts from me on this series.

The code for this post is available here BallDragSpeed.zip. Again, it’s Silverlight 1.1, VB.NET.

MC

Silverlight collision while dragging

October 19th, 2007

Following on from the previous post, this all looked good having ball controls bouncing around, but I wondered whether I could grab any ball and drag it, and still have all of the collision calculations work.

The next step after this one is to transfer the calculated drag speed for any ball into it’s vx and vy properties on release of the mouse, but to have all this work properly in the model we first need to make sure that all drag functions still maintain the basic collision detection.

I extended the initial BallControl silverlight control to have a named outer path so we can dynamically change its colour when selected. This will give us a nice visual cue to show which ball is being dragged.

Click the image below to see the experiment in action.

On the MouseLeftButtonDown event an _isMouseDown flag is set to true. This flag is used to bypass the normal calculation of the new position of the ball based on its currently velocity. The position to draw the ball control is then determined by the current mouse position.

The following code shows how the mouse is captured and the x and y position of the BallControl is updated as the mouse is moved.

The complete source code is available here DragCollisionDetection.zip

MC

Silverlight Collision Detection

October 18th, 2007

Hey, a month since that last post and there’s been heaps happening, just not on this blog! In amongst work, study and home life there’s been a bit of progress on the drag speed experiments. This and the next two posts coming up take us through how I got to the goal mentioned in the previous post - dragging an object, releasing it and letting it continue on at the same velocity as it was dragged.

I came across a framerate comparison between Silverlight, Flash, Flex and DHTML that was done by Alexey Gavrilo. The comparison used a nice animation Alexey put together and ported to each of these languages for comparison - reveals some interesting results!

I love the bouncing balls sample. There’s just something about watching it that’s mesmerising. The really interesting stuff is the maths behind it.

I took Alexey’s sample which did collision detection on round balls all of the same radius and extended it to do collision detection on balls of different sizes. Click the image below to check it out. You’ll need Silverlight 1.1 for this one.

The main Page.xaml file just contains the background, border, and a single storyboard that has a timer. The duration of the timer is set to 00:00:00 as this gives the fastest framerate. The balls are added dynamically as user controls, with a random diameter greater than a minimum limit set.

An array of BallControl items is defined, and each BallControl has it’s own position and velocity properties (x, y, vx, vy).

Each frame is drawn as the timer fires, and each ball control is rendered on screen at its x and y position. On the next frame each ball will have moved by its velocity, eg

x2 = x1 + vx
y2 = y1 + vy

If a ball’s x or y position is outside the bounds of the model then it’s x or y velocity is reversed, hence it will change direction and appear to bounce off the wall.

The cool bit is the collision detection. Alexey’s original collision detection code relied on the diameter of each ball being the same. The code snippet below shows how this was modified so that we can detetermine if a collision has occurred between balls of different sizes.

Each ball control is tested against every other ball control on every frame. The BallControl class has a doCollide function that accepts a reference to another BallControl being tested. The distance between the centre points of each ball is calculated and if this is less than the sum of radiuses of both balls then we have a collision. On collision the velocity of the opposite ball is transferred using the calculation above, and all is sweet.

Source code for the above sample can be downloaded here BallCollisionDetection.zip . You’ll need Visual Studio Orcas, Silverlight 1.1, and all code is in VB.NET.

MC

Drag speed and direction

September 18th, 2007

I started playing around with some basic dragging functionality in Silverlight to get a handle on how it all works. This post, and a couple following will take you through my attempt to get some feedback on the drag speed and direction of and object and use that to set a motion path of the object. Wynapse has got an excellent intro to the basics with his How To Drag Objects in the Silverlight Canvas blogpost and Nick Kramer takes it a step further with his drag and drop with feedback sample that shows how to capture the mouse movement and define parent and child containers.

I’m looking to capture the speed at which you drag an object and then keep the object moving at that speed, in the same direction as the drag. I figure it’s going to be a nice feature to build into controls where dragging is required and then build in a bit of intertia to slow the drag down from an initial speed set by how fast you started the drag. We’ll wait and see how and if it works when it’s there, but it should be a fun little exercise.

To start with, I picked up LiquidBoy’s round glass button off his awesome Blend Candy section (shameless rip again!), and converted that into a user control.

The control is scaled down to a useful size on the Page_Loaded event with the following code:

Private Sub ScaleControl(ByRef target As Control, ByVal scaleVal As Double)
‘Create a new scaletransform and apply it to the the target control
Dim tx As New ScaleTransform
tx.ScaleX = scaleVal
tx.ScaleY = scaleVal
target.RenderTransform = tx
End Sub

Then in Expression Blend I set up two rectangles to represent the X and Y drag speeds to give a bit of visual feedback. As we drag the round ball around the screen I’ll update the hight of the rectangles with the current X and Y drag speeds. The XAML for the sample is included in the attachment at the bottom of post.

Speed feedback

The drag speed in each of the X and Y directions is determined by calculating the difference between the previous X or Y position and the current X or Y position at timer intervals. The timer is set up using a Storyboard, defined in the Page.xaml file as follows:

<Storyboard x:Name=timer>
<
DoubleAnimation Duration=00:00:00.1 />
</
Storyboard>

The timer is started in the MouseLeftButtonDown event of the control and then stopped in the MouseLeftButtonUp event. Next I’d like a bit of feedback on the drag direction. I think an arrow pointing in the drag direction and positioned under the ball should do the trick, and then we can rotate the arrow to a position that matches the drag direction. I built an arrow by combining a rectangle and triangle (combined them together using the Object | Combine | Unite function in Blend), and then set the RenderTransformOrigin to the middle of the base of the arrow.

The trickiest part of all this is to work out the transform angle. If we’re dragging up (delta Y value is negative and delta X value is zero) then I want that to be zero degrees. If we’re dragging right (delta X value is positive and delta Y value is zero) then I want that to be 90 degress. A bit of good old trigonometry leads to the following calculation.

The ArcTan2 function is perfect for the job since it calculates the angle (in radians) using X and Y values specified as separate parameters.

Dim degrees As Double = Math.Atan2(beginX - prevX, 0 - (beginY - prevY)) * 180 / Math.PI
DirectionArrowTransform.Angle = degrees

This gives us some feeback as we move the control around.

Drag Speed Sample

When you release the mouse while dragging the X Speed and Y Speed will display the release speed. In my next post I’ll take the current speed and continue the motion of the control in the same direction as it was being dragged when the mouse was released.

The complete sample source code is available here DragSpeed2.zip. You’ll need Visual Studio Orcas, Silverlight 1.1, and all code is in VB.NET. Any suggestions, comments or questions welcome

MC

Keyspline animation

September 16th, 2007

This post is quick run through a test app I built to get a better understanding of KeySpline animation in Blend and Silverlight. I’m working towards converting some projects I did in Flash and Actionscript over the past few years to Silverlight and then take them forward with some new ideas.

Given that my background is in .NET development I was pretty excited when I found out about Silverlight. Can Microsoft get up there with Macromedia and Flash (which is an awesome product!), how is the toolset going to fit in with Visual Studio, is it going to be truly cross-platform, is it going to be easier to build a RIA? These are the types of questions I had in my head the when I first checked out Expression Blend and Silverlight 1.0. In short, I’ve got to say I’m impressed. Time to get in at the ground level ‘cause this baby’s going somewhere.

Around the same time as starting my journey into Silverlight a mate of mine Jose Fajardo (aka LiquidBoy) got going on his <Project Silverlight 1.1> how to do iTunes in Silverlight project. If you haven’t seen this then check it out, and the rest of his <blog>, Jose is one smart dude. Encouraged by this I made a bit more time for playing with this stuff and set up the blog. So, one of the first little experiments I’ve been looking at is KeySpline animation. There’s heaps of places in a nice UI to use a nice smooth animation with either an ease-in or ease-out style, just like a tween in Flash. I came across an excellent post on the Microsoft Expression Blog about Keyframe easing and key splinesThis explains how the KeySpline control points determine the path of the spline, which in turn defines the rate of change of the value being animated over time. By modify the control points we can get a wide range of easing motions with a single line XAML statement like this:     

<SplineDoubleKeyFrame Value=“100
KeyTime=0:0:1
KeySpline=0.0,0.5,0.5,0.0 />

The problem I had was trying to visualize the effect of the different control point positions on the feel of the animation. Sure, you can draw out little grid, put your control points in, estimate the spline and have a guess about how it’s going to look, but I wanted to see it and play around with it. I used the layout from the Expression Blog post above, designed the UI in Expression and wrote some code to be able to drag the control points around, give some feedback on what the control point values are, and then see that animation in action.

The end result is a Silverlight app that’s a good little test harness for trying out different KeySpline control points.

I also needed to animate something. LiquidBoy’s building up a nice set of assets with his Blend Candy collection so I thought we could get some mileage out of Dooby the Penguin (thanks LiquidBoy!)In the sample below, click and drag the two control points around to make a new spline, then click the Animate button. The textbox shows the SplineDoubleKeyFrame values to create that animation. To start again click the Reset button.

. KeySpline animation harness

The button control came from Tim Heuer’s blog post implementing silverlight controls in 1.0. The GlassButtonControl looks great and is simple, nice one Tim. I converted Tim’s sample code to VB.NET and included it as a user control in my project. Dooby was also created as a user control to keep the main Page.xaml file a bit cleaner.

The KeySpline property value of the SplineDoubleKeyFrame tag has the X and Y values with the 1 x 1 sqaure of the two control points, eg X1,Y1,X2,Y2. By dragging the control points around to make the spline steeper at the beginning we can see that this creates a motion path with the speed of the object being animated faster at the start.

Another way to look at it is that when the spline is a straight line the velocity will be constant, when the spline is curved then the object will be accelerating or decelerating, based on the shape of the curve. It’s so much easier to get this by playing with the sample rather than trying to explain it in words!

The complete project source code is available here KeySplineAnimHarness.zip. You’ll need Visual Studio Orcas, Silverlight 1.1, and all code is in VB.NET. Any suggestions, comments or questions welcome. MC