SkiaSharp 之 WPF 自绘 五环弹动球(案例版)
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SkiaSharp 之 WPF 自绘 五环弹动球(案例版)相关的知识,希望对你有一定的参考价值。
此案例基于拖曳和弹动球两个技术功能实现,如有不懂的可以参考之前的相关文章,属于递进式教程。
五环弹动球
好吧,名字是我起的,其实,你可以任意个球进行联动弹动,效果还是很不错的,有很多前端都是基于这个特效,可以搞出一些很有科技感的效果出来。
Wpf 和 SkiaSharp
新建一个WPF项目,然后,Nuget包即可 要添加Nuget包
Install-Package SkiaSharp.Views.WPF -Version 2.88.0
其中核心逻辑是这部分,会以我设置的60FPS来刷新当前的画板。
skContainer.PaintSurface += SkContainer_PaintSurface;
_ = Task.Run(() =>
while (true)
try
Dispatcher.Invoke(() =>
skContainer.InvalidateVisual();
);
_ = SpinWait.SpinUntil(() => false, 1000 / 60);//每秒60帧
catch
break;
);
弹球实体代码 (Ball.cs)
public class Ball
public double X get; set;
public double Y get; set;
public double VX get; set;
public double VY get; set;
public int Radius get; set;
public bool Dragged get; set; = false;
public SKColor sKColor get; set; = SKColors.Blue;
public bool CheckPoint(SKPoint sKPoint)
var d = Math.Sqrt(Math.Pow(sKPoint.X - X, 2) + Math.Pow(sKPoint.Y - Y, 2));
return this.Radius >= d;
五环弹动核心类 (FiveRings.cs)
/// <summary>
/// 五环弹球
/// </summary>
public class FiveRings
public SKPoint centerPoint;
public int Radius = 0;
public int BallLength = 8;
public double TargetX;
public double Spring = 0.03;
public double SpringLength = 200;
public double Friction = 0.95;
public List<Ball>? Balls;
public Ball? draggedBall;
public void init(SKCanvas canvas, SKTypeface Font, int Width, int Height)
if (Balls == null)
Balls = new List<Ball>();
for (int i = 0; i < BallLength; i++)
Random random = new Random((int)DateTime.Now.Ticks);
Balls.Add(new Ball()
X = random.Next(50, Width - 50),
Y = random.Next(50, Height - 50),
Radius = this.Radius
);
/// <summary>
/// 渲染
/// </summary>
public void Render(SKCanvas canvas, SKTypeface Font, int Width, int Height)
centerPoint = new SKPoint(Width / 2, Height / 2);
this.Radius = 20;
this.TargetX = Width / 2;
init(canvas, Font, Width, Height);
canvas.Clear(SKColors.White);
//划线
using var LinePaint = new SKPaint
Color = SKColors.Green,
Style = SKPaintStyle.Fill,
StrokeWidth = 3,
IsStroke = true,
StrokeCap = SKStrokeCap.Round,
IsAntialias = true
;
SKPath path = null;
foreach (var item in Balls)
if (path == null)
path = new SKPath();
path.MoveTo((float)item.X, (float)item.Y);
else
path.LineTo((float)item.X, (float)item.Y);
path.Close();
canvas.DrawPath(path, LinePaint);
foreach (var item in Balls)
if (!item.Dragged)
foreach (var ball in Balls.Where(t => t != item).ToList())
SpringTo(item, ball);
DrawCircle(canvas, item);
using var paint = new SKPaint
Color = SKColors.Blue,
IsAntialias = true,
Typeface = Font,
TextSize = 24
;
string by = $"by 蓝创精英团队";
canvas.DrawText(by, 600, 400, paint);
/// <summary>
/// 画一个圆
/// </summary>
public void DrawCircle(SKCanvas canvas, Ball ball)
using var paint = new SKPaint
Color = SKColors.Blue,
Style = SKPaintStyle.Fill,
IsAntialias = true,
StrokeWidth = 2
;
canvas.DrawCircle((float)ball.X, (float)ball.Y, ball.Radius, paint);
public void MouseMove(SKPoint sKPoint)
if (draggedBall != null)
draggedBall.X = sKPoint.X;
draggedBall.Y = sKPoint.Y;
public void MouseDown(SKPoint sKPoint)
foreach (var item in Balls)
if (item.CheckPoint(sKPoint))
item.Dragged = true;
draggedBall = item;
else
item.Dragged = false;
public void MouseUp(SKPoint sKPoint)
draggedBall = null;
foreach (var item in Balls)
item.Dragged = false;
public void SpringTo(Ball b1, Ball b2)
var dx = b2.X - b1.X;
var dy = b2.Y - b1.Y;
var angle = Math.Atan2(dy, dx);
var targetX = b2.X - SpringLength * Math.Cos(angle);
var targetY = b2.Y - SpringLength * Math.Sin(angle);
b1.VX += (targetX - b1.X) * Spring;
b1.VY += (targetY - b1.Y) * Spring;
b1.VX *= Friction;
b1.VY *= Friction;
b1.X += b1.VX;
b1.Y += b1.VY;
效果如下:
这个特效用的好,也能产生一些神奇的效果。
总结
这次是结合拖曳和弹动效果实现的综合案例,效果还是很不错的,之前也没想到原来还可以这样玩,拓展了玩法啊。
代码地址
https://github.com/kesshei/WPFSkiaFiveRingsDemo.git
https://gitee.com/kesshei/WPFSkiaFiveRingsDemo.git
阅
一键三连呦!,感谢大佬的支持,您的支持就是我的动力!
版权
蓝创精英团队(公众号同名,CSDN同名,CNBlogs同名)
以上是关于SkiaSharp 之 WPF 自绘 五环弹动球(案例版)的主要内容,如果未能解决你的问题,请参考以下文章