感谢各位大佬和粉丝的厚爱和关心( 催更),我会再接再厉的,其实这也是督促自己的一种方式,非常感谢。

刚写了一篇万字长文,自己也休养生息(低调发育)了一段时间,接下来来几个小案例。

拖曳小球

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 自绘 拖曳小球(案例版)的更多相关文章

  1. SkiaSharp 之 WPF 自绘 弹动小球(案例版)

    没想到粉丝对界面效果这么喜欢,接下来就尽量多来点特效,当然,特效也算是动画的一部分了.WPF里面已经包含了很多动画特效的功能支持了,但是,还是得自己实现,我这边就来个自绘实现的. 弹动小球 弹动小球是 ...

  2. SkiaSharp 之 WPF 自绘 五环弹动球(案例版)

    此案例基于拖曳和弹动球两个技术功能实现,如有不懂的可以参考之前的相关文章,属于递进式教程. 五环弹动球 好吧,名字是我起的,其实,你可以任意个球进行联动弹动,效果还是很不错的,有很多前端都是基于这个特 ...

  3. SkiaSharp 之 WPF 自绘 粒子花园(案例版)

    此案例包含了简单的碰撞检测,圆形碰撞检测方法,也可以说是五环弹球的升级版,具体可以根据例子参考. 粒子花园 这名字是案例的名字,效果更加具有科技感,很是不错,搞搞做成背景特效也是不错的选择. Wpf ...

  4. SkiaSharp 之 WPF 自绘 投篮小游戏(案例版)

    此案例主要是针对光线投影法碰撞检测功能的示例,顺便做成了一个小游戏,很简单,但是,效果却很不错. 投篮小游戏 规则,点击投篮目标点,就会有一个球沿着相关抛物线,然后,判断是否进入篮子里,其实就是一个矩 ...

  5. ABB机器人设置安全区(案例版)

    ABB机器人设置安全区.中断(案例版) 1.概述 在如今机器人中普遍会设置机器人的安全区域,也可以理解为工作范围.主要目的是为了机器人运行时的安全性和可靠性.ABB机器人也不例外,下面我们就讲讲ABB ...

  6. WPF简单的口算案例

    前几天在博客园,看到有博友利用Winform做了一个口算案例,于是我想把它移植在WPF程序中.Winform程序:http://www.cnblogs.com/ImYZF/p/3345452.html ...

  7. WebView2 通过 PuppeteerSharp 实现爬取 王者 壁纸 (案例版)

    此案例是<.Net WebView2 项目,实现 嵌入 WEB 页面 Chromium内核>文的续集. 主要是针对WebView2的一些微软自己封装的不熟悉的API,有一些人已经对 Pup ...

  8. 【万字长文】使用 LSM-Tree 思想基于.Net 6.0 C# 实现 KV 数据库(案例版)

    文章有点长,耐心看完应该可以懂实际原理到底是啥子. 这是一个KV数据库的C#实现,目前用.NET 6.0实现的,目前算是属于雏形,骨架都已经完备,毕竟刚完工不到一星期. 当然,这个其实也算是NoSQL ...

  9. WPF 实现圆形进度条

    项目中用到圆形进度条,首先就想到使用 ProgressBar 扩展一个,在园子里找到迷途的小榔头给出的思路和部分代码,自己加以实现. 进度小于60显示红色,大于60则显示绿色.效果如下: 基本思路: ...

随机推荐

  1. spring4+hibernate4 整合

    1.web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version=" ...

  2. 多线程07:async、future、packaged_task、promise

    async.future.packaged_task.promise 本节内容需要包含头文件:#include <future> 一.std::async. std::future 创建后 ...

  3. vue中blob文件下载及其它下载方式

    一.Blob对象的了解 1:blob表示一个不可变.原始数据的类文件对象.Blob()构造函数返回一个新的blob对象:blob对象的内容由参数给出的值串联组成: 2:new Blob(array, ...

  4. Redis 的数据过期了就会马上删除么?

    码哥,当 key 达到过期时间,Redis 就会马上删除么? 先说结论,并不会立马删除,Redis 有两种删除过期数据的策略: 定期选取部分数据删除: 惰性删除: 该命令在 Redis 2.4 版本, ...

  5. 嵌入:CAN

    说下我的学习过程.刚到公司的时候我根本不知道什么是CAN,甚至连以太网和串口通讯都不懂.领导把USBCAN分析仪拿给我,把铜线短接上,用软件在CAN1窗口点下发送,CAN2窗口马上接收到了发送出来的数 ...

  6. 好客租房32-事件绑定this指向(class实例方法)

    class实例方法 利用箭头函数的class实例方法 //导入react import React from 'react'   import ReactDOM from 'react-dom' // ...

  7. QC快速充电

    QC快充 一.高通QC快充的介绍 二.识别充电类型的芯片介绍 三.QC充电曲线 四.如何在log中看QC充电类型 五.QC3识别错误 六.波形图 一.高通QC快充的介绍 高通QC快充技术,又称Quic ...

  8. 用STM32玩SR04(测距、串口显示、OLED显示)

    目录 用STM32玩SR04(测距.串口显示.OLED显示) 超声波模块使用 SR04初始化 SR04使用串口打印数据 SR04使用OLED来传输数据,并显示在OLED上 用STM32玩SR04(测距 ...

  9. Node.js躬行记(21)——花10分钟入门Node.js

    Node.js 不是一门语言,而是一个基于 V8 引擎的运行时环境,下图是一张架构图. 由图可知,Node.js 底层除了 JavaScript 代码之外,还有大量的 C/C++ 代码. 常说 Nod ...

  10. c++ 超长整数加法 高精度加法

    c++ 超长整数加法 高精度加法 实现思路 不能直接使用加法,因为int和long long都已超出最大数据表示范围 数据读入采用string类型,读入后将数据的每一位存储到vector中 vecto ...