Практическое руководство. Поворот объекта с использованием геометрического пути
В этом примере демонстрируется поворот (вращение) объекта вдоль геометрического пути, который определяется объектом PathGeometry.
Пример
В следующем примере используются три объекта DoubleAnimationUsingPath, которые двигают прямоугольник по геометрическому пути.
Первый DoubleAnimationUsingPath анимирует трансформацию RotateTransform, примененную к прямоугольнику. Анимация формирует значения угла. Это заставляет прямоугольник поворачиваться (вращаться) вдоль контуров пути.
Два других объекта анимируют значения X и Y трансформации TranslateTransform, примененной к прямоугольнику. Это заставляет прямоугольник двигаться горизонтально и вертикально вдоль пути.
<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">
<Page.Resources>
<!-- This is the geometry creates the animation path. Because
this example uses it multiple times, it's declared as a resource and
frozen to improve performance. -->
<PathGeometry x:Key="AnimationPath"
Figures="M 10,100 C 35,0 135,0 160,100 180,190 285,200 310,100"
PresentationOptions:Freeze="True" />
</Page.Resources>
<Canvas Width="400" Height="400">
<!-- The object to animate. -->
<Rectangle
Width="30" Height="30" Fill="Blue">
<Rectangle.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="AnimatedRotateTransform" />
<TranslateTransform x:Name="AnimatedTranslateTransform" />
</TransformGroup>
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Path.Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever" AutoReverse="True" >
<!-- Generates angle values (in degrees) from
the path. This animation is used to
rotate the rectangle. -->
<DoubleAnimationUsingPath
Storyboard.TargetName="AnimatedRotateTransform"
Storyboard.TargetProperty="Angle"
PathGeometry="{StaticResource AnimationPath}"
Source="Angle"
Duration="0:0:5" />
<!-- Generates horizontal offset values from
the path. This animation is used to
animate the rectangle horizontally. -->
<DoubleAnimationUsingPath
Storyboard.TargetName="AnimatedTranslateTransform"
Storyboard.TargetProperty="X"
PathGeometry="{StaticResource AnimationPath}"
Source="X"
Duration="0:0:5" />
<!-- Generates vertical offset values from
the path. This animation is used to move
the rectangle vertically. -->
<DoubleAnimationUsingPath
Storyboard.TargetName="AnimatedTranslateTransform"
Storyboard.TargetProperty="Y"
PathGeometry="{StaticResource AnimationPath}"
Source="Y"
Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</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
{
public class RotateAnimationUsingPathExample : Page
{
public RotateAnimationUsingPathExample()
{
// Create a NameScope for the page so that
// we can use Storyboards.
NameScope.SetNameScope(this, new NameScope());
// Create a rectangle.
Rectangle aRectangle = new Rectangle();
aRectangle.Width = 30;
aRectangle.Height = 30;
aRectangle.Fill = Brushes.Blue;
// Create some transforms. These transforms
// will be used to move and rotate the rectangle.
RotateTransform animatedRotateTransform =
new RotateTransform();
TranslateTransform animatedTranslateTransform =
new TranslateTransform();
// Register the transforms' names with the page
// so that they can be targeted by a Storyboard.
this.RegisterName("AnimatedRotateTransform", animatedRotateTransform);
this.RegisterName("AnimatedTranslateTransform", animatedTranslateTransform);
// Create a TransformGroup to contain the transforms
// and apply the TransformGroup to the rectangle.
TransformGroup tGroup = new TransformGroup();
tGroup.Children.Add(animatedRotateTransform);
tGroup.Children.Add(animatedTranslateTransform);
aRectangle.RenderTransform = tGroup;
// Create a Canvas to contain the rectangle
// and add it to the page.
Canvas mainPanel = new Canvas();
mainPanel.Width = 400;
mainPanel.Height = 400;
mainPanel.Children.Add(aRectangle);
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 DoubleAnimationUsingPath to rotate the
// rectangle with the path by animating
// its RotateTransform.
DoubleAnimationUsingPath angleAnimation =
new DoubleAnimationUsingPath();
angleAnimation.PathGeometry = animationPath;
angleAnimation.Duration = TimeSpan.FromSeconds(5);
// Set the Source property to Angle. This makes
// the animation generate angle values from
// the path information.
angleAnimation.Source = PathAnimationSource.Angle;
// Set the animation to target the Angle property
// of the RotateTransform named "AnimatedRotateTransform".
Storyboard.SetTargetName(angleAnimation, "AnimatedRotateTransform");
Storyboard.SetTargetProperty(angleAnimation,
new PropertyPath(RotateTransform.AngleProperty));
// Create a DoubleAnimationUsingPath to move the
// rectangle horizontally along the path by animating
// its TranslateTransform.
DoubleAnimationUsingPath translateXAnimation =
new DoubleAnimationUsingPath();
translateXAnimation.PathGeometry = animationPath;
translateXAnimation.Duration = TimeSpan.FromSeconds(5);
// Set the Source property to X. This makes
// the animation generate horizontal offset values from
// the path information.
translateXAnimation.Source = PathAnimationSource.X;
// Set the animation to target the X property
// of the TranslateTransform named "AnimatedTranslateTransform".
Storyboard.SetTargetName(translateXAnimation, "AnimatedTranslateTransform");
Storyboard.SetTargetProperty(translateXAnimation,
new PropertyPath(TranslateTransform.XProperty));
// Create a DoubleAnimationUsingPath to move the
// rectangle vertically along the path by animating
// its TranslateTransform.
DoubleAnimationUsingPath translateYAnimation =
new DoubleAnimationUsingPath();
translateYAnimation.PathGeometry = animationPath;
translateYAnimation.Duration = TimeSpan.FromSeconds(5);
// Set the Source property to Y. This makes
// the animation generate vertical offset values from
// the path information.
translateYAnimation.Source = PathAnimationSource.Y;
// Set the animation to target the Y property
// of the TranslateTransform named "AnimatedTranslateTransform".
Storyboard.SetTargetName(translateYAnimation, "AnimatedTranslateTransform");
Storyboard.SetTargetProperty(translateYAnimation,
new PropertyPath(TranslateTransform.YProperty));
// Create a Storyboard to contain and apply the animations.
Storyboard pathAnimationStoryboard = new Storyboard();
pathAnimationStoryboard.RepeatBehavior = RepeatBehavior.Forever;
pathAnimationStoryboard.AutoReverse = true;
pathAnimationStoryboard.Children.Add(angleAnimation);
pathAnimationStoryboard.Children.Add(translateXAnimation);
pathAnimationStoryboard.Children.Add(translateYAnimation);
// Start the animations when the rectangle is loaded.
aRectangle.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
Public Class RotateAnimationUsingPathExample
Inherits Page
Public Sub New()
' Create a NameScope for the page so that
' we can use Storyboards.
NameScope.SetNameScope(Me, New NameScope())
' Create a rectangle.
Dim aRectangle As New Rectangle()
aRectangle.Width = 30
aRectangle.Height = 30
aRectangle.Fill = Brushes.Blue
' Create some transforms. These transforms
' will be used to move and rotate the rectangle.
Dim animatedRotateTransform As New RotateTransform()
Dim animatedTranslateTransform As New TranslateTransform()
' Register the transforms' names with the page
' so that they can be targeted by a Storyboard.
Me.RegisterName("AnimatedRotateTransform", animatedRotateTransform)
Me.RegisterName("AnimatedTranslateTransform", animatedTranslateTransform)
' Create a TransformGroup to contain the transforms
' and apply the TransformGroup to the rectangle.
Dim tGroup As New TransformGroup()
tGroup.Children.Add(animatedRotateTransform)
tGroup.Children.Add(animatedTranslateTransform)
aRectangle.RenderTransform = tGroup
' Create a Canvas to contain the rectangle
' and add it to the page.
Dim mainPanel As New Canvas()
mainPanel.Width = 400
mainPanel.Height = 400
mainPanel.Children.Add(aRectangle)
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 DoubleAnimationUsingPath to rotate the
' rectangle with the path by animating
' its RotateTransform.
Dim angleAnimation As New DoubleAnimationUsingPath()
angleAnimation.PathGeometry = animationPath
angleAnimation.Duration = TimeSpan.FromSeconds(5)
' Set the Source property to Angle. This makes
' the animation generate angle values from
' the path information.
angleAnimation.Source = PathAnimationSource.Angle
' Set the animation to target the Angle property
' of the RotateTransform named "AnimatedRotateTransform".
Storyboard.SetTargetName(angleAnimation, "AnimatedRotateTransform")
Storyboard.SetTargetProperty(angleAnimation, New PropertyPath(RotateTransform.AngleProperty))
' Create a DoubleAnimationUsingPath to move the
' rectangle horizontally along the path by animating
' its TranslateTransform.
Dim translateXAnimation As New DoubleAnimationUsingPath()
translateXAnimation.PathGeometry = animationPath
translateXAnimation.Duration = TimeSpan.FromSeconds(5)
' Set the Source property to X. This makes
' the animation generate horizontal offset values from
' the path information.
translateXAnimation.Source = PathAnimationSource.X
' Set the animation to target the X property
' of the TranslateTransform named "AnimatedTranslateTransform".
Storyboard.SetTargetName(translateXAnimation, "AnimatedTranslateTransform")
Storyboard.SetTargetProperty(translateXAnimation, New PropertyPath(TranslateTransform.XProperty))
' Create a DoubleAnimationUsingPath to move the
' rectangle vertically along the path by animating
' its TranslateTransform.
Dim translateYAnimation As New DoubleAnimationUsingPath()
translateYAnimation.PathGeometry = animationPath
translateYAnimation.Duration = TimeSpan.FromSeconds(5)
' Set the Source property to Y. This makes
' the animation generate vertical offset values from
' the path information.
translateYAnimation.Source = PathAnimationSource.Y
' Set the animation to target the Y property
' of the TranslateTransform named "AnimatedTranslateTransform".
Storyboard.SetTargetName(translateYAnimation, "AnimatedTranslateTransform")
Storyboard.SetTargetProperty(translateYAnimation, New PropertyPath(TranslateTransform.YProperty))
' Create a Storyboard to contain and apply the animations.
Dim pathAnimationStoryboard As New Storyboard()
pathAnimationStoryboard.RepeatBehavior = RepeatBehavior.Forever
pathAnimationStoryboard.AutoReverse = True
pathAnimationStoryboard.Children.Add(angleAnimation)
pathAnimationStoryboard.Children.Add(translateXAnimation)
pathAnimationStoryboard.Children.Add(translateYAnimation)
' Start the animations when the rectangle is loaded.
AddHandler aRectangle.Loaded, Sub(sender As Object, e As RoutedEventArgs) pathAnimationStoryboard.Begin(Me)
End Sub
End Class
End Namespace
Другой способ повернуть объект, используя геометрический путь, - использовать объект MatrixAnimationUsingPath и задать его свойству DoesRotateWithTangent значение true
. Дополнительные сведения и пример см. в разделе Поворот объекта с помощью геометрического пути (матричная анимация).
Описание полного примера см. в разделе Пример анимации вдоль пути.
См. также
.NET Desktop feedback