Reputation: 3438
I am having an issue trying to get an ellipse to properly follow a path on my canvas. I supposed the problem stems from the fact that my mini syntax defines movement between x and y values but am targeting only one of those values in my target property (e.g. (Canvas.Top
or Canvas.Left
). I can not seem to find any attached "Position" property on the canvas that would take in a Position type which would work with my path. What would be the proper way to get this path to work?
<Canvas Name="WaitingCanvas">
<Ellipse Name="WaitingEllipse"
Canvas.Top="100"
Canvas.Left="50"
Height="20"
Width="20"
Fill="White">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimationUsingPath
Storyboard.TargetName="WaitingEllipse"
Storyboard.TargetProperty="(Canvas.Top)"
Source="X"
Duration="0:0:5">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M 50,100 C 100,50 150,100 200, 100"/>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
Upvotes: 3
Views: 627
Reputation: 128061
Instead of simultaneously animating Canvas.Left
and Canvas.Top
you may perhaps also animate the Matrix
property of a MatrixTransform
that is assigned to the RenderTransform
property of the Ellipse. The Matrix
would be animated by a MatrixAnimationUsingPath
.
<Ellipse Height="20" Width="20" Fill="White">
<Ellipse.RenderTransform>
<MatrixTransform x:Name="transform" Matrix="1,0,0,1,50,100"/>
</Ellipse.RenderTransform>
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<MatrixAnimationUsingPath
Storyboard.TargetName="transform"
Storyboard.TargetProperty="Matrix"
Duration="0:0:5">
<MatrixAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M 50,100 C 100,50 150,100 200,100"/>
</MatrixAnimationUsingPath.PathGeometry>
</MatrixAnimationUsingPath>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
Using a MatrixAnimationUsingPath
would even allow to rotate the animated element along the tangent of the animation path, by setting DoesRotateWithTangent="True"
. That would of course only be visible if the animated element wouldn't be a circle.
Upvotes: 4
Reputation: 102743
You can't animate both Canvas.Top
and Canvas.Left
at the same time, but you can use two separate animations. Make the PathGeometry
a resources so it can be shared:
<Canvas Name="WaitingCanvas">
<Canvas.Resources>
<PathGeometry x:Name="AnimationPath" Figures="M 50,100 C 100,50 150,100 200, 100"/>
</Canvas.Resources>
<Ellipse Name="WaitingEllipse"
Canvas.Top="100"
Canvas.Left="50"
Height="20"
Width="20"
Fill="White">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimationUsingPath
Storyboard.TargetName="WaitingEllipse"
Storyboard.TargetProperty="(Canvas.Left)"
PathGeometry="{StaticResource AnimationPath}"
Source="X"
Duration="0:0:5" />
<DoubleAnimationUsingPath
Storyboard.TargetName="WaitingEllipse"
Storyboard.TargetProperty="(Canvas.Top)"
PathGeometry="{StaticResource AnimationPath}"
Source="Y"
Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
Upvotes: 2