Avalonia如何通过代码实现Path路径内点坐标的动画效果
Avalonia 路径点动画实现方案
Avalonia 动画系统没有提供WPF风格的BeginAnimation实例方法,也不支持直接对几何属性使用PathTransition实现点位移,你可以通过Avalonia内置的动画API实现同等效果,以下是两种可选实现方式:
方法1:异步扩展方法实现(更简洁)
首先引入依赖命名空间:
using Avalonia; using Avalonia.Animation; using Avalonia.Media; using System; using System.Collections.Generic; using System.Threading.Tasks;
实现代码:
public async void AnimatePoints(Point[] pts, TimeSpan timespan, bool randomized = true, Action onFinished = null) { var animTasks = new List<Task>(); // 处理PathFigure起始点动画 animTasks.Add(PathFigure.Animate( PathFigure.StartPointProperty, PathFigure.StartPoint, pts[0], timespan, easing: LinearEasing.Instance)); // 处理所有LineSegment的点动画 var random = new Random(); for (int i = 0; i < LineSegments.Count && i < pts.Length - 1; i++) { if (randomized) { // 随机延迟实现错落动画效果,不需要可删除 await Task.Delay(TimeSpan.FromMilliseconds(random.Next(0, 100))); } animTasks.Add(LineSegments[i].Animate( LineSegment.PointProperty, LineSegments[i].Point, pts[i + 1], timespan, easing: LinearEasing.Instance)); } // 所有动画完成后触发回调 await Task.WhenAll(animTasks); onFinished?.Invoke(); }
方法2:Animation实例实现(无异步依赖)
public void AnimatePoints(Point[] pts, TimeSpan timespan, bool randomized = true, Action onFinished = null) { int totalAnimCount = LineSegments.Count + 1; int completedCount = 0; var random = new Random(); void OnAnimCompleted(object sender, EventArgs e) { completedCount++; if (completedCount == totalAnimCount) { onFinished?.Invoke(); } } // 起始点动画 var startPointAnim = new Animation { Duration = timespan, Children = { new KeyFrame { Cue = new Cue(1d), Setters = { new Setter(PathFigure.StartPointProperty, pts[0]) } } } }; startPointAnim.Completed += OnAnimCompleted; startPointAnim.RunAsync(PathFigure); // 线段点动画 for (int i = 0; i < LineSegments.Count && i < pts.Length - 1; i++) { var segmentAnim = new Animation { Duration = timespan, Delay = randomized ? TimeSpan.FromMilliseconds(random.Next(0, 100)) : TimeSpan.Zero, Children = { new KeyFrame { Cue = new Cue(1d), Setters = { new Setter(LineSegment.PointProperty, pts[i+1]) } } } }; segmentAnim.Completed += OnAnimCompleted; segmentAnim.RunAsync(LineSegments[i]); } }
注意事项
- 传入的
pts数组长度需要等于线段数量+1:第一个点对应PathFigure的起始点,后续每个点对应一个LineSegment的Point属性 - 可自行替换缓动函数参数实现非线性动画效果,比如
CubicEaseInOut、QuadraticEaseOut等内置缓动 - 你原WPF代码中
randomized的两个分支逻辑完全一致,上面的实现补充了随机延迟的错落效果,不需要可以直接删除相关判断逻辑
内容的提问来源于stack exchange,提问作者Niels Bosma
相关产品推荐
相关产品推荐

