SkiaSharp 之 WPF 自绘时钟(案例版)
SkiaSharp是一个跨平台2D图形API,用于.NET平台,基于Google's Skia Graphics库(skia.org网站). 它提供了一个全面的2D API,可以跨移动、服务器和桌面模型来渲染图像。该图形库可实现获取指定坐标像素值、绘制2d图形、绘制文字(必须有相应字库支持)、创建缩略图等,微软是大力支持的。
可见此地址:
https://docs.microsoft.com/zh-cn/dotnet/api/skiasharp
首先是想熟悉下SkiaSharp的操作,另外呢,想基于SkiaSharp来做跨平台的UI渲染器,一直没有动手,在搜集资料,现在基本搜集的差不多了,所以,就找点例子,学学,也挺有趣的。
一个时钟的效果
大概是以下的样子,也挺简单的,就是对度数是要计算的,用到的方法,也就画圆和画路径以及画文本几个方法。
然后,根据时间,自动转动时钟的指针。
自从毕业后,就没有做过这样的案例了。但是,上手了,感觉还是很欣喜的。
Wpf 和 SkiaSharp
新建一个WPF项目,然后,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;}}
});
时钟逻辑
/// <summary>/// 一个简单版的时钟/// </summary>public class DrawClock{public SKPoint centerPoint;public int Radius = 0;public int HAND_TRUNCATION;public int HOUR_HAND_TRUNCATION;public int HAND_RADIUS;public int TIPS;/// <summary>/// 渲染/// </summary>public void Render(SKCanvas canvas, SKTypeface Font, int Width, int Height){centerPoint = new SKPoint(Width / 2, Height / 2);this.Radius = (int)(centerPoint.Y - 50);HAND_TRUNCATION = Width / 25;HOUR_HAND_TRUNCATION = Width / 10;HAND_RADIUS = this.Radius + 15;TIPS = this.Radius - 40;canvas.Clear(SKColors.SkyBlue);DrawCircle(canvas, Font);DrawCenter(canvas, Font);DrawHands(canvas, Font);DrawTimeNumber(canvas, Font);DrawTips(canvas, Font);using var paint = new SKPaint{Color = SKColors.Black,IsAntialias = true,Typeface = Font,TextSize = 20};using var paint2 = new SKPaint{Color = SKColors.Blue,IsAntialias = true,Typeface = Font,TextSize = 24};string msg = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss:fff:ffffff}";string tishi = " WPF SkiaSharp 自绘时钟 基础代码";string by = $"by 蓝创精英团队";canvas.DrawText(msg, 0, 30, paint);canvas.DrawText(tishi, 450, 30, paint);canvas.DrawText(by, 600, 400, paint2);}/// <summary>/// 画一个圆/// </summary>public void DrawCircle(SKCanvas canvas, SKTypeface Font){using var paint = new SKPaint{Color = SKColors.Black,Style = SKPaintStyle.Stroke,IsAntialias = true,StrokeWidth = 2};canvas.DrawCircle(centerPoint.X, centerPoint.Y, Radius, paint);}/// <summary>/// 时钟的核心/// </summary>public void DrawCenter(SKCanvas canvas, SKTypeface Font){using var paint = new SKPaint{Color = SKColors.Black,Style = SKPaintStyle.Fill,IsAntialias = true,StrokeWidth = 2};canvas.DrawCircle(centerPoint.X, centerPoint.Y, 5, paint);}private void DrawHand(SKCanvas canvas, SKTypeface Font, int times, bool isHour = false){var angle = Math.PI * 2 * (times / (double)60) - Math.PI / 2;var handRadius = isHour ? this.Radius - HAND_TRUNCATION - HOUR_HAND_TRUNCATION : this.Radius - HAND_TRUNCATION;using var paint = new SKPaint{Color = (DateTimeOffset.Now.Second % 4 <= 1) ? SKColors.Red : SKColors.Green,Style = SKPaintStyle.Fill,StrokeWidth = 2,IsStroke = true,StrokeCap = SKStrokeCap.Round,IsAntialias = true};var path = new SKPath();path.MoveTo(centerPoint);path.LineTo((float)(centerPoint.X + Math.Cos(angle) * handRadius), (float)(centerPoint.Y + Math.Sin(angle) * handRadius));path.Close();canvas.DrawPath(path, paint);}/// <summary>/// 画时针/// </summary>public void DrawHands(SKCanvas canvas, SKTypeface Font){var time = DateTime.Now;var hour = time.Hour > 12 ? time.Hour - 12 : time.Hour;DrawHand(canvas, Font, hour * 5 + time.Minute / 60 * 5, true);DrawHand(canvas, Font, time.Minute, false);DrawHand(canvas, Font, time.Second, false);}/// <summary>/// 画时间点/// </summary>public void DrawTimeNumber(SKCanvas canvas, SKTypeface Font){using var paint = new SKPaint{Color = SKColors.Black,IsAntialias = true,Typeface = Font,TextSize = 24};for (int i = 1; i <= 12; i++){var angle = Math.PI / 6 * (i - 3);var number = i.ToString();var numberTextWidth = paint.MeasureText(number);canvas.DrawText(number, (float)(centerPoint.X + Math.Cos(angle) * HAND_RADIUS - numberTextWidth / 2), (float)(centerPoint.Y + Math.Sin(angle) * HAND_RADIUS + 24 / 3), paint);}}/// <summary>/// 画提示信息/// </summary>public void DrawTips(SKCanvas canvas, SKTypeface Font){using var paint = new SKPaint{Color = SKColors.Black,IsAntialias = true,Typeface = Font,TextSize = 20};var now = DateTime.Now;//年月日var Date = $"{now.Year}/{now.Month}/{now.Day}";var DateTextWidth = paint.MeasureText(Date);var angle = Math.PI / 6 * (6 - 3);canvas.DrawText(Date, (float)(centerPoint.X + Math.Cos(angle) * TIPS - DateTextWidth / 2), (float)(centerPoint.Y + Math.Sin(angle) * TIPS), paint);//PM AMvar amOrPm = now.Hour > 12 ? "PM" : "AM";var amOrPmTextWidth = paint.MeasureText(amOrPm);var angle2 = Math.PI / 6 * (12 - 3);canvas.DrawText(amOrPm, (float)(centerPoint.X + Math.Cos(angle2) * TIPS - amOrPmTextWidth / 2), (float)(centerPoint.Y + Math.Sin(angle2) * TIPS), paint);}}
运行结果
总结
这个录的GIF播放效果真不错,基本体现出来了效果。
也算是入门了,后期,可以基于SkiaSharp,做更多的案例,出来,当然,还是基于自绘的实现。
代码地址
https://github.com/kesshei/WPFSkiaClockDemo.git
https://gitee.com/kesshei/WPFSkiaClockDemo.git
阅
一键三连呦!,感谢大佬的支持,您的支持就是我的动力!
SkiaSharp 之 WPF 自绘时钟(案例版)相关推荐
- SkiaSharp 之 WPF 自绘 拖曳小球(案例版)
感谢各位大佬和粉丝的厚爱和关心( 催更),我会再接再厉的,其实这也是督促自己的一种方式,非常感谢. 刚写了一篇万字长文,自己也休养生息(低调发育)了一段时间,接下来来几个小案例. 拖曳小球 WPF的拖 ...
- SkiaSharp 之 WPF 自绘 投篮小游戏(案例版)
此案例主要是针对光线投影法碰撞检测功能的示例,顺便做成了一个小游戏,很简单,但是,效果却很不错. 投篮小游戏 规则,点击投篮目标点,就会有一个球沿着相关抛物线,然后,判断是否进入篮子里,其实就是一个矩 ...
- SkiaSharp 之 WPF 自绘 粒子花园(案例版)
此案例包含了简单的碰撞检测,圆形碰撞检测方法,也可以说是五环弹球的升级版,具体可以根据例子参考. 粒子花园 这名字是案例的名字,效果更加具有科技感,很是不错,搞搞做成背景特效也是不错的选择. Wpf ...
- 《Axure RP7网站和APP原型制作从入门到精通(60小时案例版)》一1.3 部件概述...
本节书摘来自异步社区<Axure RP7网站和APP原型制作从入门到精通(60小时案例版)>一书中的第1章,第1.3节,作者 金乌,更多章节内容可以访问云栖社区"异步社区&quo ...
- [Web]Canvas手绘时钟
这是一个手绘时钟的案例,是不是很可爱呢! <!DOCTYPE html> <html lang="en"> <head><meta cha ...
- 图书推荐:《ASP.NET.基础教程——C#案例版》
本书结合用C#语言编写的可实际运行的示例代码,讨论了ASP.NET的构架.Web窗体.配置.HTTP管道.故障诊断和错误处理.验证.数据绑定.自定义控件.缓存.状态管理和安全性,阐述用C#构建基于We ...
- 手绘时钟的设计与实现
手绘时钟的设计与实现 功能要求:不依赖于任何图片素材,完全基于HTML5画布API绘制时钟,并实现每秒更新的动态效果. 实现效果图: 一.界面设计 1.画布的创建 1)使用<canvas> ...
- matlab模糊集合及其运算,模糊数学-Matlab案例版.pdf
模糊数学-Matlab案例版 1 基本编程思想 例题 设有矩阵 a 83 64 50 30 89 54 1 a 42 30 80 75 36 28 2 ...
- 《Axure RP7网站和APP原型制作从入门到精通(60小时案例版)》一第2章 母版详解2.1 创建母版的两种方法...
本节书摘来自异步社区<Axure RP7网站和APP原型制作从入门到精通(60小时案例版)>一书中的第2章,第2.1节,作者 金乌,更多章节内容可以访问云栖社区"异步社区&quo ...
最新文章
- mvc手把手教你写excel导入
- Excel超级链接方式应用技巧
- 【原创】源智工作流聚合步骤模型
- AC日记——Power收集 洛谷 P3800
- 软工Chapter Seven
- 二叉查找树的Java实现
- Spring Cloud微服务分布式云架构—集成项目简介
- PAT1054 求平均值 (20 分)【从非法输入字符串中获取合法输入 cin.putback()】
- 物联网将成为第四次工业革命的基石
- 绿联扩展坞拆解_拆解报告:UGREEN绿联3A1C四口多功能扩展坞(带SD卡槽版)
- 菜鸟请教高手web开发内存问题?
- 目前用到的两个分页存储过程:
- java linux 系统队列,linux下消息队列
- 【解决】RuntimeError:Trying to backward throughthe graph a second time
- 母婴商品销量分析(附Python源码及Tableau文件)
- 布鲁特-福斯算法(字符串匹配)
- 车轱辘APP提交到各应用市场的心得~
- 怎样将WPS文件转换成Word文档
- css之display:inline-block布局
- 转贴和菜头的曝脸存照