Silverlight Animation Part 2: Size

Now we'll extend our animation system to be able to animate an elements size. You can see the end result of this post at Silverlight Animation Examples

After the original post "Beginning a Silverlight Animation Framework" I was asked a few times "Why would I need something like this?". For a lot of your one off animations it makes sense to use a storyboard that's part of your user control resources, this way it's part of your designers workflow in Blend.

But when you're creating controls that will be reused throughout the application (or even multiple applications) such as Blacklight then having quick access to programmatic animations becomes very handy. In later posts I'll show some applications of it.

So size animations, these are going to be very similar to our position animation, both are going to use two double key spline animations, the only difference will be the property that will be the target of the animation. In this case we'll be animating the "Framework.Width" & "Framework.Height" properties.

Below is the SizeAnimation class:

public class SizeAnimation : AnimationBase
{
    public static TimeSpan DefaultDuration = TimeSpan.FromMilliseconds(750);
 
    public SizeAnimation(double width, double height)
        : this(width, height, DefaultDuration)
    {
 
    }
 
    public SizeAnimation(double width, double height, TimeSpan duration)
    {
        Width = width;
        Height = height;
        Duration = duration;
    }
 
    public double Width
    {
        get;
        private set;
    }
 
    public double Height
    {
        get;
        private set;
    }
 
    public TimeSpan Duration
    {
        get;
        private set;
    }
 
    protected override Storyboard CreateStoryboard()
    {
        var storyboard = new Storyboard();
 
        var widthAnimation = new DoubleAnimationUsingKeyFrames();
        var heightAnimation = new DoubleAnimationUsingKeyFrames();
 
        Storyboard.SetTargetProperty(widthAnimation, new PropertyPath("(FrameworkElement.Width)"));
        Storyboard.SetTargetProperty(heightAnimation, new PropertyPath("(FrameworkElement.Height)"));
 
        storyboard.Children.Add(widthAnimation);
        storyboard.Children.Add(heightAnimation);
 
        widthAnimation.KeyFrames.Add(new SplineDoubleKeyFrame()
        {
            KeySpline = new KeySpline()
            {
                ControlPoint1 = new Point(0.528, 0),
                ControlPoint2 = new Point(0.142, 0.847)
            }
        });
 
        heightAnimation.KeyFrames.Add(new SplineDoubleKeyFrame()
        {
            KeySpline = new KeySpline()
            {
                ControlPoint1 = new Point(0.528, 0),
                ControlPoint2 = new Point(0.142, 0.847)
            }
        });
 
        return storyboard;
    }
 
    protected override void ApplyValues(Storyboard storyboard)
    {
        if(storyboard == null)
            throw new ArgumentNullException("storyboard");
 
        var widthAnimation = storyboard.Children[0] as DoubleAnimationUsingKeyFrames;
        var heightAnimation = storyboard.Children[1] as DoubleAnimationUsingKeyFrames;
 
        widthAnimation.KeyFrames[0].Value = Width;
        widthAnimation.KeyFrames[0].KeyTime = KeyTime.FromTimeSpan(Duration);
        heightAnimation.KeyFrames[0].Value = Height;
        heightAnimation.KeyFrames[0].KeyTime = KeyTime.FromTimeSpan(Duration);
    }
}

and here's our animation extension to use it.

public static void AnimateSize(this FrameworkElement element, double width, double height)
{
    new SizeAnimation(width, height).Apply(element);
}

You can see the end result of this post at Silverlight Animation Examples.