Animate a path like it's drawn on a canvas

杀马特。学长 韩版系。学妹 提交于 2020-07-15 05:47:34

问题


I'm a newbie in WPF and please, guide me in the right direction for this problem.

I have built a WPF application which contains all the functionality of that of a road map view control. I.e. the road map can be zoomed in/out, panned in all directions using mouse, keyboard and the controls provided. I have mapped the roads as paths drawn using Expression Blend.

Currently I am looking for a way to animate a selected road, as if it was drawn by a pencil/pen/marker. Is this possible? So far, I've been able to animate the opacity and color of the path. I've search a lot for this functionality with no luck. May be I do not search for the correct terms. I hope someone of you could shed some light on to this matter.

Thanks in advance. Am sorry, if I sound crazy :) Programming is my way of being crazy :D


回答1:


I am not quite sure if this is what you are looking for, but I'll give it a shot.

The animation would be a bit complex. It would actually be a series of animations, one for each point in your path minus the first point. You would want to add point to the animated path, one at a time, from the source path. Each time you add a point, that point starts at the previous point, and travels to the desired point. The animation would move the newly added point along over time, giving the effect of that segment being "drawn". When that animation completes, you iterate to your next point and begin the next animation.




回答2:


I don't won't it to be amidst of comments, here's a great post:

http://social.msdn.microsoft.com/Forums/en/wpf/thread/19a7bd4b-cf28-4b31-a329-a5f58b9ec374

and here's is Charles Petzold's take on the problem:

http://www.charlespetzold.com/blog/2006/08/150351.html




回答3:


TL;DR: We take advantage of the PointAnimationUsingPath. We animate a point along the path and build a Clip geometry as the point is moving.


Full answer:

I start by drawing a sample Path in a Grid for demonstration purposes. Put the actual Path data in resources because we will re-use it later.

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

Then I define an empty Clip geomtery for the Path:

<Path.Clip>
    <GeometryGroup x:Name="geometryGroup" FillRule="Nonzero"/>
</Path.Clip>

So far, the Path disappeared because it is clipped to an empty geometry. What we have left to do is progressively add points back in this clipping geometry to reveal the Path. For that, we need an object to animate. I suggest to create a FrameworkPoint for the demonstration:

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

This is an object with only one property of type Point, and this property is animatable. Let's add our (invisible) point in the Grid and animate it on our 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>

At start-up, the FrameworkPoint will invisibly follow the Path over the indicated time (10 seconds). All is left to do is build our Clip as the point moves:

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

This won't give perfect results for fast animations because the sampling won't be good enough but it could give you ideas!



来源:https://stackoverflow.com/questions/8816137/animate-a-path-like-its-drawn-on-a-canvas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!