WPF: Animating along the Path

By now, WPF's animation is probably one of the biggest topics in the .NET community.  WPF provides so many ways to do all sorts of neat animations.  I wanted to start to discuss some of these features.  For intstance, below is an animation of an ellipse along a path.

<Window x:Class="WPFSamples.Client.Animation.Paths.PathAnimations001"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="PathAnimations001" Height="300" Width="300">
 <Window.Resources>
  <Storyboard x:Key="Storyboard1">
   <DoubleAnimationUsingPath BeginTime="00:00:00" Duration="00:00:02" Storyboard.TargetName="ellipseLocation" Storyboard.TargetProperty="X" Source="X" AutoReverse="True">
    <DoubleAnimationUsingPath.PathGeometry>
     <PathGeometry Figures="M88,56 C82,35 73,15 31,31 C5.,40 -8,52 -25,77 C-40.,101 -50.,130 -61,157 C-72,185 -74,215 -88,242"/>
    </DoubleAnimationUsingPath.PathGeometry>
   </DoubleAnimationUsingPath>
   <DoubleAnimationUsingPath BeginTime="00:00:00" Duration="00:00:02" Storyboard.TargetName="ellipseLocation" Storyboard.TargetProperty="Y" Source="Y" AutoReverse="True">
    <DoubleAnimationUsingPath.PathGeometry>
     <PathGeometry Figures="M88,56 C82,35 73,15 31,31 C5.,40 -8,52 -25,77 C-40.,101 -50.,130 -61,157 C-72,185 -74,215 -88,242"/>
    </DoubleAnimationUsingPath.PathGeometry>
   </DoubleAnimationUsingPath>
  </Storyboard>
 </Window.Resources>
 <Window.Triggers>
  <EventTrigger RoutedEvent="FrameworkElement.Loaded">
   <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
  </EventTrigger>
 </Window.Triggers>
 <StackPanel>
  <Ellipse Width="50" Height="50" RenderTransformOrigin="0.5,0.5" x:Name="ellipse" >
   <Ellipse.RenderTransform>
    <TransformGroup>
     <TranslateTransform x:Name="ellipseLocation" X="0" Y="0"/>
    </TransformGroup>
   </Ellipse.RenderTransform>
   <Ellipse.Fill>
    <RadialGradientBrush SpreadMethod="Reflect">
     <GradientStop Color="#FFEDEDF4" Offset="0"/>
     <GradientStop Color="#FFCA2323" Offset="1"/>
     <GradientStop Color="#FFD6D37B" Offset="0.478"/>
    </RadialGradientBrush>
   </Ellipse.Fill>
  </Ellipse>
 </StackPanel>
</Window>

This markup has several key elements:

  • At the bottom of the markup is an ellipse with a RadialGradientBrush.  This brush is a nice looking brush that gives the ellipse a neat effect.
  • A storyboard object in the resources collection.  A storyboard is the "orchestrator" of sorts of the animation.  It's responsible for managing the animation timeline and performing the changes to the X and Y property of the target object (via the Storyboard.TargetName and StoryBoard.TargetProperty).

A storyboard targets a FrameworkElement object with a name.  The Ellipse has a RenderTransform attribute called TranslateTransform that's responsible for moving the object.  So values entered to the TranslateTransform move an object.  The Storyboard is going to move the object when the Loaded event is fired on the target object.

So the Storyboard uses the TranslateTransform, passing values to the X and Y properties of the TranslateTransform and consequently moving the object.  The object moves along a path provided by the PathGeometry.  I'll talk more about this later, but know that the path coordinates, along with the M, C, and other values, actually draw an arcing line that the ellipse will traverse.

When the application runs, the ellispe goes up curves around south and drops almost off of the screen.  Because the AutoReverse property is set to true, the animation reverses when it is finished, and there you have a simple animation.

Note that the path was drawn with the Expression Blend tool, and later I'll show how to draw animations with this tool.

Comments

No Comments