像在画布上绘制一样动态绘制路径

5

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

我已经构建了一个包含所有道路地图视图控件功能的WPF应用程序。即,可以使用鼠标、键盘和提供的控件在所有方向上放大/缩小、平移道路地图。我已经使用Expression Blend将道路映射为路径。

目前,我正在寻找一种方法来动画显示所选的道路,就像被铅笔/钢笔/标记笔绘制一样。这可能吗?到目前为止,我已经能够动画显示路径的不透明度和颜色。我已经搜索了很多关于此功能的资料,但没有找到合适的结果。也许我没有用正确的术语进行搜索。希望你们中的某个人能够为我解决这个问题。

提前感谢。如果我听起来有点疯狂,很抱歉:)编程是我发疯的方式:D


我不太明白,你是否已经能够动画化透明度和颜色?如果是的话,那么对于你来说也应该很容易动画化例如StrokeThickness。 - Clemens
我已经为不透明度和颜色添加了动画效果。动画化StrokeThickness也不是问题,尽管这不是我需要的。想象一下有两个点连接在一个复杂的线路上(曲线+直线)。现在想象一下这条路径是看不见的,你正在用铅笔画这条路径。我想要实现这种效果。我帮助你理解了吗? - Hawkz
我已经有路径数据了。我不是在绘制路径,只是指定路径数据将仅呈现它而没有动画效果。我想要在呈现时逐点地对这条路径进行动画处理,以便用户可以看到它在给定的时间内从A点到B点被绘制出来。我无法再简单地解释了 :( - Hawkz
@both: 我明白了 :) 但我没有解决方案。只是在 Blend 中测试了一些东西,但似乎它没有这个功能。 但这里有一个类似的问题,也许可以帮到你们:https://dev59.com/LUrSa4cB1Zd3GeqPY75a - SvenG
@Hawkz 你能否更新一下你的问题,提供一些你想要沿着动画路径的示例?请不要考虑你的WPF经验,因为这是一种逻辑挑战而不是技术挑战 :) - user572559
显示剩余2条评论
3个回答

3

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));
    }
}

这样做可能不能完美地处理快速动画,因为采样不够精细,但它可以给你提供一些创意!

1

我不太确定这是否是你要找的,但我会试着解释一下。

动画可能会比较复杂。事实上,它将是一系列动画,每个路径点都有一个动画,除了第一个点。您需要从源路径逐个添加点到动画路径中。 每次添加点时,该点从前一个点开始,并移动到所需点。动画将在时间内移动新添加的点,给人视觉效果就像该线段被“绘制”出来一样。当该动画完成时,您迭代到下一个点并开始下一个动画。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接