WPF 动画 - 贝塞尔曲线点动画
我正在开发一个项目,涉及在两个对象之间绘制弯曲路径。 目前,我一直在编写一些测试代码来使用贝塞尔曲线和动画。 第一个测试只是将端点 (Point3) 从原始对象(一个矩形)沿直线移动到目标对象(另一个矩形)。 这是设置实际线的代码:
connector = new Path();
connector.Stroke = Brushes.Red;
connector.StrokeThickness = 3;
PathGeometry connectorGeometry = new PathGeometry();
PathFigure connectorPoints = new PathFigure();
connectorCurve = new BezierSegment();
connectorPoints.StartPoint = new Point((double)_rect1.GetValue(Canvas.LeftProperty) + _rect1.Width / 2,
(double)_rect1.GetValue(Canvas.TopProperty) + _rect1.Height / 2);
connectorCurve.Point1 = connectorPoints.StartPoint;
connectorCurve.Point2 = connectorPoints.StartPoint;
connectorCurve.Point3 = connectorPoints.StartPoint;
connectorPoints.Segments.Add(connectorCurve);
connectorGeometry.Figures.Add(connectorPoints);
connector.Data = connectorGeometry;
MainCanvas.Children.Add(connector);
好的,现在我们有一条线折叠成一个点。 现在,让我们为该线设置动画,从 _rect1 到 _rect2(端点处的两个对象):
PointAnimation pointAnim = new PointAnimation();
pointAnim.From = connectorCurve.Point3;
pointAnim.To = new Point((double)_rect2.GetValue(Canvas.LeftProperty) + _rect2.Width / 2,
(double)_rect2.GetValue(Canvas.TopProperty) + _rect2.Height / 2);
pointAnim.Duration = new Duration(TimeSpan.FromSeconds(5));
board.Children.Add(pointAnim);
效果非常好。 然而,当我尝试用故事板来做这件事时,我什么也没得到。 这是故事板代码:
Storyboard board = new Storyboard();
PointAnimation pointAnim = new PointAnimation();
pointAnim.From = connectorCurve.Point3;
pointAnim.To = new Point((double)_rect2.GetValue(Canvas.LeftProperty) + _rect2.Width / 2,
(double)_rect2.GetValue(Canvas.TopProperty) + _rect2.Height / 2);
pointAnim.Duration = new Duration(TimeSpan.FromSeconds(5));
Storyboard.SetTarget(pointAnim, connectorCurve);
Storyboard.SetTargetProperty(pointAnim, new PropertyPath(BezierSegment.Point3Property));
board.Children.Add(pointAnim);
board.Begin();
没有任何动作。 我怀疑我所提供的 SetTarget 或 SetTargetProperty 存在问题,但似乎无法弄清楚。 有人有在 WPF 中制作线条/贝塞尔点动画的经验吗?
I'm working on a project that involves drawing curved paths between two objects. Currently, I've been writing some test code to play around with bezier curves and animation. The first test is simply to move the endpoint (Point3) from the origin object (a rectangle) to the destination object (another rectangle), in a straight line. here is the code which sets up the actual line:
connector = new Path();
connector.Stroke = Brushes.Red;
connector.StrokeThickness = 3;
PathGeometry connectorGeometry = new PathGeometry();
PathFigure connectorPoints = new PathFigure();
connectorCurve = new BezierSegment();
connectorPoints.StartPoint = new Point((double)_rect1.GetValue(Canvas.LeftProperty) + _rect1.Width / 2,
(double)_rect1.GetValue(Canvas.TopProperty) + _rect1.Height / 2);
connectorCurve.Point1 = connectorPoints.StartPoint;
connectorCurve.Point2 = connectorPoints.StartPoint;
connectorCurve.Point3 = connectorPoints.StartPoint;
connectorPoints.Segments.Add(connectorCurve);
connectorGeometry.Figures.Add(connectorPoints);
connector.Data = connectorGeometry;
MainCanvas.Children.Add(connector);
OK, so we now have a line collapsed to a point. Now, lets animate that line, going from _rect1 to _rect2 (the two objects at the endpoints):
PointAnimation pointAnim = new PointAnimation();
pointAnim.From = connectorCurve.Point3;
pointAnim.To = new Point((double)_rect2.GetValue(Canvas.LeftProperty) + _rect2.Width / 2,
(double)_rect2.GetValue(Canvas.TopProperty) + _rect2.Height / 2);
pointAnim.Duration = new Duration(TimeSpan.FromSeconds(5));
board.Children.Add(pointAnim);
Works beautifully. However, when I try to do it with a storyboard, I get nothing. Here's the storyboarded code:
Storyboard board = new Storyboard();
PointAnimation pointAnim = new PointAnimation();
pointAnim.From = connectorCurve.Point3;
pointAnim.To = new Point((double)_rect2.GetValue(Canvas.LeftProperty) + _rect2.Width / 2,
(double)_rect2.GetValue(Canvas.TopProperty) + _rect2.Height / 2);
pointAnim.Duration = new Duration(TimeSpan.FromSeconds(5));
Storyboard.SetTarget(pointAnim, connectorCurve);
Storyboard.SetTargetProperty(pointAnim, new PropertyPath(BezierSegment.Point3Property));
board.Children.Add(pointAnim);
board.Begin();
Nothing moves. I'm suspecting there is a problem with what I'm feeding SetTarget or SetTargetProperty, but can't seem to figure it out. Does anyone have experience with animating line / bezier points in WPF?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我重新创建了您的代码,这有效:
修复了它:) 看来目标需要是控件本身。
向下一步,如下所示:
...给出 InvalidOperationException:
I recreated your code, and this works:
That fixes it :) It seems that the target needs to be the control itself.
Going one step down, like this:
...gives the InvalidOperationException:
http://msdn .microsoft.com/en-us/library/system.windows.media.animation.storyboard(VS.95).aspx 说:
..如果你这样做的话!
该页面上的示例还设置 Storyboard 对象的 Duration 属性。
最后是一个一般性提示,一旦您掌握了这些类型的 UI 对象和奇怪的 XAML 对象图的基础知识,最好将其放入 ResourceDictionary 中,并使用“Resources["Name"] as Storyboard”之类的内容稍后将其取回。
希望这有帮助:看起来缺少的 Duration 应该可以解决问题。
编辑:看起来持续时间默认设置为自动,我会看看我还能想出什么,请耐心等待..:)
http://msdn.microsoft.com/en-us/library/system.windows.media.animation.storyboard(VS.95).aspx says:
..in case you were doing that!
The sample on that page also sets the Duration property of the Storyboard object.
Finally a general tip, with these kinds of UI objects and weird XAML object graphs once you've got the basics working best to put it in a ResourceDictionary and use something like 'Resources["Name"] as Storyboard' to get it back later.
Hope that's helpful: looks like the missing Duration should do the trick.
edit: Looks like Duration is set to Automatic by default, I will see what else I can come up with, please bear with me.. :)