这个案例是逛帖子发现的一个面试题,原题是让用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,绘制圆盘的方法其实很简单,因为绘制的圆较多,能够封装这样一个专门绘制圆盘的函数
// 绘制圆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()
}
复制代码
这里用到一些三角函数的知识,掌握这些知识看图便可明白,理解后,翻译成代码就容易的多了,只需计算出对应的x、y坐标,调用前面封装的drawArc
方法便可。
// 绘制刻度
drawPoint() {
for (let i = 0; i < 60; i++) {
let x, y = ...
this.drawArc(...)
}
}复制代码
小时刻度共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复制代码
与drawPane相同就不赘述了
有个地方还不满意,开始的动画是定义一个计时器实现的,由于不在开始设计构思内,写完后临时添加的(为了显示绘制过程),感受有点low,还有想好怎么更好的实现这个功能,有知道的欢迎留言探讨
但愿看完本篇文章能对你有帮助
文中若有错误,欢迎在评论区指正,若是这篇文章帮助到了你,欢迎点赞和关注。
想阅读更多优质文章、可关注个人github博客,你的star✨、点赞和关注是我持续创做的动力
详细代码参考,canvas真实时钟