Path Animations Overview

This topic introduces path animations, which enable you to use a geometric path to generate output values. Path animations are useful for moving and rotating objects along complex paths.

Prerequisites

To understand this topic, you should be familiar with WPF animations features. For an introduction to animation features, see the Animation Overview.

Because you use a PathGeometry object to define a path animation, you should also be familiar with PathGeometry and the different types of PathSegment objects. For more information, see the Geometry Overview.

What Is a Path Animation?

A path animation is a type of AnimationTimeline that uses a PathGeometry as its input. Instead of setting a From, To, or By property (as you do for a From/To/By animation) or using key frames (as you use for a key-frame animation), you define a geometric path and use it to set the PathGeometry property of the path animation. As the path animation progresses, it reads the x, y, and angle information from the path and uses that information to generate its output.

Path animations are very useful for animating an object along a complex path. One way to move an object along a path is to use a MatrixTransform and a MatrixAnimationUsingPath to transform an object along a complex path. The following example demonstrates this technique by using the MatrixAnimationUsingPath object to animate the Matrix property of a MatrixTransform. The MatrixTransform is applied to a button and causes it to move along a curved path. Because the DoesRotateWithTangent property is set to true, the rectangle rotates along the tangent of the path.

<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" 
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="PresentationOptions" Margin="20">
  <Canvas Width="400" Height="400">
      
    <!-- The Button that is animated across the screen by animating
         the MatrixTransform applied to the button. -->
    <Button MinWidth="100" Content="A Button">
      <Button.RenderTransform>
        <MatrixTransform x:Name="ButtonMatrixTransform">
          <MatrixTransform.Matrix >
            <Matrix />
          </MatrixTransform.Matrix>
        </MatrixTransform>
      </Button.RenderTransform>
      <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Loaded">
          <BeginStoryboard>
            <Storyboard>
              <MatrixAnimationUsingPath
              Storyboard.TargetName="ButtonMatrixTransform"
              Storyboard.TargetProperty="Matrix"
              DoesRotateWithTangent="True"
              Duration="0:0:5" 
              RepeatBehavior="Forever" >
                <MatrixAnimationUsingPath.PathGeometry>
                  <PathGeometry 
                    Figures="M 10,100 C 35,0 135,0 160,100 180,190 285,200 310,100" 
                    PresentationOptions:Freeze="True" />
                </MatrixAnimationUsingPath.PathGeometry>
              </MatrixAnimationUsingPath>
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </Button.Triggers>
    </Button>
  </Canvas>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SDKSample
{

    /// <summary>
    /// Shows how to animate an object along
    /// a geometric path.
    /// </summary>
    public class MatrixAnimationUsingPathDoesRotateWithTangentExample : Page
    {

        public MatrixAnimationUsingPathDoesRotateWithTangentExample()
        {
            this.Margin = new Thickness(20);

            // Create a NameScope for the page so that
            // we can use Storyboards.
            NameScope.SetNameScope(this, new NameScope());

            // Create a button.
            Button aButton = new Button();
            aButton.MinWidth = 100;
            aButton.Content = "A Button";

            // Create a MatrixTransform. This transform
            // will be used to move the button.
            MatrixTransform buttonMatrixTransform = new MatrixTransform();
            aButton.RenderTransform = buttonMatrixTransform;

            // Register the transform's name with the page
            // so that it can be targeted by a Storyboard.
            this.RegisterName("ButtonMatrixTransform", buttonMatrixTransform);

            // Create a Canvas to contain the button
            // and add it to the page.
            // Although this example uses a Canvas,
            // any type of panel will work.
            Canvas mainPanel = new Canvas();
            mainPanel.Width = 400;
            mainPanel.Height = 400;
            mainPanel.Children.Add(aButton);
            this.Content = mainPanel;

            // Create the animation path.
            PathGeometry animationPath = new PathGeometry();
            PathFigure pFigure = new PathFigure();
            pFigure.StartPoint = new Point(10, 100);
            PolyBezierSegment pBezierSegment = new PolyBezierSegment();
            pBezierSegment.Points.Add(new Point(35, 0));
            pBezierSegment.Points.Add(new Point(135, 0));
            pBezierSegment.Points.Add(new Point(160, 100));
            pBezierSegment.Points.Add(new Point(180, 190));
            pBezierSegment.Points.Add(new Point(285, 200));
            pBezierSegment.Points.Add(new Point(310, 100));
            pFigure.Segments.Add(pBezierSegment);
            animationPath.Figures.Add(pFigure);

            // Freeze the PathGeometry for performance benefits.
            animationPath.Freeze();

            // Create a MatrixAnimationUsingPath to move the
            // button along the path by animating
            // its MatrixTransform.
            MatrixAnimationUsingPath matrixAnimation =
                new MatrixAnimationUsingPath();
            matrixAnimation.PathGeometry = animationPath;
            matrixAnimation.Duration = TimeSpan.FromSeconds(5);
            matrixAnimation.RepeatBehavior = RepeatBehavior.Forever;

            // Set the animation's DoesRotateWithTangent property
            // to true so that rotates the rectangle in addition
            // to moving it.
            matrixAnimation.DoesRotateWithTangent = true;

            // Set the animation to target the Matrix property
            // of the MatrixTransform named "ButtonMatrixTransform".
            Storyboard.SetTargetName(matrixAnimation, "ButtonMatrixTransform");
            Storyboard.SetTargetProperty(matrixAnimation,
                new PropertyPath(MatrixTransform.MatrixProperty));

            // Create a Storyboard to contain and apply the animation.
            Storyboard pathAnimationStoryboard = new Storyboard();
            pathAnimationStoryboard.Children.Add(matrixAnimation);

            // Start the storyboard when the button is loaded.
            aButton.Loaded += delegate(object sender, RoutedEventArgs e)
            {
                // Start the storyboard.
                pathAnimationStoryboard.Begin(this);
            };
        }
    }
}

Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Imports System.Windows.Navigation
Imports System.Windows.Shapes


Namespace SDKSample

    ''' <summary>
    ''' Shows how to animate an object along
    ''' a geometric path.
    ''' </summary>
    Public Class MatrixAnimationUsingPathDoesRotateWithTangentExample
        Inherits Page

        Public Sub New()
            Me.Margin = New Thickness(20)

            ' Create a NameScope for the page so that
            ' we can use Storyboards.
            NameScope.SetNameScope(Me, New NameScope())

            ' Create a button.
            Dim aButton As New Button()
            aButton.MinWidth = 100
            aButton.Content = "A Button"

            ' Create a MatrixTransform. This transform
            ' will be used to move the button.
            Dim buttonMatrixTransform As New MatrixTransform()
            aButton.RenderTransform = buttonMatrixTransform

            ' Register the transform's name with the page
            ' so that it can be targeted by a Storyboard.
            Me.RegisterName("ButtonMatrixTransform", buttonMatrixTransform)

            ' Create a Canvas to contain the button
            ' and add it to the page.
            ' Although this example uses a Canvas,
            ' any type of panel will work.
            Dim mainPanel As New Canvas()
            mainPanel.Width = 400
            mainPanel.Height = 400
            mainPanel.Children.Add(aButton)
            Me.Content = mainPanel

            ' Create the animation path.
            Dim animationPath As New PathGeometry()
            Dim pFigure As New PathFigure()
            pFigure.StartPoint = New Point(10, 100)
            Dim pBezierSegment As New PolyBezierSegment()
            pBezierSegment.Points.Add(New Point(35, 0))
            pBezierSegment.Points.Add(New Point(135, 0))
            pBezierSegment.Points.Add(New Point(160, 100))
            pBezierSegment.Points.Add(New Point(180, 190))
            pBezierSegment.Points.Add(New Point(285, 200))
            pBezierSegment.Points.Add(New Point(310, 100))
            pFigure.Segments.Add(pBezierSegment)
            animationPath.Figures.Add(pFigure)

            ' Freeze the PathGeometry for performance benefits.
            animationPath.Freeze()

            ' Create a MatrixAnimationUsingPath to move the
            ' button along the path by animating
            ' its MatrixTransform.
            Dim matrixAnimation As New MatrixAnimationUsingPath()
            matrixAnimation.PathGeometry = animationPath
            matrixAnimation.Duration = TimeSpan.FromSeconds(5)
            matrixAnimation.RepeatBehavior = RepeatBehavior.Forever

            ' Set the animation's DoesRotateWithTangent property
            ' to true so that rotates the rectangle in addition
            ' to moving it.
            matrixAnimation.DoesRotateWithTangent = True

            ' Set the animation to target the Matrix property
            ' of the MatrixTransform named "ButtonMatrixTransform".
            Storyboard.SetTargetName(matrixAnimation, "ButtonMatrixTransform")
            Storyboard.SetTargetProperty(matrixAnimation, New PropertyPath(MatrixTransform.MatrixProperty))

            ' Create a Storyboard to contain and apply the animation.
            Dim pathAnimationStoryboard As New Storyboard()
            pathAnimationStoryboard.Children.Add(matrixAnimation)

            ' Start the storyboard when the button is loaded.
            AddHandler aButton.Loaded, Sub(sender As Object, e As RoutedEventArgs) pathAnimationStoryboard.Begin(Me)



        End Sub
    End Class
End Namespace

For more information about the path syntax that is used in the XAML example, see the Path Markup Syntax overview. For the complete sample, see Path Animation Sample.

You can apply a path animation to a property by using a Storyboard in XAML and code, or by using the BeginAnimation method in code. You can also use a path animation to create an AnimationClock and apply it to one or more properties. For more information about the different methods for applying animations, see Property Animation Techniques Overview.

Path Animation Types

Because animations generate property values, there are different animation types for different property types. To animate a property that takes a Double (such as the X property of a TranslateTransform), you use an animation that produces Double values. To animate a property that takes a Point, you use an animation that produces Point values, and so on.

Path animation classes belong to the System.Windows.Media.Animation namespace and use the following naming convention:

<Type> AnimationUsingPath

Where <Type> is the type of value that the class animates.

WPF provides the following path animation classes.

Property type Corresponding path animation class Example
Double DoubleAnimationUsingPath Animate an Object Along a Path (Double Animation)
Matrix MatrixAnimationUsingPath Animate an Object Along a Path (Matrix Animation)
Point PointAnimationUsingPath Animate an Object Along a Path (Point Animation)

A MatrixAnimationUsingPath generates Matrix values from its PathGeometry. When used with a MatrixTransform, a MatrixAnimationUsingPath can move an object along a path. If you set the DoesRotateWithTangent property of the MatrixAnimationUsingPath to true, it also rotates the object along the curves of the path.

A PointAnimationUsingPath generates Point values from the x- and y-coordinates of its PathGeometry. By using a PointAnimationUsingPath to animate a property that takes Point values, you can move an object along a path. A PointAnimationUsingPath cannot rotate objects.

A DoubleAnimationUsingPath generates Double values from its PathGeometry. By setting the Source property, you can specify whether the DoubleAnimationUsingPath uses the x-coordinate, y-coordinate, or angle of the path as its output. You can use a DoubleAnimationUsingPath to rotate an object or move it along the x-axis or y-axis.

Path Animation Input

Each path animation class provides a PathGeometry property for specifying its input. The path animation uses the PathGeometry to generate its output values. The PathGeometry class lets you describe multiple complex figures that are composed of arcs, curves, and lines.

At the heart of a PathGeometry is a collection of PathFigure objects; these objects are so named because each figure describes a discrete shape in the PathGeometry. Each PathFigure consists of one or more PathSegment objects, each of which describes a segment of the figure.

There are many types of segments.

Segment Type Description
ArcSegment Creates an elliptical arc between two points.
BezierSegment Creates a cubic Bezier curve between two points.
LineSegment Creates a line between two points.
PolyBezierSegment Creates a series of cubic Bezier curves.
PolyLineSegment Creates a series of lines.
PolyQuadraticBezierSegment Creates a series of quadratic Bezier curves.
QuadraticBezierSegment Creates a quadratic Bezier curve.

The segments in a PathFigure are combined into a single geometric shape, which uses the end point of a segment as the start point of the next segment. The StartPoint property of a PathFigure specifies the point from which the first segment is drawn. Each subsequent segment starts at the end point of the previous segment. For example, a vertical line from 10,50 to 10,150 can be defined by setting the StartPoint property to 10,50 and creating a LineSegment with a Point property setting of 10,150.

For more information about PathGeometry objects, see the Geometry Overview.

In XAML, you can also use a special abbreviated syntax to set the Figures property of a PathGeometry. For more information, see Path Markup Syntax overview.

For more information about the path syntax that is used in the XAML example, see the Path Markup Syntax overview.

See also