FollowExample.axaml代码
<UserControl xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="AvaloniaUI.FollowExample"> <Canvas x:Name="containerCanvas" Background="transparent" PointerMoved="OnPointerMoved"> <Rectangle x:Name="followRectangle" Canvas.Left="0" Canvas.Top="0" Fill="red" Width="50" Height="50" /> </Canvas> </UserControl>
FollowExample.axaml.cs代码
using Avalonia; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Markup.Xaml; using Shares.Avalonia; using System; namespace AvaloniaUI; public partial class FollowExample : UserControl { private readonly AnimationPlayer animation = new AnimationPlayer(); private Point lastMousePosition = new Point(300, 200); private Vector rectangleVelocity = new Vector(0, 0); public FollowExample() { InitializeComponent(); // 初始位置 Canvas.SetLeft(followRectangle, lastMousePosition.X); Canvas.SetTop(followRectangle, lastMousePosition.Y); // 配置 AnimationPlayer animation.Duration = double.MaxValue; // 无限播放 animation.Loop = true; animation.Fps = 60; // 每帧执行“跟随逻辑” animation.At(0).PlayGlobal(UpdateRectangle); animation.Start(); } private void OnPointerMoved(object? sender, PointerEventArgs e) { lastMousePosition = e.GetPosition(containerCanvas); } private void UpdateRectangle(double globalProgress) { // 当前矩形位置 var location = new Point( Canvas.GetLeft(followRectangle), Canvas.GetTop(followRectangle)); // 指向鼠标的向量 Vector toMouse = lastMousePosition - location; // 施加“跟随力” double followForce = 0.01; rectangleVelocity += toMouse * followForce; // 阻尼系数(防止发散) double drag = 0.8; rectangleVelocity *= drag; // 更新位置 location += rectangleVelocity; Canvas.SetLeft(followRectangle, location.X); Canvas.SetTop(followRectangle, location.Y); } }
运行效果