Información general sobre animaciones en trazados

En este tema se presentan las animaciones de trazado, que permiten usar un trazado geométrico para generar valores de salida. Las animaciones de trazado son útiles para mover y girar objetos a lo largo de trazados complejos.

Requisitos previos

Para comprender este tema, debería estar familiarizado con las características de las animaciones de WPF. Consulte Información general sobre animaciones para obtener una introducción a las características de las animaciones.

Puesto que usa un objeto PathGeometry para definir un trazado de animación, también debería estar familiarizado con PathGeometry y los diferentes tipos de objetos PathSegment. Para obtener más información, consulte Información general sobre geometría.

¿Qué es una animación de trazado?

Un trazado de animación es un tipo de AnimationTimeline que usa un PathGeometry como entrada. En lugar de establecer una propiedad From, To o By (como lo hace para una animación From/To/By) o de usar marcos clave (como usa para una animación de marcos clave), se debe definir un trazado geométrico y usarlo para establecer la propiedad PathGeometry de la animación de trazado. A medida que la animación de trazado avanza, lee la información de x, de y y del ángulo del trazado y usa esa información para generar la salida.

Las animaciones de trazado son muy útiles para animar un objeto a lo largo de un trazado complejo. Una manera de mover un objeto a lo largo de un trazado es usar un MatrixTransform y un MatrixAnimationUsingPath para transformar un objeto a lo largo de una ruta compleja. En el ejemplo siguiente se muestra esta técnica mediante el uso del objeto MatrixAnimationUsingPath para animar la propiedad Matrix de un MatrixTransform. Este MatrixTransform se aplica a un botón y hace que se mueva a lo largo de un trazado curvo. Como la propiedad DoesRotateWithTangent está establecida en true, el rectángulo rota a lo largo de la tangente del trazado.

<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

Para más información sobre la sintaxis de trazado que se usa en el ejemplo XAML, consulte la información general sobre sintaxis de marcado de trazados. Para ver el ejemplo completo, consulte el Ejemplo de animación de trazado.

Puede aplicar una animación de trazado a una propiedad mediante un Storyboard en XAML y en código, o mediante un BeginAnimation en el código. También puede usar una animación de trazado para crear unAnimationClock y aplicarlo a una o más propiedades. Para obtener más información sobre los distintos métodos de aplicación de animaciones, consulte Información general sobre técnicas de animación de propiedades.

Tipos de animación de trazado

Dado que las animaciones generan valores de propiedad, existen distintos tipos de animaciones para los diversos tipos de propiedades. Para animar una propiedad que toma un Double (como la propiedad X de un TranslateTransform), use una animación que produzca valores Double. Para animar una propiedad que toma un elemento Point, se usa una animación que produzca valores Point, y así sucesivamente.

Las clases de animación de trazados pertenecen al espacio de nombres System.Windows.Media.Animation y cumplen con la siguiente convención de nomenclatura:

<Tipo>AnimationUsingPath

Donde <Tipo> es el tipo de valor que la clase anima.

WPF proporciona las siguientes clases de animación de trazado.

Tipo de propiedad Clase de animación de trazado correspondiente Ejemplo
Double DoubleAnimationUsingPath Animación de un objeto a lo largo de un trazado (animación doble)
Matrix MatrixAnimationUsingPath Animación de un objeto a lo largo de un trazado (animación de matriz)
Point PointAnimationUsingPath Animación de un objeto a lo largo de un trazado (animación en punto)

Un MatrixAnimationUsingPath genera valores Matrix a partir de su PathGeometry. Cuando MatrixAnimationUsingPath se usa con un MatrixTransform, puede mover un objeto a lo largo de un trazado. Si establece la propiedad DoesRotateWithTangent del MatrixAnimationUsingPath en true, también gira el objeto a lo largo de las curvas del trazado.

Un PointAnimationUsingPath genera valores Point a partir de las coordenadas x e y de su PathGeometry. Al usar un PointAnimationUsingPath para animar una propiedad que toma valores Point, puede mover un objeto a lo largo de un trazado. Un PointAnimationUsingPath no puede girar objetos.

Un DoubleAnimationUsingPath genera valores Double a partir de su PathGeometry. Al establecer la propiedad Source, puede especificar si el DoubleAnimationUsingPath usa como salida la coordenada x, la coordenada y o un ángulo del trazado. Se puede usar un DoubleAnimationUsingPath para girar un objeto o moverlo a lo largo del eje x o del eje y.

Entrada de animación de trazado

Cada clase de animación de trazado proporciona una propiedad PathGeometry para especificar su entrada. La animación de trazado usa PathGeometry para generar los valores de salida. La clase PathGeometry permite describir varias figuras complejas que se componen de arcos, curvas y líneas.

En el corazón de un elemento PathGeometry hay una colección de objetos PathFigure, denominados así porque cada figura describe una forma discreta en PathGeometry. Cada PathFigure está compuesto de uno o más objetos PathSegment, cada uno de los cuales describe un segmento de la figura.

Hay muchos tipos de segmentos.

Tipo de segmento Descripción
ArcSegment Crea un arco elíptico entre dos puntos.
BezierSegment Crea una curva Bézier cúbica entre dos puntos.
LineSegment Crea una línea entre dos puntos.
PolyBezierSegment Crea una serie de curvas Bézier cúbicas.
PolyLineSegment Crea una serie de líneas.
PolyQuadraticBezierSegment Crea una serie de curvas Bézier cuadráticas.
QuadraticBezierSegment Crea una curva Bézier cuadrática.

Los segmentos en un PathFigure se combinan en una sola forma geométrica que usa el punto final de un segmento como el punto inicial del segmento siguiente. La propiedad StartPoint de un objeto PathFigure especifica el punto desde el que se dibuja el primer segmento. Cada segmento posterior comienza en el punto final del segmento anterior. Por ejemplo, se puede definir una línea vertical de 10,50 a 10,150 estableciendo la propiedad StartPoint en 10,50 y creando un LineSegment con un valor de propiedad Point de 10,150.

Para obtener más información sobre los objetos PathGeometry, consulte Información general sobre geometría.

En XAML también se puede usar una sintaxis abreviada especial para establecer la propiedad Figures de un PathGeometry. Para obtener más información, consulte la información general sobre sintaxis de marcado de trazados.

Para más información sobre la sintaxis de trazado que se usa en el ejemplo XAML, consulte la información general sobre sintaxis de marcado de trazados.

Vea también