感謝各位大佬和粉絲的厚愛和關心( 催更),我會再接再厲的,其實這也是督促自己的一種方式,非常感謝。
剛寫了一篇萬字長文,自己也休養生息(低調發育)了一段時間,接下來來幾個小案例。
拖曳小球
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同名)