You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 21:45:02