canvas点阵实现粒子化时间显示

粒子化数字

三维数组
首先定义一个7x10的三维数组digit,通过1和0的位置组合来储存数字0-9和冒号的信息,能看出1的集合形成了1-9和冒号的形状
格子系统
画小圆要用到canvas的arc()函数,需要的参数是圆心x坐标,圆心y坐标,圆的半径,0,2*Math.PI
假设要显示的数字的大格子的左上角坐标为(x,y),小圆半径是R,为了和其他小圆留有一定的空隙,所以小格子的边长多加1px,为R+1,那么第(i,j)个小圆的圆心位置就是:


CenterX:x+j2(R+1)+(R+1)
CenterY:y+i2(R+1)+(R+1)

圆心坐标
那么我们定义一个renderDigit函数,传入参数x,y,num,ctx,设置fillStyle颜色,用两次循环来遍历数组的行列,如果digit[i][j]的值为1,就在那个位置画一个小圆
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function renderDigit(x, y, num, ctx) {
ctx.fillStyle = "rgb(0,102,153)";
for (var i = 0; i < digit[num].length; i++)
for (var j = 0; j < digit[num][i].length; j++) {
if (digit[num][i][j] == 1) {
ctx.beginPath();
ctx.arc(x + j * 2 * (RADIUS + 1) + (RADIUS + 1), y + i * 2 * (RADIUS + 1) + (RADIUS + 1), RADIUS, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
}
}
}

数字和冒号都可以调用这个renderDigit函数画出来,只是x和y的位置不同,所以我们再定义一个render函数,传入ctx,定义hours,minites,seconds变量,为了让第一个数字位置在合适的位置,设置这几个全局变量,MARGINTOP和MARGINLEFT,还有小球半径RADIUS,在传入x的时候为了和左边的数字留有间隙,所以多加了1个(RADIUS+1),也就是2x7x(RADIUS+1),需要注意的是冒号不同隔那么远,只需要隔9x(RADIUS),同时因为绘制不同数字是把数字拆分来绘制的,所以在传入num的时候是需要拆分十位和个位数的,冒号就直接传个10就行,因为在三位数组里冒号是第11个,而数组是从0开始的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function render(ctx) {
var hours = 12;
var minites = 23
var seconds = 34;
renderDigit(MARGINLEFT, MARGINTOP, parseInt(hours / 10), ctx);
renderDigit(MARGINLEFT + 15(RADIUS + 1), MARGINTOP, parseInt(hours % 10), ctx);
renderDigit(MARGINLEFT + 30(RADIUS + 1), MARGINTOP, 10, ctx);
renderDigit(MARGINLEFT + 39(RADIUS + 1), MARGINTOP, parseInt(minites / 10), ctx);
renderDigit(MARGINLEFT + 54(RADIUS + 1), MARGINTOP, parseInt(minites % 10), ctx);
renderDigit(MARGINLEFT + 69(RADIUS + 1), MARGINTOP, 10, ctx);
renderDigit(MARGINLEFT + 78(RADIUS + 1), MARGINTOP, parseInt(seconds / 10), ctx);
renderDigit(MARGINLEFT + 93 * (RADIUS + 1), MARGINTOP, parseInt(seconds % 10), ctx);
}

然后直接调用render函数并且传入ctx,就能画出这些粒子化的数字了
但是上面的hours,minites,seconds都是写死的,如果要用来显示时间的话,要用new Date()来获取具体时间,这样一个粒子化的时钟就做好了

demo:戳我