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));
}
}
这不会为快速动画提供完美的结果,因为采样不够好,但它可以给你一些想法!