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();
}