阅读 688

[Canvas] JS 绘制真实时钟

导读

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

案例需要掌握的

  • canvas基本使用,arc、fillRect等

  • ES6 class语法

  • 一些三角函数知识

效果如图所示


github

分析

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


逻辑结构

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

  • 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真实时钟


关注下面的标签,发现更多相似文章
评论