使用h5 canvas-绘制时钟

举报
khz 发表于 2020/06/19 10:42:05 2020/06/19
【摘要】 学习完canvas之后,突发奇想,使用canvas api 绘制一个时钟。话不多说,先上图:为了突出各个元素,使用不同的颜色表示,虽然有点花花绿绿,但我觉得还挺ok。画图之前,首先我们需要分析一下时钟的构造:表盘(刻度,圆盘)+指针(时针,分针,秒针)首先准备好画布 <canvas id="mycanvas" width="500" height="500px"></canvas>...

学习完canvas之后,突发奇想,使用canvas api 绘制一个时钟。

话不多说,先上图:

为了突出各个元素,使用不同的颜色表示,虽然有点花花绿绿,但我觉得还挺ok。

画图之前,首先我们需要分析一下时钟的构造:表盘(刻度,圆盘)+指针(时针,分针,秒针)

首先准备好画布


      <canvas id="mycanvas" width="500" height="500px"></canvas>


然后初始化画布


     //获取画布元素

      var canvas = document.getElementById("mycanvas");

      //画布尺寸

      var W = canvas.clientWidth;

      var H = canvas.clientHeight;

      //半径

      var r = 200;

      canvas.style.background = "#ccc";

      //获取上下文

      var ctx = canvas.getContext("2d");


第一步,绘制表盘

我们利用 arc(x,y.radius,起始弧度,结束弧度,旋转方向) 绘制圆弧

x,y --- 圆心坐标
radius --- 半径
弧度和角度的关系 --- 弧度 = 角度*Math.PI/180

旋转方向 --- true:逆时针;false:顺时针(默认)


 //表盘外径

 ctx.beginPath();

      ctx.lineWidth = 10;

      ctx.arc(W / 2H / 2r02 * Math.PI);

      ctx.stroke();

      ctx.fillStyle="#fff";

      ctx.closePath();

      ctx.fill();

如图:

通过封装函数剔除重复代码

 //刻度封装函数

      function getScaleMark(radlineWidth) {

        ctx.save();

        ctx.beginPath();

        for (var i = 0i < 60i++) {

          ctx.lineWidth = lineWidth;

          ctx.moveTo(W / 2H / 2);

          ctx.arc(W / 2,H / 2,r,(rad * i * Math.PI/ 180,(rad * (i + 1* Math.PI/ 180

          );

        }

        ctx.closePath();

        ctx.stroke();

      }

 //小刻度

      getScaleMark(6,2);

如图:

  //大刻度

      getScaleMark(30,5);

如图:

为了显示出所需刻度,需要绘制两个圆覆盖掉中间区域

 //圆盘小刻度截断

      ctx.save();

      ctx.beginPath();

      ctx.arc(W/2,H/2,0.95*r,0,2*Math.PI);

      ctx.fillStyle='#ffffff'

      ctx.closePath();

      ctx.fill();

如图:

//圆盘大刻度截断

 ctx.beginPath();

      ctx.arc(W/2,H/2,0.9*r,0,2*Math.PI);

      ctx.fillStyle='#ffffff'

      ctx.closePath();

      ctx.fill();

如图:

第二步,绘制指针

    首先,指针是绕着圆心旋转,利用moveTo以圆心为起点,绘制指针

    

//秒

      ctx.save();

      ctx.beginPath();

      ctx.lineWidth = 3

      ctx.strokeStyle='#f0f'

      ctx.moveTo(W/2H/2);

      ctx.arc(W/2H/20.85 * r00);

      ctx.closePath();

      ctx.stroke();

      //分

      ctx.save();

      ctx.beginPath();

      ctx.lineWidth = 5;

      ctx.strokeStyle='#fc0' 

      ctx.moveTo(W/2H/2);

      ctx.arc(W/2H/20.7 * r-90*Math.PI/180-90*Math.PI/180);

      ctx.closePath();

      ctx.stroke();

      //时针

      ctx.save();

      ctx.beginPath();

      ctx.lineWidth = 7 

      ctx.strokeStyle='#f00'

      ctx.moveTo(W/2H/2);

      ctx.arc(W/2H/20.5 * r-70*Math.PI/180-70*Math.PI/180);

      ctx.closePath();

      ctx.stroke();

      //圆心

      ctx.save();

      ctx.beginPath();

      ctx.arc(W/2,H/2,0.03*r,0,2*Math.PI);

      ctx.fillStyle="#000"

      ctx.closePath();

      ctx.fill();   

如图:


最后,我们需要燃时钟动起来,运用setInterval();

      ...

      //获取当前系统时间

      var nowDate = new Date();

      //小时

      var hh = nowDate.getHours()>12?nowDate.getHours()-12:nowDate.getHours();

      var mm = nowDate.getMinutes();

      var ss = nowDate.getSeconds();

      //相应刻度

      var hhVal = (-90+hh*30+mm/2)*Math.PI/180;

      var mmVal = (-90+mm*6)*Math.PI/180;

      var ssVal = (-90+ss*6)*Math.PI/180;

      //秒

      ctx.save();

      ctx.beginPath();

      ctx.lineWidth = 3

      ctx.strokeStyle='#f0f'

      ctx.moveTo(W/2H/2);

      ctx.arc(W/2H/20.85 * rssValssVal);

      ctx.closePath();

      ctx.stroke();

      //分

      ctx.save();

      ctx.beginPath();

      ctx.lineWidth = 5;

      ctx.strokeStyle='#fc0' 

      ctx.moveTo(W/2H/2);

      ctx.arc(W/2H/20.7 * rmmValmmVal);

      ctx.closePath();

      ctx.stroke();

      //时针

      ctx.save();

      ctx.beginPath();

      ctx.lineWidth = 7 

      ctx.strokeStyle='#f00'

      ctx.moveTo(W/2H/2);

      ctx.arc(W/2H/20.5 * rhhValhhVal);

      ctx.closePath();

      ctx.stroke();

       ...

  setInterval(toDraw,1000);

完成之后,时钟就能动起来了。


完整代码如下:

HTML:

<canvas id="mycanvas" width="500" height="500px"></canvas>

Javascript:

  //获取画布元素

      var canvas = document.getElementById("mycanvas");

      //画布尺寸

      var W = canvas.clientWidth;

      var H = canvas.clientHeight;

      //半径

      var r = 200;

      canvas.style.background = "#ccc";

      //创建2d画笔

      var ctx = canvas.getContext("2d");  

      function toDraw(){

      ctx.save();

      ctx.clearRect(0,0,W,H);

      //表盘外径

      ctx.beginPath();

      ctx.strokeStyle = "#00ffff";

      ctx.lineWidth = 10;

      ctx.arc(W / 2H / 2r02 * Math.PI);

      ctx.stroke();

      ctx.fillStyle="#fff";

      ctx.closePath();

      ctx.fill();

      //小刻度

      getScaleMark(6,2);

      //圆盘刻度截断

      ctx.save();

      ctx.beginPath();

      ctx.arc(W/2,H/2,0.95*r,0,2*Math.PI);

      ctx.fillStyle='#ffffff'

      ctx.closePath();

      ctx.fill();

      //时钟刻度

      getScaleMark(30,5);

      //圆盘刻度截断

      ctx.beginPath();

      ctx.arc(W/2,H/2,0.9*r,0,2*Math.PI);

      ctx.fillStyle='#ffffff'

      ctx.closePath();

      ctx.fill();

      ctx.save();

      //获取当前系统时间

      var nowDate = new Date();

      //小时

      var hh = nowDate.getHours()>12?nowDate.getHours()-12:nowDate.getHours();

      var mm = nowDate.getMinutes();

      var ss = nowDate.getSeconds();

      //相应刻度

      var hhVal = (-90+hh*30+mm/2)*Math.PI/180;

      var mmVal = (-90+mm*6)*Math.PI/180;

      var ssVal = (-90+ss*6)*Math.PI/180;

      //秒

      ctx.save();

      ctx.beginPath();

      ctx.lineWidth = 3

      ctx.strokeStyle='#f0f'

      ctx.moveTo(W/2H/2);

      ctx.arc(W/2H/20.85 * rssValssVal);

      ctx.closePath();

      ctx.stroke();

      //分

      ctx.save();

      ctx.beginPath();

      ctx.lineWidth = 5;

      ctx.strokeStyle='#fc0' 

      ctx.moveTo(W/2H/2);

      ctx.arc(W/2H/20.7 * rmmValmmVal);

      ctx.closePath();

      ctx.stroke();

      //时针

      ctx.save();

      ctx.beginPath();

      ctx.lineWidth = 7 

      ctx.strokeStyle='#f00'

      ctx.moveTo(W/2H/2);

      ctx.arc(W/2H/20.5 * rhhValhhVal);

      ctx.closePath();

      ctx.stroke();

      //圆心

      ctx.save();

      ctx.beginPath();

      ctx.arc(W/2,H/2,0.03*r,0,2*Math.PI);

      ctx.fillStyle="#000"

      ctx.closePath();

      ctx.fill();   

      }

      setInterval(toDraw,1000)

      //刻度封装函数

      function getScaleMark(radlineWidth) {

        ctx.save();

        ctx.beginPath();

        for (var i = 0i < 60i++) {

          ctx.lineWidth = lineWidth;

          ctx.moveTo(W / 2H / 2);

          ctx.arc(W / 2,H / 2,r,(rad * i * Math.PI/ 180,(rad * (i + 1* Math.PI/ 180);

        }

        ctx.closePath();

        ctx.stroke();

      }



【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。