HarmonyOS-基于canvas绘制复古钟表

发表于:2022-3-04 09:28

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:罗鹏荣    来源:鸿蒙社区

  一、前言
  找个空闲的时间,将目光聚焦到钟表上。开始你会感觉流逝的只是滴滴答答,一分一秒的时间,而慢慢的你会感觉到消逝的是你无声无息的生命。 今天分享一个利用canvas绘制时钟的写法,实现模拟时钟的功能,钟表时间与系统时间保持一致,刻度将24小时制转换为12小时制。
  效果展示
  二、canvas的属性、方法
  1.API链接地址:https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-canvas-canvas-0000000000621808
  2.案例中使用到的属性和方法:
  三、创建画布。
  //hml部分
  <canvas ref="canvas" style="width: 320px; height: 320px; background-color: #000;"></canvas>
  //以下为JS代码
  const el = this.$refs.canvas;
  const ctx = el.getContext('2d',{ antialias: true });
  //绘制的准备工作--画布的中心点
  const canvasX = JSON.stringify(el.style.width).replace(/[^0-9]/ig,"");
  const canvasY = JSON.stringify(el.style.height).replace(/[^0-9]/ig,"");

  四、获取当前时间并转换为12小时制
  const date = new Date();
  const hour = date.getHours();
  const minute = date.getMinutes();
  const second = date.getSeconds();
  const hours = hour > 15 ? hour - 16 : hour + 8;
  const hh = hours > 12 ? hours - 12 : hours;

  五、绘制表盘
  ctx.lineWidth = 6; 
  ctx.strokeStyle = '#FFF';
  ctx.beginPath();
  // x,y,r,0~360,true/false:正反向画圆
  ctx.arc(Number(canvasX/2), Number(canvasY/2), Number(canvasX/2 - 20), Number(canvasX/2 - 110), 0, true);
  ctx.closePath();
  ctx.stroke();

  六、绘制分刻度
  for (var i = 0; i < 60; i++) {
                  ctx.save();
                  ctx.lineWidth = 2;
                  if(i < this.second){
                      ctx.strokeStyle = 'rgba(6,235,0,0.5)';
                  }else if(i == this.second){
                      ctx.strokeStyle = '#06EB00';
                  }else{
                      ctx.strokeStyle = '#999';
                  }
                  ctx.translate(Number(canvasX/2), Number(canvasY/2))
                  ctx.rotate(i * 6 * Math.PI / 180);
                  ctx.beginPath();
                  ctx.moveTo(0, Number(42 - canvasX/2));
                  ctx.lineTo(0, Number(30 - canvasX/2));
                  ctx.closePath();
                  ctx.stroke();
                  ctx.restore();
              }

  七、绘制时刻度
  for (var index = 0; index < 12; index++) {
                  ctx.save();
                  ctx.lineWidth = 4;
                  if((index * 5) == this.second){
                      ctx.strokeStyle = '#06EB00';
                  }else{
                      ctx.strokeStyle = '#FFF';
                  }
                  ctx.translate(Number(canvasX / 2), Number(canvasY / 2));
                  ctx.rotate((index+30) * 30 * Math.PI / 180) //角度*3.14/180=弧度
                  ctx.beginPath();
                  ctx.moveTo(0, Number(canvasX / 2 - 50));
                  ctx.lineTo(0, Number(canvasY / 2 - 30));
                  ctx.closePath();
                  ctx.stroke();
                  ctx.restore();
              }

  八、绘制时钟
   ctx.save();
                  ctx.lineWidth = 6;
                  ctx.strokeStyle = "#FFF";
                  ctx.translate(Number(canvasX/2), Number(canvasY/2));
          //如果时间不是整点,需要采用 h*6 + m*360 + s* 21600 ,来计算时针的偏移量 
                  ctx.rotate(this.hour * (Math.PI / 6) + this.minute  * (Math.PI / 360) + this.second * (Math.PI / 21600));
                  ctx.beginPath();
                  ctx.moveTo(0, Number(80 - canvasX/2));
                  ctx.lineTo(0, Number(canvasX/2 - 145));
                  ctx.closePath();
                  ctx.stroke();
                  ctx.restore();

  九、绘制分钟
  ctx.save();
              ctx.lineWidth = 4;
              ctx.strokeStyle = "#FFF";
              ctx.translate(Number(canvasX/2), Number(canvasY/2));
              ctx.rotate(this.minute * 6 * Math.PI / 180);
              ctx.beginPath();
              ctx.moveTo(0, Number(60 - canvasX/2));
              ctx.lineTo(0, Number(canvasX/2 - 140));
              ctx.closePath();
              ctx.stroke();
              ctx.restore();

  十、绘制秒钟
  ctx.save();
              ctx.lineWidth = 2;
              ctx.strokeStyle = "red";
              ctx.fillStyle = "red"
              ctx.translate(Number(canvasX/2), Number(canvasY/2));
              ctx.rotate(this.second * 6 * Math.PI / 180);
              ctx.beginPath();
              ctx.moveTo(0, Number(62 - canvasX/2));
              ctx.lineTo(0, Number(canvasX/2 - 130));
              ctx.closePath();
              ctx.stroke();
              //绘制中心红点
              ctx.beginPath();
              ctx.arc(0,0,4,0,360 * Math.PI / 180)
              ctx.fill();
              //绘制秒针头部的圆圈
              ctx.beginPath();
              ctx.arc(0,Number(58 - canvasX/2),4,0,360 * Math.PI / 180);
              ctx.stroke();
              ctx.restore();

  源码地址
  https://gitee.com/luopengrong/harmonyos/tree/clock

  总结
  此时能得到一个静态时钟图,将步骤四到步骤十的代码封装成drawclock() 函数,采用setInterval()函数的功能,每1000ms,运行一次drawclock() 函数,这样就每一秒画一次,显示的就是时钟啦!本次分享希望对大家有所帮助。

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号