文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

HarmonyOS Canvas 实现时钟

2024-12-01 19:44

关注

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

前言

最近在学习HarmonyOS 相关的东西,看了很多网上的canvas 实现时钟,现在我也来写一个关于HarmonyOS 的时钟吧。

项目说明

效果展示

实现步骤

1、在页面index.hml 中定义一个canvas 元素

<div class="container">
<canvas ref="clock" style="width: 600px; height:600px; background-color:#5a5a5a ">canvas>
div

2、需要在index.js data 中定义两个变量用来存放目标元素和绘制2d

export default {
data: {
c:'',
ctx:''
}
}

3、需要在onShow 生命周期中拿到目标元素并且绘制 2d

onShow(){
this.el = this.$refs.clock;
//获取canvas绘图上下文
this.ctx = this.el.getContext('2d');
this.initData()
},

4、定义一个初始化函数initData(),调用绘制函数

initData:function(){
this.updateClock(this.ctx)
},

5、绘制函数clock函数

(1)首先绘制外部最大的圆

drawPanel:function(ctx){
ctx.beginPath() //开始
ctx.arc(300, 300, 200, 0, Math.PI * 2) //绘制弧线路径
ctx.fillStyle = 'white' //填充颜色
ctx.fill() //填充
ctx.closePath() //闭合
},

此时的页面长这样:

(2)绘制时间(时)刻度(12小时刻度)

hourCalibration:function(ctx){
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; //定义刻度的数字
ctx.beginPath(); //开始
ctx.translate(300, 300) //移动当前坐标系的原点
ctx.font = '30px bold' //文字的大小
ctx.textAlign = "center"; // 文字居中
ctx.textBaseline = "middle"; // 设置文本绘制中的水平对齐方式 为文本块的中间
ctx.fillStyle = "black"; // 填充颜色
for (var i = 0; i < arr.length; i++) {
//绘制填充类文本
ctx.fillText(
arr[i],
168 * Math.cos(((i * 30 - 60) * Math.PI) / 180),
168 * Math.sin(((i * 30 - 60) * Math.PI) / 180)
);
}
ctx.closePath(); // 结束
},

此时页面:

(3)绘制中心的小圆点

centerDot:function(ctx){
ctx.beginPath(); // 开始
ctx.arc(0, 0, 8, 0, 2 * Math.PI); //绘制弧线路径
ctx.fill(); //对封闭路径进行填充
ctx.beginPath(); //开始
ctx.fillStyle = "white";
ctx.arc(0, 0, 5, 0, 2 * Math.PI); //绘制弧线路径
ctx.fill();//对封闭路径进行填充
},

此时的页面长这样:

(4)获取时间并且转化成北京时间

此时需要获取当前系统的本地时间,在此处遇到了一个小麻烦,鸿蒙开发者工具new Date() 获取到的时间为格林威治时间,而我们现在采用的是北京时间,需要写函数来转化时间,转化函数为getTimeStamp()。

getTimeStamp:function(){
var zoneOffset = 8;
//算出时差,并转换为毫秒:
var offset2 = new Date().getTimezoneOffset()* 60 * 1000;
//算出现在的时间:
var nowDate2 = new Date().getTime();
//此时东八区的时间
var currentZoneDate = new Date(nowDate2 + offset2 + zoneOffset*60*60*1000);
return currentZoneDate;
}

获取当前北京时间:

//修改时间 默认获取的是格林威治时间 需要将时间转化为北京时间才行
var date = this.getTimeStamp(new Date())
//获取当前的小时
var hours = date.getHours()
console.log(hours+'hours')
//获取当前分钟
var minutes = date.getMinutes()
console.log(minutes+'minutes')
//获取当前秒数
var seconds = date.getSeconds()
console.log(seconds+'seconds')

(5) 绘制时钟的指针

hourHand:function(ctx,hours, minutes){
var radius =
((2 * Math.PI) / 12) * hours + (((1 / 6) * Math.PI) / 60) * minutes;
ctx.save();// 保存当前状态,为了旋转后能回到当初状态。
ctx.beginPath(); //开始
ctx.lineWidth = 8; // 针的宽度
ctx.lineCap = "round"; // 针头为圆角
ctx.strokeStyle = "green"; //针的颜色
ctx.rotate(radius); // 旋转
ctx.moveTo(0, 0);
ctx.lineTo(0, -90);
ctx.stroke();
ctx.closePath() // 结束
// 回到保存的状态
ctx.restore();
},

此时的页面长这样:

(6)绘制分针的指针

minuteHand:function(ctx,minutes){
2 * Math.PI;
var radius = ((2 * Math.PI) / 60) * minutes;
ctx.save(); // 保存当前状态,为了旋转后能回到当初状态。
ctx.beginPath(); //开始
ctx.lineWidth = 4; // 针的宽度
ctx.lineCap = "round"; //针头为圆角
ctx.strokeStyle = "black";
ctx.rotate(radius); //旋转
ctx.moveTo(0, 0);
ctx.lineTo(0, -110);
ctx.stroke(); //绘制轮廓圆
ctx.closePath() //结束
ctx.restore();
},

此时页面长这样:

(7)绘制秒针

secondHand:function(ctx,seconds) {
var radius = ((2 * Math.PI) / 60) * seconds;
ctx.save(); // 保存当前状态,为了旋转后能回到当初状态。
ctx.beginPath(); //开始
ctx.lineWidth = 2; // 针的宽度
ctx.lineCap = "round"; //针头为圆角
ctx.strokeStyle = "red";
ctx.rotate(radius); //旋转
ctx.moveTo(0, 0);
ctx.lineTo(0, -140);
ctx.stroke();//绘制轮廓圆
ctx.closePath() //结束
ctx.restore();
},

此时页面长这样:

(8)最后一步我们需要写一个更新函数用来调用所有绘画函数并且在更新函数中获取对应的北京时间:

updateClock:function(ctx){
var time = this.getTimeStamp(new Date())
var hours = time.getHours();
var minutes = time.getMinutes();
var seconds = time.getSeconds();
ctx.save();
this.drawPanel(this.ctx);
this.hourCalibration(this.ctx);
this.secondHand(this.ctx,seconds);
this.minuteHand(this.ctx,minutes);
this.hourHand(this.ctx,hours, minutes);
this.centerDot(this.ctx)
ctx.closePath();
ctx.restore();
}

6、最后一步我们需要让这个钟表转动起来

那么就需要在initData 函数中写一个定时器没一秒钟执行一次绘制函数即可: 最后的图片如上图第一张图所示的效果。

initData:function(){
// 定时器一分钟刷新一次时间
let timer = setInterval(()=>{
this.ctx.clearRect(0, 0, 600, 600); //删除指定区域内的绘制内容。
this.updateClock(this.ctx)
},1000)
},

总结:

以上就是canvas 绘制一个时钟的全部步骤了。 最重要的一点是要能正确的获取到时间(北京时间)但是我发现在编辑器上new Date() 到的时间跟咋们的北京时间相差了八小时,在一位同事的提醒下才知道这个获取的时间为格林威治时间,那么我们需要将这个格林威治时间转化成北京时间,在网上找了一段转化方法终于转化成功。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。

来源:鸿蒙社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯