路径动画概述

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

先决条件

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

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

什么是路径动画?

路径动画是一种使用PathGeometry作为输入的AnimationTimeline。 无需设置 From、To 或 By 属性(正如对 From/To/By 动画所做的那样)或使用关键帧(用于关键帧动画),而是定义几何路径,并使用它设置 PathGeometry 路径动画的属性。 随着路径动画的进行,它会从路径中读取 x、y 和角度信息,并使用该信息生成其输出。

路径动画对于沿复杂路径对对象进行动画处理非常有用。 沿路径移动对象的一种方法是使用 MatrixTransformMatrixAnimationUsingPath 转换复杂路径上的对象。 下面的示例通过使用MatrixAnimationUsingPath对象对Matrix属性进行动画处理,以演示此技术。 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 命名空间,并使用以下命名约定:

<类型>AnimationUsingPath

其中 <Type> 是类动画的值的类型。

WPF 提供以下路径动画类。

属性类型 相应的路径动画类 示例:
Double DoubleAnimationUsingPath 在路径上创建对象动画(双动画)
Matrix MatrixAnimationUsingPath 在路径上对对象进行动画处理(矩阵动画)
Point PointAnimationUsingPath 对路径上的对象进行动画处理(点动画)

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

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

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

路径动画输入

每个路径动画类都提供一个PathGeometry属性,用于指定其输入。 路径动画使用 PathGeometry 生成其输出值。 通过 PathGeometry 类,可以描述由弧线、曲线和线条组成的多个复杂图形。

PathGeometry的核心是一个PathFigure对象的集合;之所以这样命名是因为每个图形在PathGeometry中描述了一个独立的形状。 每个 PathFigure 对象都包含一个或多个 PathSegment 对象,其中每个对象描述图形的一段。

有许多类型的片段。

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

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

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

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

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

另请参阅