How to make an ellipse follow a curve on a canvas

你说的曾经没有我的故事 提交于 2020-03-15 05:47:32

问题


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>

回答1:


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>



回答2:


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.



来源:https://stackoverflow.com/questions/17842433/how-to-make-an-ellipse-follow-a-curve-on-a-canvas

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!