Silverlight how to: Procedural Animation
March 11, 2008 @ 8:40 am in Microsoft, Silverlight
Whenever possible developers should encourage designers to maintain all of their Silverlight storyboards within XAML. This allows the designers the optimum environment to use a tool like Blend to tweak the animation timing, easing and any relevant Key Splines. That said, there are situations where a developer may create a UserControl that requires full control over the format of the animation. Defining this storyboard procedurally, allows the developer a more consistent level of control and allows an easier approach to manipulating properties within this storyboard.
The following will show a simple example of how one could include a “DoubleAnimationUsingKeyFrames” that allows the TranslateTransform’s “X” property to be manipulated each time the animation is played.
The first step in defining our animating UserControl is to attach a “Loaded” event handler within our constructor. This allows us to have the XAML parsed by the UserControls base class, yet inject a procedural storyboard into the UserControls resources.
1 2 3 4 5 | public Box()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(Page_Loaded);
} |
Our storyboard will include a “DoubleAnimationUsingKeyFrames”, “SplineDoubleKeyFrame” with a corresponding “KeySpline”. I have chosen to refactor this logic into a method. In the event that we wanted to manipulate both the “X” and the “Y” TranslateTransform property, this method could be called twice passing both “X” and “Y” as the last argument.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | private static SplineDoubleKeyFrame CreateDoubleAnimation(ref Storyboard sb,
TranslateTransform translation, string property)
{
DoubleAnimationUsingKeyFrames da = new DoubleAnimationUsingKeyFrames();
da.SetValue(NameProperty, string.Concat("da_", property));
SplineDoubleKeyFrame sdkf = new SplineDoubleKeyFrame();
sdkf.SetValue(NameProperty, string.Concat("sdkf_",property));
sdkf.Value = 0;
sdkf.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.25));
//define the KeySpline
KeySpline ksX = new KeySpline();
ksX.ControlPoint1 = new Point(1.0, 0.25);
ksX.ControlPoint2 = new Point(0.75, 1.0);
sdkf.KeySpline = ksX;
//add the SplineDoubleKeyFrame to the DoubleAnimationUsingKeyFrames
da.KeyFrames.Add(sdkf);
//define which TranslateTransform property will be targeted by the DoubleAnimation
Storyboard.SetTarget(da, translation);
Storyboard.SetTargetProperty(da, property);
sb.Children.Add(da);
return sdkf;
} |
Within our Page_Loaded handler we define the transformation group for this control, call our helper function and insert the storyboard into the UserControls grid (LayoutRoot) resource collection. In this example, we are only manipulating the 2D, X/Y coordinate system so we only need to include the “TranslateTransform” within the transform group. If Scale was being translated as well, we would include a “ScaleTransform” object within the group.
1 2 3 4 5 6 7 8 9 10 11 12 | void Page_Loaded(object sender, RoutedEventArgs e)
{
//define the Render Transformation for this control
TranslateTransform translation = new TranslateTransform();
TransformGroup transforms = new TransformGroup();
transforms.Children.Add(translation);
this.RenderTransform = transforms;
_sdkfX = CreateDoubleAnimation(ref _sb, translation, "X");
this.LayoutRoot.Resources.Add("playerAnimation", _sb);
} |
Lastly, I created a public method in the UserControl that sets the “X” and starts the animation. This method can be called repeatedly from the location that is instantiating this UserControl.
1 2 3 4 5 6 | public bool Animate(int x)
{
_sdkfX.SetValue(SplineDoubleKeyFrame.ValueProperty, x);
_sb.Begin();
return true;
} |
Code: Animation.zip
/p>
Tagged as 

March 24th, 2008 at 3:43 am
omg.. good work, guy