首页 > 技术文章 > canvas动态时钟

feitan 2016-01-26 14:03 原文

利用canvas可以绘制一些复杂的效果动画,这里展示了如何绘制一个动态的时钟,主要运用canvas的坐标变换、坐标状态的保存和恢复。思路来自《HTML5基础开发教程》范立峰,感谢给我知识的学校图书馆和本书作者。

效果是这样的:

参考代码:

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="utf-8">
 5     <title>clock</title>
 6     <script type="text/javascript">
 7 
 8         var slen = 70, mlen = 65, hlen = 45,    //指针长度
 9             swidth = 2, mwidth = 3, hwidth = 4, //指针宽度
10             s = 0, m = 0, h = 0;                //时分秒数
11 
12         function draw(){
13             var canvas = document.getElementById("canvas");
14             var context = canvas.getContext("2d");
15             
16             context.beginPath();
17             context.arc(200,150,4,0,Math.PI*2,true);    //画表盘中心
18             context.fill();   //画实心的
19             context.closePath();
20             
21             context.beginPath();  
22             context.arc(200,150,100,0,Math.PI*2,true);  //画表盘外围
23             context.stroke();  //画空心的
24             context.closePath();
25             
26             context.beginPath();                        //画刻度
27             context.translate(200,150);                 //平移到圆心
28             context.rotate(-Math.PI/2);                 //逆时针旋转至12点
29             context.save();
30             for (var i = 0 ; i < 60; i++) {
31                 if (i%5 == 0){
32                     context.fillRect(80,0,20,5); //整点刻度线
33                 }else{
34                     context.fillRect(90,0,10,2); //分钟刻度线
35                 }
36                 context.rotate(Math.PI/30);
37             }
38             context.closePath();
39 
40             setInterval(refresh,1000,context);  //每一秒刷新一次 IE不支持带参数
41         }
42 
43         function refresh(context){
44             //var canvas = document.getElementById("canvas");  //IE下方式
45             //var context = canvas.getContext("2d");
46             context.restore();
47             context.save();
48             context.rotate(s*Math.PI/30);     //擦秒针
49             context.clearRect(5,-1,slen+1,swidth+2);
50 
51             context.restore();
52             context.save();
53             context.rotate(m*Math.PI/30);     //擦分针
54             context.clearRect(5,-1,mlen+1,mwidth+2); 
55 
56             context.restore();
57             context.save();
58             context.rotate(h*Math.PI/6);      //擦时针
59             context.clearRect(5,-1,hlen+1,hwidth+2);
60 
61             var time = new Date();            //获取时间
62             s = time.getSeconds();
63             m = time.getMinutes();
64             h = time.getHours();
65 
66             context.restore();
67             context.save();
68             context.rotate(s*Math.PI/30);    //画秒针
69             context.fillRect(5,0,slen,swidth);
70 
71             context.restore();
72             context.save();
73             context.rotate(m*Math.PI/30);    //画分针
74             context.fillRect(5,0,mlen,mwidth);
75 
76             context.restore();
77             context.save();
78             context.rotate(h*Math.PI/6);     //画时针
79             context.fillRect(5,0,hlen,hwidth);
80 
81         }
82     </script>
83 <head>
84 <body onload="draw()">
85 <fieldset>
86     <legend>clock</legend>
87     <canvas id="canvas" width="400px" height="300px"></canvas>
88 </fieldset>
89 </body>
90 </html>

涉及到的canvas用法可参考我的《canvas绘画常用方法》http://www.cnblogs.com/feitan/p/5137325.html

需要补充提到的是save()和restore()两个方法。save()将当前坐标设置(而不是画布呈现的效果)保存到栈中,每调用restore()时,保存坐标状态的栈顶取出最后一次save()的状态,恢复到当前坐标状态上。代码中,总是以圆心为坐标起点,以x水平线指向12点位置的状态为原始状态,每重画指针时就把当前状态恢复到原始状态,并再save为了下次再使用。

推荐阅读