TL;DR:我们利用PointAnimationUsingPath
。我们为路径上的一个点设置动画并构建一个Clip
点移动时的几何形状。
完整答案:
我首先绘制一个样本Path
in a Grid
出于演示目的。把实际的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>
然后我定义一个空的Clip
几何为Path
:
<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
会无形中跟随Path
在指定的时间(10 秒)内。剩下要做的就是建立我们的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));
}
}
这不会为快速动画提供完美的结果,因为采样不够好,但它可以给您带来想法!