Canvas 示例:时钟
先来看下最终效果图:
星期天趁空隙实现了个简单的一个时钟,下面回顾下其实现原理,和遇到的问题,对 H5 这块还是个菜鸟,只有不断通过练习去熟悉了。
设计
凡是从构思开始,而不是盲目的去实现代码。
设计图:
从上图中该时钟分为几个部分
- 画布,背景蓝色部分;
- 第一个圆:时钟边框,最外层 8 个像素的宽边框;
- 第二个圆:点圆圈,代表着时间划分,每两个点之间代表 12 分钟(60 / 5 = 12);
- 第三个圆:数字圆,上面依次显示
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
数字,代表小时数; - 三个线条,分别是:时针(
r * 0.5
),分针(r * 0.75
),秒针(r * 0.85
);
实现
根据上面的设计图和部位划分,来逐步实现 UI。
时钟模块文件:clock.js
// clock.js
function Clock(canvas) {
this.canvas = canvas;
this.width = this.canvas.offsetWidth;
this.height = this.canvas.offsetHeight;
this.rem = this.width / 200;
this.ctx = this.canvas.getContext('2d');
this.r = this.width / 2;
this.digits = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
this.dotCount = 60;
this.cellRad = 2 * Math.PI / this.digits.length;
}
上面定义了时钟构造函数,参数是一个画布对象,成员包含
this.canvas
:缓存画布对象;this.width
:画布的实际宽度,这里选择让其变成成员,原因是后面会使用到画布宽高,这里创建时进行缓存,避免后面使用时才去计算;this.height
:画布实际高度,同上;this.rem
:相对画布的比例,参考值:200px
,这个成员可以应对画布的大小缩放情况,使其他元素相应的做出响应;this.ctx
:画布上下文;this.r
:外圆的半径;this.digits
:小时数字数组,用来显示在时钟表盘上的数字;this.dotCount
:定义时钟表盘上的点的数量;this.cellRad
:小时与小时数字之间的弧度,这里其实就是30 度
角的弧度;
原型函数列表:(事先定义好可能需要的函数)
Clock.prototype._context
:获取画布上下文,实际上就是得到this.ctx
成员;Clock.prototype.drawBg
:绘制背景,也就是最外圈的时钟的边框圆;Clock.prototype.drawDigits
:绘制数字,根据单位角度 * 小时数字索引
,将数字绘制到相应的位置上,这里需要注意的是画布的起始位置默认是水平向右的位置开始,也就是 3 点钟方向;Clock.prototype.drawDot
:绘制点,分割成 60 个点,同样是根据每两个点之间的弧度来实现;Clock.prototype.drawHourHand
:绘制小时时针线;Clock.prototype.drawMinuteHand
:绘制分钟时针线;Clock.prototype.drawSecondHand
:绘制秒钟时针线;Clock.prototype._drawHand
:绘制时针线的统一函数,因为不管是小时,分钟,秒钟也好,最终都是画线条,因此有其共同点,不同点在于线的粗细,长短,和弧度,因此可统一函数接口,将不同点作为参数传入;Clock.p