Общие сведения об анимации с использованием пути

В этом разделе представлены общие сведения об анимациях по контуру, которые позволяют использовать геометрические контуры для формирования выходных значений. Анимации по контуру можно использовать для перемещения или вращения объектов по сложным траекториям.

Необходимые компоненты

Для понимания этого раздела нужно иметь представление о средствах анимации WPF. Общие сведения о возможностях анимации см. в разделе Общие сведения об анимации.

Так как для определения анимации пути используется PathGeometry объект, вы также должны ознакомиться с PathGeometry различными PathSegment типами объектов. Более подробную информацию см. в разделе Общие сведения о классе Geometry.

Что такое анимация по контуру?

Анимация пути — это тип AnimationTimeline , который использует его входные PathGeometry данные. Вместо задания свойства From, To или By (как и для анимации from/To/By) или использования ключевых кадров (как используется для анимации ключевых кадров), вы определяете геометрический путь и используете его для задания PathGeometry свойства анимации пути. При выполнении анимации по контуру текущие данные о координатах X, Y и угле наклона используются для расчета выходных данных.

Метод анимации по контуру очень удобен при выполнении анимации объекта по сложной траектории. Одним из способов перемещения объекта вдоль пути является использование MatrixTransform и MatrixAnimationUsingPath преобразование объекта вдоль сложного пути. В следующем примере демонстрируется этот метод с помощью MatrixAnimationUsingPath объекта для анимации Matrix свойства объекта MatrixTransform. 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, см. в обзоре синтаксиса разметки пути. Описание полного примера см. в разделе Пример анимации вдоль пути.

Анимацию пути можно применить к свойству с помощью Storyboard XAML и кода или с помощью метода в коде BeginAnimation . Вы также можете использовать анимацию пути для создания AnimationClock и применения его к одному или нескольким свойствам. Дополнительные сведения о различных способах применения анимации см. в разделе Общие сведения о методах анимации свойств.

Типы анимаций по контуру

Так как при анимации создаются значения свойств, существуют различные типы анимаций для различных типов свойств. Чтобы анимировать свойство, которое принимает ( Double например X , свойство a TranslateTransform), используйте анимацию, которая создает Double значения. Для анимации свойства, принимающего Point, используйте анимацию, создающую значения Point и так далее.

Классы анимации пути относятся к System.Windows.Media.Animation пространству имен и используют следующее соглашение об именовании:

<Тип>AnimationUsingPath

Где <Type> — тип значения, которое анимируется классом.

WPF предоставляет следующие классы анимации пути.

Тип свойства Соответствующий класс анимации по контуру Пример
Double DoubleAnimationUsingPath Анимация объекта вдоль контура (двойная анимация)
Matrix MatrixAnimationUsingPath Анимация объекта вдоль контура (матричная анимация)
Point PointAnimationUsingPath Анимация объекта вдоль контура (точечная анимация)

Объект MatrixAnimationUsingPath создает Matrix значения из нее PathGeometry. При использовании с MatrixTransformMatrixAnimationUsingPath объектом может перемещать объект по пути. Если задано DoesRotateWithTangent свойство MatrixAnimationUsingPathtrueобъекта, он также поворачивает объект вдоль кривых пути.

A PointAnimationUsingPath создает Point значения из координат x-и y его PathGeometry. С помощью PointAnimationUsingPath анимации свойства, принимающего Point значения, можно переместить объект по пути. Не PointAnimationUsingPath удается повернуть объекты.

Объект DoubleAnimationUsingPath создает Double значения из нее PathGeometry. Задав Source свойство, можно указать, используется ли DoubleAnimationUsingPath координата x, координата y или угол пути в качестве выходных данных. Можно использовать DoubleAnimationUsingPath для поворота объекта или перемещения по оси X или оси Y.

Входные данные для анимации по контуру

Каждый класс анимации пути предоставляет PathGeometry свойство для указания входных данных. Анимация пути используется PathGeometry для создания выходных значений. Класс PathGeometry позволяет описать несколько сложных фигур, состоящих из дуг, кривых и линий.

В основе PathGeometry является коллекция PathFigure объектов; эти объекты так называются, так как каждая фигура описывает дискретную фигуру в PathGeometry. Каждая PathFigure из них состоит из одного или нескольких PathSegment объектов, каждый из которых описывает сегмент рисунка.

Существует несколько типов сегментов.

Тип сегмента Description
ArcSegment Создает эллиптическую дугу между двумя точками.
BezierSegment Создает кривую Безье третьего порядка между двумя точками.
LineSegment Создает линию между двумя точками.
PolyBezierSegment Создает набор кривых Безье третьего порядка.
PolyLineSegment Создает набор линий.
PolyQuadraticBezierSegment Создает набор кривых Безье второго порядка.
QuadraticBezierSegment Создает кривую Безье второго порядка.

Сегменты в a PathFigure объединяются в одну геометрическую фигуру, которая использует конечную точку сегмента в качестве начальной точки следующего сегмента. Свойство StartPointPathFigure указывает точку, из которой нарисован первый сегмент. Каждый последующий сегмент начинается в конечной точке предыдущего сегмента. Например, вертикальную линию из 10,50 в 10,150 можно определить, задав для свойства StartPoint значение 10,50 и создав LineSegment со свойством Point, которому задано значение 10,150.

Дополнительные сведения об объектах PathGeometry см. в разделе Общие сведения о классе Geometry.

В XAML можно также использовать специальный сокращенный синтаксис для задания Figures свойства объекта PathGeometry. Дополнительные сведения см. в обзоре синтаксис разметки пути.

Дополнительные сведения о синтаксисе пути, используемом в примере XAML, см. в обзоре синтаксиса разметки пути.

См. также