【问题标题】:Can I animate the X- and Y- coordinates of a WPF Bezier curve control point separately?我可以分别为 WPF Bezier 曲线控制点的 X 坐标和 Y 坐标设置动画吗?
【发布时间】:2015-03-15 11:44:21
【问题描述】:

我正在尝试在 WPF 中创建一个动画贝塞尔曲线,我打算通过平滑缓慢地为端点和控制点设置动画来使其“栩栩如生”。我不希望任何点遵循明显可预测的路径,例如简单的椭圆或圆形。

通过使用两个不同的 DoubleAnimations,我在其他更简单的动画中取得了成功,例如分别为 Canvas.Top 和 Canvas.Left 制作动画。

但在 Bezier 段中,控制点和端点作为 Point() 实例给出,我似乎无法弄清楚如何分别为这些 Point 实例的 X 和 Y 坐标设置动画。虽然(例如)BezierSegment.ControlPoint2 有一个 PropertyPath,但该点的 X 坐标似乎没有。

我已经研究过通过从 PointAnimationBase 继承来实现我自己的自定义点动画,但是很难浏览文档以了解它们是如何联系在一起的 - 并且没有太多示例。

从 PointAnimationBase 继承的自定义动画是正确的方法吗?如何将其绑定到 BezierSegment 的控制点?还是我应该看一些完全不同的东西来达到效果?

【问题讨论】:

    标签: c# wpf animation


    【解决方案1】:

    自定义 PointAnimation 似乎是一种明智的方法。

    以下 XAML 显示了标准 PointAnimation 如何为 QuadraticBezierSegment 的 Point1 属性设置动画:

    <Path Stroke="Black" StrokeThickness="3">
        <Path.Data>
            <PathGeometry>
                <PathGeometry.Figures>
                    <PathFigure StartPoint="100,200">
                        <PathFigure.Segments>
                            <QuadraticBezierSegment Point2="200,200"/>
                        </PathFigure.Segments>
                    </PathFigure>
                </PathGeometry.Figures>
            </PathGeometry>
        </Path.Data>
        <Path.Triggers>
            <EventTrigger RoutedEvent="Loaded">
                <BeginStoryboard>
                    <Storyboard>
                        <PointAnimation
                            Storyboard.TargetProperty="Data.Figures[0].Segments[0].Point1"
                            From="150,200" To="150,0" Duration="0:0:1"/>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Path.Triggers>
    </Path>
    

    自定义 PointAnimation 需要您实现 GetCurrentValueCore 方法并返回一个 Point 实例,该实例表示动画的当前值,具体取决于 animationClock 参数提供的当前时间:

    public class MyPointAnimation : PointAnimationBase
    {
        protected override Point GetCurrentValueCore(
            Point defaultOriginValue, Point defaultDestinationValue,
            AnimationClock animationClock)
        {
            double x = ... // as function of animationClock
            double y = ... // as function of animationClock
            return new Point(x, y);
        }
    
        protected override Freezable CreateInstanceCore()
        {
            return new MyPointAnimation();
        }
    }
    

    【讨论】:

    • 感谢一百万!它工作得很好。当我冒险进入未知领域时,我发现 WPF 有点令人生畏(但同时,一旦我理解了它就很棒:-)。您的回答准确地显示了我需要的详细信息,并让我们能够理解从哪里开始以及它是如何联系起来的。
    猜你喜欢
    • 2022-01-21
    • 1970-01-01
    • 2014-11-14
    • 2022-09-23
    • 2011-11-13
    • 1970-01-01
    • 2015-09-28
    • 2021-06-28
    • 1970-01-01
    相关资源
    最近更新 更多