我是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