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.pswp.cn/news/284288.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284288.shtml
英文地址,請注明出處:http://en.pswp.cn/news/284288.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Nodejs Guides(四)

EVENTS events模塊API實例 const EventEmitter require(events);class MyEmitter extends EventEmitter { } //EventListener 會按照監聽器注冊的順序同步地調用所有監聽器。 //所以需要確保事件的正確排序且避免競爭條件或邏輯錯誤。 //監聽器函數可以使用 setImmediate() 或…

[轉]常用自動化測試工具

1、Appium 官網&#xff1a;http://appium.io AppUI自動化測試 Appium 是一個移動端自動化測試開源工具&#xff0c;支持iOS 和Android 平臺&#xff0c;支持Python、Java 等語言&#xff0c;即同一套Java 或Python 腳本可以同時運行在iOS 和Android平臺&#xff0c;Appium 是…

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…

顧小清:教育信息化進入數字化轉型重要時期

身處技術加快更新、新概念頻出的時代&#xff0c;教育信息化的發展更需要堅守以人為本的初心&#xff0c;在熱點炒作的雜音中保持理智&#xff0c;避免盲目&#xff0c;抓住符合教育規律、滿足教育需求、安全有效的準繩&#xff0c;理性推進和落實。 技術在不斷發展&#xff0c…

EJB

Enterprise JavaBean,企業級javabean,是J2EE的一部分&#xff0c;定義了一個用于 開發基于組件的企業多重應用程序的標準。其特點包括網絡服務支持和核心開發工具(SDK)。 是Java的核心代碼&#xff0c;分別是會話Bean&#xff08;Session Bean&#xff09;&#xff0c;實體Be…

java 連接redis 以及基本操作

一、首先下載安裝redis 二、項目搭建 1.搭建一個maven 工程 2. 在pom.xml文件的dependencies節點下增加如下內容&#xff1a; <!-- resis --><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version&…

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. 屬性域的關聯地理數據庫按照面向對象的模型存儲地理信息,也可以將其非空間信息保存在表中。對于要素和表可以設置一些規則進行限制,對屬性的約束稱為屬性域。 屬性域是描述字段合法值的規則,是一種增強數據…

ctype.h

isalpha&#xff1a;int isalpha(char ch);檢查ch是否是字母.是字母返回非0&#xff0c;否則返回0。iscntrl&#xff1a; int iscntrl(int ch); 檢查ch是否控制字符(其ASCII碼在0和0x1F之間,數值為 0-31).是返回非0,否則返回 0.isdigit&#xff1a;int isdigit(char ch);檢查ch…

『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;或表中具有相同屬性的對象的子集。可 通過它們對數據進行分類。 子類型是特征類(或對象類)中特征(或對象)的次級分類。例如一個公路線要素類可以根 據其字段類型的值細分為“高速公路”和“普通公路”兩個子類型。 子類…

作為Java程序員應該掌握的10項技能

本文詳細羅列了作為Java程序員應該掌握的10項技能。分享給大家供大家參考。具體如下&#xff1a; 1、語法&#xff1a;必須比較熟悉&#xff0c;在寫代碼的時候IDE的編輯器對某一行報錯應該能夠根據報錯信息知道是什么樣的語法錯誤并且知道任何修正。 2、命令&#xff1a;必須熟…

在Winform程序中設置管理員權限及為用戶組添加寫入權限

在我們一些Winform程序中&#xff0c;往往需要具有一些特殊的權限才能操作系統文件&#xff0c;我們可以設置運行程序具有管理員權限或者設置運行程序的目錄具有寫入的權限&#xff0c;如果是在操作系統里面&#xff0c;我們可以設置運行程序以管理員身份運行&#xff0c;或者設…

數據庫性能系列之索引(上)

前言上一次&#xff0c;我們從優化子查詢的角度&#xff0c;講解了一些簡單的數據庫性能優化方面的知識。通過優化子查詢的順序&#xff0c;包括合理使用IN和EXISTS&#xff0c;可以起到部分查詢的效率提升。但對于其他大多數場景&#xff0c;如單表記錄很大&#xff0c;或多表…

題目1023:EXCEL排序---------Case后面的是count,不是C

#include<stdio.h> #include<algorithm> #include<cstring> using namespace std;struct student {char num[10];char name[10];int grade; }s[100002]; int cmp1(student s1,student s2)//case 1 按照學號遞增 {return strcmp(s1.num,s2.num)<0; } int…