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));
}
}
这样做可能不能完美地处理快速动画,因为采样不够精细,但它可以给你提供一些创意!