SkiaSharp 之 WPF 自绘 拖曳小球(案例版)
感谢各位大佬和粉丝的厚爱和关心( 催更),我会再接再厉的,其实这也是督促自己的一种方式,非常感谢。
刚写了一篇万字长文,自己也休养生息(低调发育)了一段时间,接下来来几个小案例。
拖曳小球
WPF的拖曳效果,基本配置一下,就可以了,但是自绘的话,就得自己控制,按键点击,按键移动和按键松开的事件,与其配合达到目的。
这个效果实现了,其实也变相的实现了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;
}
}
});
实现代码的 鼠标按下,移动,鼠标松开
先对SkiaSharp对象,增加相关事件
skContainer.MouseDown += SkContainer_MouseDown;
skContainer.MouseUp += SkContainer_MouseUp;
skContainer.MouseMove += SkContainer_MouseMove;
然后增加相关事件处理代码,我这边都统一处理了.
private void SkContainer_MouseDown(object sender, MouseButtonEventArgs e)
{
var cur = e.GetPosition(sender as IInputElement);
drawClock.MouseDown(new SKPoint((float)cur.X, (float)cur.Y), true);
}
private void SkContainer_MouseUp(object sender, MouseEventArgs e)
{
var cur = e.GetPosition(sender as IInputElement);
drawClock.MouseDown(new SKPoint((float)cur.X, (float)cur.Y), false);
}
private void SkContainer_MouseMove(object sender, MouseEventArgs e)
{
var cur = e.GetPosition(sender as IInputElement);
drawClock.MouseMove(new SKPoint((float)cur.X, (float)cur.Y));
}
拖曳核心类
/// <summary>
/// 拖曳
/// </summary>
public class Drag
{
public SKPoint centerPoint;
public int Radius = 0;
private bool Pressed = false;
private bool CirclePressend = false;
private SKPoint sKPoint = SKPoint.Empty;
private SKPoint CirclePoint = SKPoint.Empty;
private SKCanvas canvas;
private float dx = 0;
private float dy = 0;
/// <summary>
/// 渲染
/// </summary>
public void Render(SKCanvas canvas, SKTypeface Font, int Width, int Height)
{
this.canvas = canvas;
centerPoint = new SKPoint(Width / 2, Height / 2);
this.Radius = 40;
canvas.Clear(SKColors.White);
if (CirclePoint.IsEmpty)
{
CirclePoint = new SKPoint(centerPoint.X, centerPoint.Y);
}
if (CirclePressend)
{
CirclePoint = new SKPoint(sKPoint.X - dx, sKPoint.Y - dy);
DrawCircle(this.canvas, CirclePoint);
}
else
{
DrawCircle(this.canvas, CirclePoint);
}
using var paint = new SKPaint
{
Color = SKColors.Black,
IsAntialias = true,
Typeface = Font,
TextSize = 24
};
var msg = $"X:{ sKPoint.X} Y:{sKPoint.Y} Pressed:{Pressed} CirclePressend:{CirclePressend}";
canvas.DrawText(msg, 0, 30, paint);
}
public void MouseMove(SKPoint sKPoint)
{
this.sKPoint = sKPoint;
if (CirclePressend)//按下,就开始拖动
{
CirclePoint = sKPoint;
}
}
public void MouseDown(SKPoint sKPoint, bool Pressed)
{
this.sKPoint = sKPoint;
this.Pressed = Pressed;
if (this.Pressed)
{
this.CirclePressend = CheckPoint(sKPoint, CirclePoint);
if (this.CirclePressend)
{
dx = sKPoint.X - CirclePoint.X;
dy = sKPoint.Y - CirclePoint.Y;
}
}
else
{
this.CirclePressend = false;
}
}
public bool CheckPoint(SKPoint sKPoint, SKPoint CirclePoint)
{
var d = Math.Sqrt(Math.Pow(sKPoint.X - CirclePoint.X, 2) + Math.Pow(sKPoint.Y - CirclePoint.Y, 2));
return this.Radius >= d;
}
/// <summary>
/// 画一个圆
/// </summary>
public void DrawCircle(SKCanvas canvas, SKPoint sKPoint)
{
using var paint = new SKPaint
{
Color = SKColors.Blue,
Style = SKPaintStyle.Fill,
IsAntialias = true,
StrokeWidth = 2
};
canvas.DrawCircle(sKPoint.X, sKPoint.Y, Radius, paint);
}
}
效果如下:

我可以点的球的边边哦,这也是一个小技巧,点到球哪里,停止的时候,鼠标还在那个位置,是不是有点像拖动窗体的感觉了。
总结
以前对拖曳总是很好奇,一直想是如何实现的,现在自己也自己从头到尾的实现了,那么,它就是已知的,这就是可以写出来的进步,每天都应该有一点这样的进步。
代码地址
https://github.com/kesshei/WPFSkiaDragDemo.git
https://gitee.com/kesshei/WPFSkiaDragDemo.git
阅
一键三连呦!,感谢大佬的支持,您的支持就是我的动力!
版权
蓝创精英团队(公众号同名,CSDN同名,CNBlogs同名)
SkiaSharp 之 WPF 自绘 拖曳小球(案例版)的更多相关文章
- SkiaSharp 之 WPF 自绘 弹动小球(案例版)
没想到粉丝对界面效果这么喜欢,接下来就尽量多来点特效,当然,特效也算是动画的一部分了.WPF里面已经包含了很多动画特效的功能支持了,但是,还是得自己实现,我这边就来个自绘实现的. 弹动小球 弹动小球是 ...
- SkiaSharp 之 WPF 自绘 五环弹动球(案例版)
此案例基于拖曳和弹动球两个技术功能实现,如有不懂的可以参考之前的相关文章,属于递进式教程. 五环弹动球 好吧,名字是我起的,其实,你可以任意个球进行联动弹动,效果还是很不错的,有很多前端都是基于这个特 ...
- SkiaSharp 之 WPF 自绘 粒子花园(案例版)
此案例包含了简单的碰撞检测,圆形碰撞检测方法,也可以说是五环弹球的升级版,具体可以根据例子参考. 粒子花园 这名字是案例的名字,效果更加具有科技感,很是不错,搞搞做成背景特效也是不错的选择. Wpf ...
- SkiaSharp 之 WPF 自绘 投篮小游戏(案例版)
此案例主要是针对光线投影法碰撞检测功能的示例,顺便做成了一个小游戏,很简单,但是,效果却很不错. 投篮小游戏 规则,点击投篮目标点,就会有一个球沿着相关抛物线,然后,判断是否进入篮子里,其实就是一个矩 ...
- ABB机器人设置安全区(案例版)
ABB机器人设置安全区.中断(案例版) 1.概述 在如今机器人中普遍会设置机器人的安全区域,也可以理解为工作范围.主要目的是为了机器人运行时的安全性和可靠性.ABB机器人也不例外,下面我们就讲讲ABB ...
- WPF简单的口算案例
前几天在博客园,看到有博友利用Winform做了一个口算案例,于是我想把它移植在WPF程序中.Winform程序:http://www.cnblogs.com/ImYZF/p/3345452.html ...
- WebView2 通过 PuppeteerSharp 实现爬取 王者 壁纸 (案例版)
此案例是<.Net WebView2 项目,实现 嵌入 WEB 页面 Chromium内核>文的续集. 主要是针对WebView2的一些微软自己封装的不熟悉的API,有一些人已经对 Pup ...
- 【万字长文】使用 LSM-Tree 思想基于.Net 6.0 C# 实现 KV 数据库(案例版)
文章有点长,耐心看完应该可以懂实际原理到底是啥子. 这是一个KV数据库的C#实现,目前用.NET 6.0实现的,目前算是属于雏形,骨架都已经完备,毕竟刚完工不到一星期. 当然,这个其实也算是NoSQL ...
- WPF 实现圆形进度条
项目中用到圆形进度条,首先就想到使用 ProgressBar 扩展一个,在园子里找到迷途的小榔头给出的思路和部分代码,自己加以实现. 进度小于60显示红色,大于60则显示绿色.效果如下: 基本思路: ...
随机推荐
- Nginx代理websocket为什么要这样做?
Nginx反向代理websocket 示例: http { map $http_upgrade $connection_upgrade { default upgrade; '' close; } s ...
- Event Loop 是什么?
Event Loop 是什么? 本文写于 2020 年 12 月 6 日 广义上来说 Event Loop 并不是 JavaScript 独有的概念,他是一个计算机的通用概念. 狭义上来说,只有 No ...
- 767. Reorganize String - LeetCode
Question 767. Reorganize String Solution 题目大意: 给一个字符串,将字符按如下规则排序,相邻两个字符一同,如果相同返回空串否则返回排序后的串. 思路: 首先找 ...
- 流,用声明性的方式处理数据集 - 读《Java 8实战》
引入流 Stream API的代码 声明性 更简洁,更易读 可复合 更灵活 可并行 性能更好 流是什么? 它允许以声明方式处理数据集合 遍历数据集的高级迭代器 透明地并行处理 简短定义:从支持数据处理 ...
- Flask表单验证
学习内容:①判断请求方式(request.method) from flask import Flask,render_template,request app = Flask(__name__) @ ...
- javaweb开发案例
1.实验3 (1)当运行Servlet时,碰到"空指针异常"错误怎么处理? 答:应提示用户操作有误,或设置对象值为空字符串或一个默认值,或是不执行某操作,直接跳转到其他处理中. ( ...
- Jackson多态序列化
场景 做一个消息中心,专门负责发送消息.消息分为几种渠道,包括手机通知(Push).短信(SMS).邮件(Email),Websocket等渠道. 我定义了一个基类MessageRequest用来接收 ...
- Spring Ioc源码分析系列--@Autowired注解的实现原理
Spring Ioc源码分析系列--@Autowired注解的实现原理 前言 前面系列文章分析了一把Spring Ioc的源码,是不是云里雾里,感觉并没有跟实际开发搭上半毛钱关系?看了一遍下来,对我的 ...
- Java_Scanner的使用
目录 Scanner对象 scanner.next()和scanner.nextln()的区别 scanner.hasNext()和scanner.hasNextln() Scanner拓展 视频课程 ...
- 【clickhouse专栏】单机版的安装与验证
<clickhouse专栏>第三节内容,先安装一个单机版的clickhouse,是后续学习多副本或者分布式集群安装的基础内容.但基本的clickhouse是不依赖于zookeeper的,只 ...