像在画布上绘制路径一样为路径设置动画效果



我是WPF的新手,请指导我解决这个问题。

我已经构建了一个WPF应用程序,它包含了路线图视图控件的所有功能。也就是说,路线图可以放大/缩小,使用鼠标、键盘和提供的控件向各个方向平移。我已将道路映射为使用"表达式混合"绘制的路径。

目前,我正在寻找一种方法来设置选定道路的动画,就好像它是用铅笔/笔/记号笔绘制的一样。这可能吗?到目前为止,我已经能够设置路径的不透明度和颜色的动画。我已经为这个功能搜索了很多,但没有运气。可能是我没有搜索正确的术语。我希望你们中的某个人能对此事有所了解。

提前谢谢。对不起,如果我听起来很疯狂:)编程是我疯狂的方式:D

TL;DR:我们利用PointAnimationUsingPath。我们沿着路径设置一个点的动画,并在点移动时构建Clip几何体


完整答案:

我首先在Grid中绘制一个示例Path,用于演示目的。将实际的Path数据放入资源中,因为我们稍后会重用它。

<Grid>
    <Grid.Resources>
        <PathGeometry x:Key="path">
            <PathFigure>
                <BezierSegment Point1="10 30" Point2="100 100" Point3="200 10" />
            </PathFigure>
        </PathGeometry>
    </Grid.Resources>
    <Path x:Name="myPath" StrokeThickness="5" Stroke="Black" Data="{StaticResource path}" />
</Grid>

然后,我为Path:定义了一个空的Clip地理空间

<Path.Clip>
    <GeometryGroup x:Name="geometryGroup" FillRule="Nonzero"/>
</Path.Clip>

到目前为止,Path消失了,因为它被剪裁为一个空的几何体。我们要做的是在这个剪裁几何体中逐步添加点,以显示Path。为此,我们需要一个对象来设置动画。我建议为演示创建一个FrameworkPoint

public class FrameworkPoint : FrameworkElement {
    public static DependencyProperty CenterProperty = DependencyProperty.RegisterAttached("Center", typeof(Point), typeof(FrameworkPoint));
    public Point Center { get => (Point)GetValue(CenterProperty); set => SetValue(CenterProperty, value); }
    public event Action<Point> CoordinatesChanged;
    protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) {
        base.OnPropertyChanged(e);
        if (e.Property == CenterProperty) {
            CoordinatesChanged?.Invoke(Center);
        }
    }
}

这是一个只有一个Point类型属性的对象,并且该属性是可设置动画的。让我们在Grid中添加我们的(不可见)点,并在Path:上对其进行动画处理

<local:FrameworkPoint x:Name="myPoint">
    <local:FrameworkPoint.Triggers>
        <EventTrigger RoutedEvent="Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <PointAnimationUsingPath Duration="00:00:10"
                                             Storyboard.TargetProperty="Center"
                                             PathGeometry="{StaticResource path}"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </local:FrameworkPoint.Triggers>
</local:FrameworkPoint>

在启动时,FrameworkPoint将在所指示的时间(10秒)内不可见地跟随Path。剩下要做的就是随着时间的推移构建我们的Clip

public partial class MainWindow : Window {
    public MainWindow() {
        InitializeComponent();
        myPoint.CoordinatesChanged += MyPoint_CoordinatesChanged;
    }
    private void MyPoint_CoordinatesChanged(Point obj) {
        geometryGroup.Children.Add(new EllipseGeometry(obj, 5, 5));
    }
}

这不会为快速动画提供完美的结果,因为采样不够好,但它可以给你一些想法!

我不太确定这是否是你想要的,但我会试一试。

动画会有点复杂。它实际上是一系列动画,路径中的每个点减去第一个点都有一个动画。您可能希望从源路径一次一个地向动画路径添加点。每次添加点时,该点都从上一个点开始,然后移动到所需的点。动画会随着时间的推移移动新添加的点,从而产生"绘制"线段的效果。该动画完成后,将迭代到下一个点并开始下一个动画。

我不想被评论淹没,这里有一个很棒的帖子:

http://social.msdn.microsoft.com/Forums/en/wpf/thread/19a7bd4b-cf28-4b31-a329-a5f58b9ec374

以下是Charles Petzold对这个问题的看法:

http://www.charlespetzold.com/blog/2006/08/150351.html

相关内容

最新更新