路径动画概述
本主题介绍了路径动画,使你能够使用几何路径来生成输出值。 路径动画可用于沿着复杂路径移动和旋转对象。
先决条件
若要了解本主题,应熟悉 WPF 动画功能。 有关动画功能的简介,请参阅动画概述。
由于你使用 PathGeometry 对象来定义一个路径动画,因此还应熟悉 PathGeometry 和不同类型的 PathSegment 对象。 有关详细信息,请参阅几何概述。
什么是路径动画?
路径动画是一种使用 PathGeometry 作为输入的 AnimationTimeline。 可以定义一个几何路径并使用它来设置路径动画的 PathGeometry
属性,而不是设置 From、To 或 By 属性(如对 From/To/By 动画所执行的操作)或使用关键帧(如用于关键帧动画)。 路径动画运行时,会从路径中读取 x、y 和角度信息并使用该信息生成其输出。
路径动画对沿着复杂路径的对象进行动画处理非常有用。 沿着路径移动对象的一种方法是使用 MatrixTransform 和 MatrixAnimationUsingPath 来沿着复杂路径转换对象。 下面的示例通过使用 MatrixAnimationUsingPath 对象对 MatrixTransform 的 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 的属性(例如 TranslateTransform 的 X 属性)进行动画处理,可以使用生成 Double 值的动画。 要为采用 Point 的属性进行动画处理,请使用生成 Point 值的动画,依此类推。
路径动画类属于 System.Windows.Media.Animation 命名空间,并使用以下命名约定:
<Type> AnimationUsingPath
其中 <Type> 为该类进行动画处理的值的类型。
WPF 提供以下路径动画类。
属性类型 | 相应的路径动画类 | 示例 |
---|---|---|
Double | DoubleAnimationUsingPath | 沿着路径针对对象进行动画处理(双重动画) |
Matrix | MatrixAnimationUsingPath | 沿着路径针对对象进行动画处理(矩阵动画) |
Point | PointAnimationUsingPath | 沿着路径针对对象进行动画处理(点动画) |
MatrixAnimationUsingPath 从其 PathGeometry 生成 Matrix 值。 与 MatrixTransform 一起使用时,MatrixAnimationUsingPath 可以沿路径移动对象。 如果将 MatrixAnimationUsingPath 的 DoesRotateWithTangent 属性设置为 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 中的多个线段组合成一个几何形状,它使用线段的终点作为下一段的起点。 PathFigure 的 StartPoint 属性指定绘制第一个线段的起点。 每个后续段都从上一段的终点开始。 例如,通过将 StartPoint 属性设置为 10,50
并创建一个 Point 属性设置为 10,150
的 LineSegment,可以定义从 10,50
到 10,150
的垂直线。
有关 PathGeometry 对象的详细信息,请参阅 Geometry 概述。
在 XAML 中,还可以使用特殊的缩写语法来设置 PathGeometry 的 Figures 属性。 有关详细信息,请参阅路径标记语法概述。
有关 XAML 示例中使用的路径语法的详细信息,请参阅路径标记语法概述。