wpf 鼠标动画

xaml

<Grid x:Name="RootGrid" Background="#000123" />

cs

  private readonly DispatcherTimer time = new();

    // 创建动画 
    private Storyboard CreateStoryBoard(Shape shape)
    {
        var duration = TimeSpan.FromMilliseconds(Random.Shared.Next(500, 2000));

        var widthAnimation = new DoubleAnimation
        {
            From = 0,
            To = Random.Shared.Next(40, 60),
            Duration = duration,
        };

        Storyboard.SetTarget(widthAnimation, shape);
        Storyboard.SetTargetProperty(widthAnimation, new PropertyPath(WidthProperty));

        var opacityAnimation = new DoubleAnimation
        {
            From = 1,
            To = 0,
            Duration = duration,
        };

        Storyboard.SetTarget(opacityAnimation, shape);
        Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(OpacityProperty));

        var storyboard = new Storyboard();
        storyboard.Children.Add(widthAnimation);
        storyboard.Children.Add(opacityAnimation);

        return storyboard;
    }

    private void FollowTheMouseIconWindow_OnLoaded(object sender, RoutedEventArgs e)
    {
        this.time.Interval = TimeSpan.FromSeconds(0.1);
        this.time.Tick += this.TimeOnTick;
        this.time.Start();
    }

    // 计算 rect 位置
    private Point GetShapePoint()
    {
        //  使用向量计算出鼠标位置的偏移量 (rect 默认会在 RootGrid 的中心)
        var grid = this.RootGrid;
        var mousePoint = Mouse.GetPosition(grid);
        var vector = new Vector(mousePoint.X, mousePoint.Y) - new Vector(grid.ActualWidth / 2, grid.ActualHeight / 2);

        // 鼠标位置的偏移量加上一个随机数
        const int len = 35;
        return new Point(vector.X + Random.Shared.Next(-1 * len, len), vector.Y + Random.Shared.Next(-1 * len, len));
    }

    private void TimeOnTick(object? sender, EventArgs e)
    {
        // 计算 rect 的位置值
        var point = this.GetShapePoint();

        // 创建 rect 
        var shape = new Ellipse
        {
            Stroke = Brushes.RoyalBlue,
            StrokeThickness = Random.Shared.Next(0, 6),
            RenderTransformOrigin = new Point(0.5, 0.5),
            RenderTransform = new TranslateTransform(point.X, point.Y),
        };

        // 高宽绑定,这样只需要改变一个值就可以改变所有
        shape.SetBinding(HeightProperty, new Binding(nameof(shape.Width)) { Source = shape, });

        // 给 rect 创建一个尺寸与透明的动画 
        var storyBoard = this.CreateStoryBoard(shape);
        storyBoard.Completed += (_, _) =>
        {
            if (shape.Parent is Panel panel)
            {
                panel.Children.Remove(shape);
            }
        };

        this.RootGrid.Children.Add(shape);
        storyBoard.Begin();
    }
上一篇
下一篇