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

效果如下:

572f0c3bb10f688ecaede25706d46801.gif

我可以点的球的边边哦,这也是一个小技巧,点到球哪里,停止的时候,鼠标还在那个位置,是不是有点像拖动窗体的感觉了。

总结

以前对拖曳总是很好奇,一直想是如何实现的,现在自己也自己从头到尾的实现了,那么,它就是已知的,这就是可以写出来的进步,每天都应该有一点这样的进步。

代码地址

https://github.com/kesshei/WPFSkiaDragDemo.git

https://gitee.com/kesshei/WPFSkiaDragDemo.git

一键三连呦!,感谢大佬的支持,您的支持就是我的动力!

版权

蓝创精英团队(公众号同名,CSDN同名)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/284288.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ABP学习资源整理

不同的编程语言都有构建Web Application的框架&#xff0c;比如C#中的ASP.NET Core和ABP&#xff0c;Java中的Spring Boot和Spring Cloud&#xff0c;Python中的Django和Flask&#xff0c;Node.js中的Express和Koa2&#xff0c;Go中的Beego和Gin等。今天要介绍的主角是ABP框架&…

【ArcGIS微课1000例】0049:制图表达(4)---自由式制图表达

文章目录 一、转换为自由表达并编辑二、将效果转换为几何当编辑地图时,可能会遇到一个独特的或显著的特征,需要专门的符号的情况,可以使用覆盖的制图表达来实现,但是往往不够。可能需要简单地绘制一个图形以达到要求的外观,这时可以尝试使用自由式制图表达。 自由式制图表…

基于FPGA的异步FIFO设计

今天要介绍的异步FIFO&#xff0c;可以有不同的读写时钟&#xff0c;即不同的时钟域。由于异步FIFO没有外部地址端口&#xff0c;因此内部采用读写指针并顺序读写&#xff0c;即先写进FIFO的数据先读取&#xff08;简称先进先出&#xff09;。这里的读写指针是异步的&#xff0…

EJB

Enterprise JavaBean,企业级javabean,是J2EE的一部分&#xff0c;定义了一个用于 开发基于组件的企业多重应用程序的标准。其特点包括网络服务支持和核心开发工具(SDK)。 是Java的核心代码&#xff0c;分别是会话Bean&#xff08;Session Bean&#xff09;&#xff0c;实体Be…

WinForm(一):开始一个WinForm程序

WinForm程序只能运行在Windows上&#xff0c;即使是基于.NET5&#xff0c;6&#xff0c;7也一样。因为WinForm的UI层对接的底层API是基于Windows的。用VisualStudio创建一个WinForm应用很简单&#xff0c;建议使用非.NET Framework版&#xff0c;因为.NET Framework微软渐渐不支…

【ArcGIS微课1000例】0050:Geodatabase属性域操作全解

文章目录 1. 属性域的创建2. 属性域的查看3. 属性域的删除与修改4. 属性域的关联地理数据库按照面向对象的模型存储地理信息,也可以将其非空间信息保存在表中。对于要素和表可以设置一些规则进行限制,对属性的约束称为属性域。 属性域是描述字段合法值的规则,是一种增强数据…

『JavaScript』核心

为什么80%的码农都做不了架构师&#xff1f;>>> 弱类型语言 JavaScript是一种弱类型的语言。变量可以根据所赋的值改变类型。原始类型之间也可以进行类型转换。其弱类型的物质为其带来了极大的灵活性。 注意&#xff1a;原始类型使用值传递&#xff0c;复合类型使用…

优酷VIP会员周卡只需7.5元,看《沉香如屑》用优酷视频

由杨紫、成毅主演的《沉香如屑》已上线7天。站内热度值已经破万&#xff0c;也拿下了4次日冠的好成绩。追优酷视频最新热剧不能没有优酷VIP会员啊&#xff0c;优酷的会员&#xff0c;价格算是最便宜的了&#xff0c;下面是幻海优品优酷VIP会员特价充值的价格。优酷VIP会员特价充…

Solr6.1.0Windows安装步骤

一、 环境 solr 6.1.0 下载地址 http://archive.apache.org/dist/lucene/solr/6.1.0/ jdk 1.8 tomcat8 二、 安装solr到tomcat 1.解压solr&#xff0c;把 solr-6.1.0\solr-6.1.0\server 下的solr-webapp 文件夹拷贝到tomcat 的webapps下&#xff0c;重命名为solr&#xff1b;…

[转]Autofac 框架初识与应用

一、前言 这上一篇中&#xff0c;主要讲述了什么是IoC容器&#xff0c;以及了解到它是DI构造函注入的框架&#xff0c;它管理着依赖项的生命周期以及映射关系&#xff0c;同时也介绍实践了在ASP.Net Core中,默认提供的内置IoC容器&#xff0c;以及它的实例注册方式和相应的生命…

【ArcGIS微课1000例】0051:Geodatabase子类型操作全解

子类型是要素类中具有相同属性的要素的子集&#xff0c;或表中具有相同属性的对象的子集。可 通过它们对数据进行分类。 子类型是特征类(或对象类)中特征(或对象)的次级分类。例如一个公路线要素类可以根 据其字段类型的值细分为“高速公路”和“普通公路”两个子类型。 子类…

在Winform程序中设置管理员权限及为用户组添加写入权限

在我们一些Winform程序中&#xff0c;往往需要具有一些特殊的权限才能操作系统文件&#xff0c;我们可以设置运行程序具有管理员权限或者设置运行程序的目录具有写入的权限&#xff0c;如果是在操作系统里面&#xff0c;我们可以设置运行程序以管理员身份运行&#xff0c;或者设…

数据库性能系列之索引(上)

前言上一次&#xff0c;我们从优化子查询的角度&#xff0c;讲解了一些简单的数据库性能优化方面的知识。通过优化子查询的顺序&#xff0c;包括合理使用IN和EXISTS&#xff0c;可以起到部分查询的效率提升。但对于其他大多数场景&#xff0c;如单表记录很大&#xff0c;或多表…

【ArcGIS微课1000例】0052:创建地理数据库注记(标准注记、要素关联注记、尺寸注记)

本文讲述创建地理数据库注记(标准注记、要素关联注记、尺寸注记)的方法。 文章目录 一、创建标准注记二、创建与要素关联的注记三、创建尺寸注记一、创建标准注记 标准注记不与地理数据库中的要素关联。标准注记的一个例子是,地图上标记某山脉的文字,没有特定的要索代表该…

Lambda表达式超详解

目录 背景 Lambda表达式的用法 函数式接口 Lambda表达式的基本使用 语法精简 变量捕获 匿名内部类 匿名内部类中的变量捕获 Lambda的变量捕获 Lambda表达式在类集中的使用 Collection接口 List接口 Map接口 总结 背景 Lambda表达式是Java SE 8中的一个重要的新特性.…

【ArcGIS微课1000例】0043:ArcGIS绘制国界线的3种方法

本文讲解ArcGIS绘制国界线的3种方法。 文章目录 1. 直接修改国界线符号2. 缓冲区工具3. 制图表达1. 直接修改国界线符号 直接修改国界线/省界线的符号。点击“线要素”出现符号选择器,点击【编辑符号】按钮,编辑成下面右图的形式。缺点:只能在边界一侧出现缓冲样式,如下面…

C# 获取系统已安装的.NET版本

本文经原作者授权以原创方式二次分享&#xff0c;欢迎转载、分享。原文作者&#xff1a;唐宋元明清原文地址&#xff1a; https://www.cnblogs.com/kybs0/p/16478587.htmlC# 获取系统已安装的.NET版本获取系统已安装的.NET版本&#xff0c;来确定当前应用可运行的环境。获取系…

.NET 6 Minimal API 的经验分享

Minimal API 是 .NET 6 提供的最新功能 &#xff0c; 对比传统的 ASP.NET Core Web API 方式更加直接 , 你可以用几行代码编写好 REST API 。 没有了祖传的 Startup.cs 和 Controller &#xff0c;通过简单的代码就可以完成 API 的开发。在第二阶段的 .NET 挑战赛中就以 .NET 6…

JavaWeb之Filter过滤器

原本计划这一篇来总结JSP&#xff0c;由于JSP的内容比较多&#xff0c;又想着晚上跑跑步减减肥&#xff0c;所以今天先介绍Filter以及它的使用举例&#xff0c;这样的话还有些时间可以锻炼锻炼。言归正传&#xff0c;过滤器从字面理解她的话有拦网、过滤的功能&#xff0c;可以…