Composing animations with Silverlight.FX

When I read Nikhil’s “Effects and Transitions for Silverlight” and its accompanying Silverlight.FX framework, I was impressed by how easy it was, and is, to create an animation and declare it on any Silverlight framework element.

<Grid>
    <Grid.RowDefinitions>...</Grid.RowDefinitions>
        <fxglitz:Effects.ClickEffect>
            <fxglitz:HighlightEffect TargetName="highlightImage" HighlightColor="Yellow" Duration="00:00:01" />
        </fxglitz:Effects.ClickEffect>
        <Border x:Name="highlightImage">
            <Image Source="/Silverlight.png" />
        </Border>
        <TextBlock Grid.Row="1">Highlight</TextBlock>
</Grid>

With a framework this powerful, I wanted to extend it even further by providing a fluent interface, similar to jQuery, to compose and chain animations together. This way, you can declare a common animation element and behavior once, and apply it to any framework element you require, swap it for another, or chain reusable components together.

Here is the equivalent code for the highlight example above, using the new fluent interface:

Animator.WithNew(highlightImage)
        .Highlight(Colors.Yellow)
        .For(1.Seconds())
        .When(EffectBehaviors.Clicked)
        .Play();

So far we have a nice, code-centric way to declare these powerful effects (or any custom effects you create in addition to the ones provided with FX). Now we can take it even further by providing animation chaining to achieve the results of the CompositeAnimation effect in a natural way.

<fxui:ClickEffect>
    <fxeffects:CompositeEffect AutoReverse="True" Composition="Parallel">
        <fxeffects:Move TargetName="compositeImage" HorizontalMovement="50" Duration="00:00:01" Easing="QuadraticInOut" />
        <fxeffects:Resize TargetName="compositeImage" ScaleXRatio="0.5" ScaleYRatio="0.5" Duration="00:00:01" Easing="QuadraticInOut" />
        <fxeffects:Spin TargetName="compositeImage" SpinAngle="360" Duration="00:00:01" Easing="QuadraticInOut" />
        <fxeffects:Fade TargetName="compositeImage" FadeOpacity="0.5" Duration="00:00:01" Easing="QuadraticInOut" />
    </fxeffects:CompositeEffect>
</fxui:ClickEffect>

The above is nice and declarative, but you can achieve better readability and flow in the code below. In addition to parallel animations, you can also mix it up with sequential animations using the Then() method.

Animator.WithNew(compositeImage)
     .WithEasing(EffectEasing.QuadraticInOut)
     .Move(50).For(1.Seconds())
     .And().Resize(0.5, 0.5).For(1.Seconds())
     .And().Spin(360).For(1.Seconds())
     .And().FadeTo(0.5).For(1.Seconds())
     .Play();

You can also predefine animations and remix them at runtime using the the new interface. For example, the composite effect above is made up of four separate animations. Using the declarative approach we would have to create a new effect that wraps all of those effects, or rewrite them every time we wanted that particular combination of effects. Using a fluent interface we can declare each animation separately, and use them in one or many places interchangeably.

// Move script (used on another image)
var move = Animator.WithNew().Move(50).For(1.Seconds());
move.On(moveImage).Play();

// Resize script (used on another image)
var resize = Animator.WithNew().Resize(0.5, 0.5).For(1.Seconds());
resize.On(resizeImage).Play();

// Spin script (used on another image)
var spin = Animator.WithNew().Spin(360).For(1.Seconds());
spin.On(spinImage).Play();

// An animation on a new target but reusing
// the animations used on other targets
Animator.WithNew(compositeImage)
    .WithEasing(EffectEasing.QuadraticInOut)
    .FadeTo(0.5).For(1.Seconds())
    .And(move)
    .And(resize)
    .And(spin)
    .When(EffectBehaviors.Clicked)
    .Play();

The results above are achieved by combining animators’ contents together in the And() overloaded method. You are free to download the project, which includes the same effects examples from Silverlight.FX using the new fluent interface in the code-behind.

Enjoy!
Downloads: AnimationComposer

kick it on DotNetKicks.com

Sharing
  • Print this article!
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Identi.ca
  • TwitThis