网上会看到很多绘制的时钟,看代码也是云里雾里,自学了下Canvas,觉得不难,就自己做了一个。
先看一下截图:
比较简陋,但是该有的都有了,样式只加了个阴影。
html代码就不贴了,就一个canvas。
<canvas id="clock" width="300" height="300"></canvas>
下面是JS实现:
1、取得上下文:
var clock = document.getElementById('clock'), context = clock.getContext('2d');
2、为了方便,先把绘制上下文做一下变换。
移动之前原点在左上角,现在把他移动到中心处,这里我们画上钟表中心。
平移之后,0度在下午三点钟方向,我们把他旋转到12点钟方向,这样时间和角度就是统一的了。
context.translate(150, 150); context.rotate(-Math.PI / 2);
3、首先绘制个大圆,作为钟表的外轮廓。
因为在上面做了平移,所以圆心就是(0,0),然后最后一个参数是false,表示按顺时针方向绘制,因为旋转过,所以就是从12点方向,顺时针方向绘制了个圆,正好和表的走法是一致的,
这样后面处理起来就方便的多。
context.beginPath(); context.arc(0, 0, 130, 0, Math.PI * 2, false); context.closePath(); context.stroke();
4、绘制中心的点
context.beginPath(); context.arc(0, 0, 5, 0, Math.PI * 2, false); context.closePath(); context.fill();
5、绘制小时刻度,12个,角度间隔是30度,这里需要弧度。
x和y的确定需要画图看一下,其实不难。
x也就是半径的sin值,y是cos值。
var angle = 0; for(var i = 0; i < 12; i++) { angle += Math.PI / 6; context.beginPath(); var x = radius * Math.cos(angle), y = radius * Math.sin(angle); var dx = 10 * Math.cos(angle); dy = 10 * Math.sin(angle); context.moveTo(x, y); context.lineTo(x - dx, y - dy); context.stroke(); context.closePath(); }
6、绘制分秒的刻度,60个,和上面一样。
var angle = 0; for(var i = 0; i < 60; i++) { angle += Math.PI / 30; context.beginPath(); var x = radius * Math.cos(angle), y = radius * Math.sin(angle); var dx = 3 * Math.cos(angle); dy = 3 * Math.sin(angle); context.moveTo(x, y); context.lineTo(x - dx, y - dy); context.stroke(); context.closePath(); }
7、接下来就是三根针了,首先获得当前的时间。
小时如果大于12了,我们要减掉12,同时我们会发现,时针不是一下子跳跃的,他也是慢慢的移动到下一个小时的,所以要取得他的准确小时数。
var now = new Date(), hour = now.getHours(), minute = now.getMinutes(), second = now.getSeconds(); hour = hour >= 12 ? hour - 12 : hour; hour += minute / 60;
8、绘制秒针,可以像上面那样的画个图看看。110是长度,时针和分针的绘制方法是一样的。
var xS = 110 * Math.cos(Math.PI / 30 * second), yS = 110 * Math.sin(Math.PI / 30 * second); context.beginPath(); context.moveTo(0, 0); context.lineTo(xS, yS); context.stroke();
9、动画
动画就是不停的擦除更新,首先在最开始就擦除。
context.clearRect(-150, -150, 300, 300);
然后使用setTimeout。假设之前的都放在drawClock函数里,那么就可以每个一秒就调用自身。
setTimeout(function() { drawClock(); }, 1000);
这样基本就可以了,然后可以简单的把重复的地方封装一下。