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