[Canvas] JS 绘制真实时钟

导读

这个案例是逛帖子发现的一个面试题,原题是让用html元素完成,当时刚好是在作关于canvas方面的东西,想着那样太简单了,就用canvas来实现一下,挑战一下本身。javascript

案例须要掌握的html

  • canvas基本使用,arc、fillRect等java

  • ES6 class语法git

  • 一些三角函数知识github

效果如图所示面试


githubcanvas

分析

这个图形较为简单,都是比较规整的图形,一图胜千言,大概须要写下面几个功能。或许到这里,聪明的你已经能够完成这个案例了。api


逻辑结构

这里理一下结构,我喜欢使用下面的结构bash

  • constructor 处理实例化对象时传入的参数函数

  • init 初始化默认参数,减小constructor的臃肿

  • render 集中处理渲染函数

  • update 集中处理更新的数据

class Scene {
  constructor() { ... }
  init() { ... }
  render() { ... }
  update() { ... }
  // other method...
}复制代码

实现

圆盘 drawPane

外圆盘绘制 drawPane,绘制圆盘的方法其实很简单,因为绘制的圆较多,能够封装这样一个专门绘制圆盘的函数

// 绘制圆apiarc(x, y, r, 0, 2*PI)
// 依次绘制3个圆

drawArc(200, 200, 200, '#ff1515')
drawArc(200, 200, 190, '#b70d0d')
drawArc(200, 200, 180, '#ffffff')

drawArc(x, y, r, color='#000') {
  ctx.beginPath()
  ctx.fillStyle = color
  ctx.arc(x, y, r, 0, 6.28)
  ctx.fill()  
}
复制代码

绘制分钟刻度 drawPoint

这里用到一些三角函数的知识,掌握这些知识看图便可明白,理解后,翻译成代码就容易的多了,只需计算出对应的x、y坐标,调用前面封装的drawArc方法便可。

// 绘制刻度
drawPoint() {
  for (let i = 0; i < 60; i++) {
    let x, y = ...
    this.drawArc(...)
  }
}复制代码

绘制小时刻度 drawRect

小时刻度共12个,圆环共360度,每刻度360/12,小时刻度看似和分钟刻度差很少,其实难度仍是比较大的,由于默认的旋转中心在(0,0),每次绘制须要手动的修改旋转中心。

注意点

  • 调用Canvas的平移、放缩、旋转、错切、裁剪等操做时通常要使用save、restore来保存和重置状态

  • rotate的角度要加90度

drawScale() {
	ctx.save()
  // ...
  ctx.restore()
}复制代码

绘制指针

有了前面的基础,绘制指针就会简单不少,因为绘制时分秒指针类似,这里把它抽出来,作成单独的函数

drawScale(x, y, w, h, angle, color) {...}复制代码

计算指针的角度,这个看似难,其实很是简单

举个例子

  • 秒针、分针共60刻度,均分360度 -> 360/60

  • 时针共12刻度,均分360度 -> 360/12

这样作仍是不够的,还有考虑秒对分的影响、秒分对时的影响,因此能够这样换算

// 偏移角度 = 折算的当前时刻数 * 单位角度​

sec * 360/60
(min + sec/60) * 360/60
(hour + min/60 + sec/60/60) * 360/12复制代码

drawPane2

与drawPane相同就不赘述了

探讨

有个地方还不满意,开始的动画是定义一个计时器实现的,由于不在开始设计构思内,写完后临时添加的(为了显示绘制过程),感受有点low,还有想好怎么更好的实现这个功能,有知道的欢迎留言探讨


小结

但愿看完本篇文章能对你有帮助

文中若有错误,欢迎在评论区指正,若是这篇文章帮助到了你,欢迎点赞和关注。

想阅读更多优质文章、可关注个人github博客,你的star✨、点赞和关注是我持续创做的动力

详细代码参考,canvas真实时钟

相关文章
相关标签/搜索