路径动画概述

本主题介绍了路径动画,使你能够使用几何路径来生成输出值。 路径动画可用于沿着复杂路径移动和旋转对象。

先决条件

若要了解本主题,应熟悉 WPF 动画功能。 有关动画功能的简介,请参阅动画概述

由于你使用 PathGeometry 对象来定义一个路径动画,因此还应熟悉 PathGeometry 和不同类型的 PathSegment 对象。 有关详细信息,请参阅几何概述

什么是路径动画?

路径动画是一种使用 PathGeometry 作为输入的 AnimationTimeline。 可以定义一个几何路径并使用它来设置路径动画的 PathGeometry 属性,而不是设置 From、To 或 By 属性(如对 From/To/By 动画所执行的操作)或使用关键帧(如用于关键帧动画)。 路径动画运行时,会从路径中读取 x、y 和角度信息并使用该信息生成其输出。

路径动画对沿着复杂路径的对象进行动画处理非常有用。 沿着路径移动对象的一种方法是使用 MatrixTransformMatrixAnimationUsingPath 来沿着复杂路径转换对象。 下面的示例通过使用 MatrixAnimationUsingPath 对象对 MatrixTransformMatrix 属性进行动画处理来演示此方法。 MatrixTransform 应用于按钮,并使其沿着曲线路径移动。 由于 DoesRotateWithTangent 属性设置为 true,因此矩形会沿着路径的切线旋转。

<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

有关 XAML 示例中使用的路径语法的详细信息,请参阅路径标记语法概述。 有关完整示例,请参阅路径动画示例

通过在 XAML 和代码中使用 Storyboard 或在代码中使用 BeginAnimation 方法,可以将路径动画应用到属性。 还可以使用路径动画创建 AnimationClock,并将其应用到一个或多个属性中。 有关应用动画的不同方法的详细信息,请参阅属性动画技术概述

路径动画类型

由于动画会生成属性值,因此不同的属性类型具有不同的动画类型。 要对采用 Double 的属性(例如 TranslateTransformX 属性)进行动画处理,可以使用生成 Double 值的动画。 要为采用 Point 的属性进行动画处理,请使用生成 Point 值的动画,依此类推。

路径动画类属于 System.Windows.Media.Animation 命名空间,并使用以下命名约定:

<Type> AnimationUsingPath

其中 <Type> 为该类进行动画处理的值的类型

WPF 提供以下路径动画类。

属性类型 相应的路径动画类 示例
Double DoubleAnimationUsingPath 沿着路径针对对象进行动画处理(双重动画)
Matrix MatrixAnimationUsingPath 沿着路径针对对象进行动画处理(矩阵动画)
Point PointAnimationUsingPath 沿着路径针对对象进行动画处理(点动画)

MatrixAnimationUsingPath 从其 PathGeometry 生成 Matrix 值。 与 MatrixTransform 一起使用时,MatrixAnimationUsingPath 可以沿路径移动对象。 如果将 MatrixAnimationUsingPathDoesRotateWithTangent 属性设置为 true,它还会沿路径曲线旋转对象。

PointAnimationUsingPath 从其 PathGeometry 的 x 和 y 坐标生成 Point 值。 通过使用 PointAnimationUsingPath 对采用 Point 值的属性进行动画处理,可以沿路径移动对象。 PointAnimationUsingPath 不能旋转对象。

DoubleAnimationUsingPath 从其 PathGeometry 生成 Double 值。 通过设置 Source 属性,可以指定 DoubleAnimationUsingPath 是使用 x 坐标、y 坐标还是路径的角度作为其输出。 可以使用 DoubleAnimationUsingPath 来沿着 x 轴或 y 轴旋转或移动对象。

路径动画输入

每个路径动画类提供了 PathGeometry 属性,用于指定其输入。 路径动画使用 PathGeometry 生成其输出值。 PathGeometry 类能够描述组成弧线、曲线和直线的多个复杂图形。

PathGeometry 的核心是 PathFigure 对象的集合;这些对象之所以如此命名,是因为每个图都描述了 PathGeometry 中的一个离散形状。 每个 PathFigure 都由一个或多个 PathSegment 对象组成,其中每一个都描述了图的一个线段。

有多种类型的线段。

线段类型 说明
ArcSegment 在两点之间创建一条椭圆弧。
BezierSegment 创建两个点之间的三次方贝塞尔曲线。
LineSegment 创建两个点之间的直线。
PolyBezierSegment 创建一系列三次方贝塞尔曲线。
PolyLineSegment 创建一系列直线。
PolyQuadraticBezierSegment 创建一系列二次贝塞尔曲线。
QuadraticBezierSegment 创建一条二次贝塞尔曲线。

PathFigure 中的多个线段组合成一个几何形状,它使用线段的终点作为下一段的起点。 PathFigureStartPoint 属性指定绘制第一个线段的起点。 每个后续段都从上一段的终点开始。 例如,通过将 StartPoint 属性设置为 10,50 并创建一个 Point 属性设置为 10,150LineSegment,可以定义从 10,5010,150 的垂直线。

有关 PathGeometry 对象的详细信息,请参阅 Geometry 概述

在 XAML 中,还可以使用特殊的缩写语法来设置 PathGeometryFigures 属性。 有关详细信息,请参阅路径标记语法概述。

有关 XAML 示例中使用的路径语法的详细信息,请参阅路径标记语法概述。

另请参阅