鸿蒙自定义控件实现罗盘数字时钟效果

news/2024/7/20 17:45:34 标签: harmonyos, OpenHarmony, 数字时钟罗盘

前言:

DevEco Studio版本:4.0.0.600

关注过我的小伙伴一定知道我之前写过一篇基于Android的 仿抖音效果的数字时钟罗盘 最近看了鸿蒙的Canvas组件,今天通过Canvas组件也实现下罗盘数字时钟的效果。

参考链接:OpenHarmony Canvas   OpenHarmony Canvasrenderingcontext2d

效果:

实现原理分析

之前安卓实现是通过matrix矩阵的方式实现,但是在鸿蒙(API10)中暂时没有给画笔设置矩阵的方法。通过查找CanvasRenderingContext2D的方法,发现rotate方法比较符合要求。

已知圆形的整个弧度为:2 * Math.PI,那么每一秒的弧度为:2 * Math.PI / 60 * (每一秒所占弧度的比例)

通过for循环可得到每一秒的弧度需要旋转的弧度为:

rotate(2 * Math.PI / 60 * (index + 1 ) //index数组角标

为了使时分秒保持在右侧水平线上,就只能通过旋转坐标系来保持当前时间所在X轴坐标系一直在原始0或60秒的那个坐标系上,那么旋转的弧度为:2 * Math.PI / 60 * (每一秒所占弧度的比例 - 当前秒值所占弧度的比例)

通过for循环可得到每一秒的弧度在原始X轴方向为:

rotate(2 * Math.PI / 60 * (index + 1 - second))//index数组角标

同理可得分钟的每一分的弧度在原始X轴方向为:

rotate(2 * Math.PI / 60 * (index + 1 - minute))

时钟的每一时的弧度在原始X轴方向为:

rotate(2 * Math.PI / 12 * (index + 1 - hour))

代码实现:

1、Canvas创建

private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
@State canvasWidth: number = 500 // 500是表盘默认大小
private radius: number = 40 // 默认表盘半径

build() {
   Stack({ alignContent: Alignment.Center }) {
      Canvas(this.context)
         .padding({ top: 76 })
         .width(this.canvasWidth)
         .height(this.canvasWidth + HEIGHT_ADD)
         .onReady(() => {
            
         })
   }
   .width('100%')
   .height('100%')
   .backgroundColor(Color.Black)
}

2、定时器每隔一秒获取时间

Canvas(this.context)
   .padding({ top: 76 })
   .width(this.canvasWidth)
   .height(this.canvasWidth + HEIGHT_ADD)
   .onReady(() => {
      //添加setInterval定时器,每隔1s执行一次updateTime函数
      this.intervalId = setInterval(this.updateTime, 1000)
   })


updateTime = () => {
   this.context.clearRect(0, 0, this.canvasWidth, this.canvasWidth + HEIGHT_ADD)
   let nowTime = new Date()
   let hour = nowTime.getHours()
   let minute = nowTime.getMinutes()
   let second = nowTime.getSeconds()
   console.info("22222222222   hour: " + hour + "  minute: " + minute + "  second: " + second)

   this.context.translate(this.canvasWidth / 2, this.canvasWidth / 2) //移动当前坐标系的原点
   this.drawTime(hour, minute, second)
   this.context.translate(-this.canvasWidth / 2, -this.canvasWidth / 2) //当前坐标系的原点复原
}

3、数据初始化

const hours: Array<string> = ["一点", "二点", "三点", "四点", "五点", "六点", "七点", "八点", "九点", "十点", "十一点", "十二点"];

const minutes: Array<string> = ["一分", "二分", "三分", "四分", "五分", "六分", "七分", "八分", "九分", "十分", "十一分", "十二分", "十三分", "十四分", "十五分", "十六分", "十七分", "十八分", "十九分",
   "二十分", "二十一分", "二十二分", "二十三分", "二十四分", "二十五分", "二十六分", "二十七分", "二十八分", "二十九分", "三十分", "三十一分", "三十二分", "三十三分", "三十四分", "三十五分", "三十六分",
   "三十七分", "三十八分", "三十九分", "四十分", "四十一分", "四十二分", "四十三分", "四十四分", "四十五分", "四十六分", "四十七分", "四十八分", "四十九分", "五十分", "五十一分", "五十二分", "五十三分",
   "五十四分", "五十五分", "五十六分", "五十七分", "五十八分", "五十九分", ""];

const seconds: Array<string> = ["一秒", "二秒", "三秒", "四秒", "五秒", "六秒", "七秒", "八秒", "九秒", "十秒", "十一秒", "十二秒", "十三秒", "十四秒", "十五秒", "十六秒", "十七秒", "十八秒", "十九秒",
   "二十秒", "二十一秒", "二十二秒", "二十三秒", "二十四秒", "二十五秒", "二十六秒", "二十七秒", "二十八秒", "二十九秒", "三十秒", "三十一秒", "三十二秒", "三十三秒", "三十四秒", "三十五秒", "三十六秒",
   "三十七秒", "三十八秒", "三十九秒", "四十秒", "四十一秒", "四十二秒", "四十三秒", "四十四秒", "四十五秒", "四十六秒", "四十七秒", "四十八秒", "四十九秒", "五十秒", "五十一秒", "五十二秒", "五十三秒",
   "五十四秒", "五十五秒", "五十六秒", "五十七秒", "五十八秒", "五十九秒", ""];

4、绘制时分秒

drawTime(hour: number, minute: number, second: number) {
   this.context.save()

   hours.forEach((value, index) => {
      this.context.fillStyle = (hour % 12) == (index + 1) ? '#0080DC' : '#FFFFFF'
      this.context.font = (hour % 12) == (index + 1) ? '16px' : "14px"
      this.context.textAlign = "start"
      this.context.textBaseline = "middle"

      this.context.rotate(2 * Math.PI / 12 * (index + 1 - hour))
      this.context.fillText(value, this.radius + 30, 0)
      this.context.rotate(-2 * Math.PI / 12 * (index + 1 - hour))
      this.context.save()
      this.context.restore()
   })

   minutes.forEach((value, index) => {
      this.context.fillStyle = minute == (index + 1) ? '#0080DC' : '#FFFFFF'
      this.context.font = minute == (index + 1) ? '16px' : "14px"
      this.context.textAlign = "start"
      this.context.textBaseline = "middle"
      this.context.rotate(2 * Math.PI / 60 * (index + 1 - minute))
      this.context.fillText(value, this.radius + 70, 0)
      this.context.rotate(-2 * Math.PI / 60 * (index + 1 - minute))
      this.context.save()
      this.context.restore()
   })

   seconds.forEach((value, index) => {
      this.context.fillStyle = second == (index + 1) ? '#0080DC' : '#FFFFFF'
      this.context.font = second == (index + 1) ? '16px' : "14px"
      this.context.textAlign = "start"
      this.context.textBaseline = "middle"
      this.context.rotate(2 * Math.PI / 60 * (index + 1 - second))
      this.context.fillText(value, this.radius + 120, 0)
      this.context.rotate(-2 * Math.PI / 60 * (index + 1 - second))
      this.context.save()
      this.context.restore()
   })
}


http://www.niftyadmin.cn/n/5446165.html

相关文章

Linux 理解文件系统、磁盘结构、软硬链接

目录 一、理解磁盘结构 1、磁盘的物理结构 2、硬件层面理解 3、磁盘的具体物理存储结构 4、进行逻辑抽象 5、磁盘文件的管理 二、理解文件系统 1、文件的构成 2、为何选择4KB而非512字节作为基本单位? 3、文件系统的组成 数据块&#xff08;Data Blocks&#xff09; inode表&a…

linux查看usb是3.0还是2.0

1 作为device cat /sys/devices/platform/10320000.usb30drd/10320000.dwc3/udc/10320000.dwc3/current_speed 如下 high-speed usb2.0 super-speed usb3.0 2 作为host linux下使用以下命令查看 &#xff0c;如果显示 速率为5G, 则为USB 3.0&#xff0c; USB2.0通常显示速率…

机器学习-05-特征工程

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中特征工程部分。 参考 机器学习之特征工程详解 特征工程&#xff08;Feature Engineering&#xff09; 特征工程是指使用专业的背景知识和技巧处理数据&#xff0c;使得特征能在机器学习算法上发生更好的…

PMSM 永磁同步电机滑膜控制 SVPWM矢量控制 matlab simulink 仿真

仿真搭建平台&#xff1a; (1)该模型采用matlab/simulink 2016b版本搭建&#xff0c;使用matlab 2016b及以上版本打开最佳; (2)该模型已经提前转换了各个常用版本&#xff08;最低为matlab2012b&#xff09;&#xff0c;防止出现提示版本过高的情况。 模型截图&#xff1a; 算…

机器学习金融应用技术指南

1 范围 本文件提供了金融业开展机器学习应用涉及的体系框架、计算资源、数据资源、机器学习引擎、机 器学习服务、安全管理、内控管理等方面的建议。 本文件适用于开展机器学习金融应用的金融机构、技术服务商、第三方安全评估机构等。 2 规范性引用文件 下列文件中的内容通过…

MATLAB下载+安装教程

下载 MATLAB&#xff1a; 访问 MathWorks 官方网站&#xff1a;MathWorks 官方网站在网站上找到 "Downloads"&#xff08;下载&#xff09;选项&#xff0c;并选择 MATLAB。登录或创建一个 MathWorks 帐号。选择您希望下载的 MATLAB 版本&#xff0c;并根据您的操作…

超融合服务器:企业转型的助推器?

在当今快速发展的数字化时代&#xff0c;企业需要灵活、高效且可靠的IT基础设施来支撑其业务运营。传统的存储环境由于其复杂性和局限性&#xff0c;已经难以满足现代企业的需求。而超融合设备的出现&#xff0c;为企业提供了一个全新的选择。本文将深入探讨超融合服务器的优势…

复试专业前沿问题问答合集7-2——神经网络与强化学习

复试专业前沿问题问答合集7-2——神经网络与强化学习 神经网络与强化学习相关的基础知识问答 Q1: 什么是人工神经网络(Artificial Neural Networks, ANN)? A1: 人工神经网络是一种模仿生物神经网络行为的计算模型,由大量相互连接的人工神经元组成。每个神经元接收输入,…