js实现时钟

效果图

html代码

js代码

 

  1. (function(window){  
  2.     var proto = {  
  3.         init: function(e){  
  4.             this.before(e);  
  5.             this.start();  
  6.         },  
  7.         before: function(e){  
  8.             this.canvas = e.canvas;  
  9.         },  
  10.         start: function(){  
  11.             var This = this;  
  12.             var mycanvas = this.canvas;  
  13.             var width = mycanvas.width;  
  14.             var height = mycanvas.height;  
  15.             var myc = mycanvas.getContext("2d");  
  16.             var coords = [];  
  17.             setcoords();  
  18.             draw();  
  19.             setInterval(draw,1000);  
  20.             function draw(){  
  21.                 //绘制点  
  22.                 myc.clearRect(0, 0, width, height);  
  23.                 myc.lineCap = 'round';  
  24.                 myc.beginPath();  
  25.                 myc.fillStyle = "#000";  
  26.                 myc.arc(width/2, height/2, height/2, 0, 2*Math.PI);  
  27.                 myc.fill();  
  28.                 myc.beginPath();  
  29.                 myc.fillStyle = "#fff";  
  30.                 myc.arc(width/2, height/2, height/2*0.9, 0, 2*Math.PI);  
  31.                 myc.fill();  
  32.                 for( var i=0; i<coords.length; i++ ){  
  33.                     myc.beginPath();  
  34.                     var tmp = coords[i];  
  35.                     myc.moveTo(tmp[0], tmp[1]);  
  36.                     myc.lineTo(tmp[2], tmp[3]);  
  37.                     myc.strokeStyle = "#000";  
  38.                     myc.lineWidth = tmp[4]?width*0.02:width*0.01;  
  39.                     myc.stroke();  
  40.                 };  
  41.                 //绘制指针  
  42.                 var tmp = getPoint();  
  43.                 for( var i=0, l=tmp.length; i<l; i++ ){  
  44.                     myc.beginPath();  
  45.                     myc.moveTo(tmp[i][0],tmp[i][1]);  
  46.                     myc.lineTo(tmp[i][2],tmp[i][3]);  
  47.                     if( i == 0 ){  
  48.                         myc.lineWidth = width*0.03;  
  49.                     }else if( i==1 ){  
  50.                         myc.lineWidth = width*0.02;  
  51.                     }else if( i==2 ){  
  52.                         myc.lineWidth = width*0.01;  
  53.                     }  
  54.                     myc.strokeStyle = "#000";  
  55.                     myc.shadowBlur = 4;  
  56.                     myc.shadowColor = "#fff";  
  57.                     myc.stroke();  
  58.                     //指针圆  
  59.                     if( i==2 ){  
  60.                         myc.beginPath();  
  61.                         var x = tmp[i][4];  
  62.                         var y = tmp[i][5];  
  63.                         myc.arc(x, y, width*0.03, 0 , 2*Math.PI);  
  64.                         myc.fillStyle = "#fff";  
  65.                         myc.fill();  
  66.                         myc.strokeStyle = "#000";  
  67.                         myc.stroke();  
  68.                     };  
  69.                 };  
  70.                 //绘制中心圆  
  71.                 myc.beginPath();  
  72.                 myc.arc(width/2, height/2, width*0.03/2, 0 ,2*Math.PI);  
  73.                 myc.fillStyle = "#fff";  
  74.                 myc.fill();  
  75.                 myc.beginPath();  
  76.                 myc.arc(width/2, height/2, width*0.018/2, 0 ,2*Math.PI);  
  77.                 myc.fillStyle = "#000";  
  78.                 myc.fill();  
  79.                 myc.beginPath();  
  80.                 myc.arc(width/2, height/2, width*0.005/2, 0 ,2*Math.PI);  
  81.                 myc.fillStyle = "#fff";  
  82.                 myc.fill();  
  83.             };  
  84.             function setcoords(){  
  85.                 var r1 = height/2*0.85;  
  86.                 var r2 = height/2*0.8;  
  87.                 var r3 = height/2*0.75;  
  88.                 for( var i=1; i<61; i++ ){  
  89.                     var angle = i*6*Math.PI/180;  
  90.                     var x1 = width/2 + r1*Math.sin(angle);  
  91.                     var y1 = height/2 - r1*Math.cos(angle);  
  92.                     var x2 = width/2 + r2*Math.sin(angle);  
  93.                     var y2 = height/2 - r2*Math.cos(angle);  
  94.                     var tmp = [x1, y1, x2, y2];  
  95.                     if( i%5 == 0 ){  
  96.                         x2 = width/2 + r3*Math.sin(angle);  
  97.                         y2 = height/2 - r3*Math.cos(angle);  
  98.                         tmp.splice(2,1,x2);  
  99.                         tmp.splice(3,1,y2);  
  100.                         tmp.push(1);  
  101.                     };  
  102.                     coords.push(tmp);  
  103.                 };  
  104.             };  
  105.             function getPoint(){  
  106.                 var angle = getTimeAngle();  
  107.                 var bLength = 0.05*width;  
  108.                 var hX1 = width/2 + bLength*Math.sin( (angle.h+180)*Math.PI/180 );  
  109.                 var hY1 = width/2 - bLength*Math.cos( (angle.h+180)*Math.PI/180 );  
  110.                 var hX2 = width/2 + 0.15*width*Math.sin( angle.h*Math.PI/180 );  
  111.                 var hY2 = height/2 - 0.15*width*Math.cos( angle.h*Math.PI/180 );  
  112.                 var mX1 = width/2 + bLength*Math.sin( (angle.m+180)*Math.PI/180 );  
  113.                 var mY1 = width/2 - bLength*Math.cos( (angle.m+180)*Math.PI/180 );  
  114.                 var mX2 = width/2 + 0.28*width*Math.sin( angle.m*Math.PI/180 );  
  115.                 var mY2 = height/2 - 0.28*width*Math.cos( angle.m*Math.PI/180 );  
  116.                 var sX1 = width/2 + bLength*Math.sin( (angle.s+180)*Math.PI/180 );  
  117.                 var sY1 = width/2 - bLength*Math.cos( (angle.s+180)*Math.PI/180 );  
  118.                 var sX2 = width/2 + 0.35*width*Math.sin( angle.s*Math.PI/180 );  
  119.                 var sY2 = height/2 - 0.35*width*Math.cos( angle.s*Math.PI/180 );  
  120.                 var rX1 = width/2 + 0.28*width*Math.sin( angle.s*Math.PI/180 );  
  121.                 var rY1 = height/2 - 0.28*width*Math.cos( angle.s*Math.PI/180 );  
  122.                 return [  
  123.                     [hX1, hY1, hX2, hY2],  
  124.                     [mX1, mY1, mX2, mY2],  
  125.                     [sX1, sY1, sX2, sY2, rX1, rY1]  
  126.                 ];  
  127.             };  
  128.             function getTimeAngle(){  
  129.                 var now = new Date();  
  130.                 var s = now.getSeconds();  
  131.                 var m = now.getMinutes() + s/60;  
  132.                 var h = (now.getHours()>=12?now.getHours()-12:now.getHours()) + m/60;  
  133.                 return {  
  134.                     h: h*30,  
  135.                     m: m*6,  
  136.                     s: s*6  
  137.                 };  
  138.             };  
  139.         }  
  140.     };  
  141.     function Clock(e){  
  142.         this.init(e)  
  143.     };  
  144.     Clock.prototype = proto;  
  145.     Clock.prototype.constructor = Clock;  
  146.     window.Clock = Clock;  
  147. })(window);  
(function(window){
	var proto = {
		init: function(e){
			this.before(e);
			this.start();
		},
		before: function(e){
			this.canvas = e.canvas;
		},
		start: function(){
			var This = this;
			var mycanvas = this.canvas;
			var width = mycanvas.width;
			var height = mycanvas.height;
			var myc = mycanvas.getContext("2d");
			var coords = [];
			setcoords();
			draw();
			setInterval(draw,1000);
			function draw(){
				//绘制点
				myc.clearRect(0, 0, width, height);
				myc.lineCap = 'round';
				myc.beginPath();
				myc.fillStyle = "#000";
				myc.arc(width/2, height/2, height/2, 0, 2*Math.PI);
				myc.fill();
				myc.beginPath();
				myc.fillStyle = "#fff";
				myc.arc(width/2, height/2, height/2*0.9, 0, 2*Math.PI);
				myc.fill();
				for( var i=0; i<coords.length; i++ ){
					myc.beginPath();
					var tmp = coords[i];
					myc.moveTo(tmp[0], tmp[1]);
					myc.lineTo(tmp[2], tmp[3]);
					myc.strokeStyle = "#000";
					myc.lineWidth = tmp[4]?width*0.02:width*0.01;
					myc.stroke();
				};
				//绘制指针
				var tmp = getPoint();
				for( var i=0, l=tmp.length; i<l; i++ ){
					myc.beginPath();
					myc.moveTo(tmp[i][0],tmp[i][1]);
					myc.lineTo(tmp[i][2],tmp[i][3]);
					if( i == 0 ){
						myc.lineWidth = width*0.03;
					}else if( i==1 ){
						myc.lineWidth = width*0.02;
					}else if( i==2 ){
						myc.lineWidth = width*0.01;
					}
					myc.strokeStyle = "#000";
					myc.shadowBlur = 4;
					myc.shadowColor = "#fff";
					myc.stroke();
					//指针圆
					if( i==2 ){
						myc.beginPath();
						var x = tmp[i][4];
						var y = tmp[i][5];
						myc.arc(x, y, width*0.03, 0 , 2*Math.PI);
						myc.fillStyle = "#fff";
						myc.fill();
						myc.strokeStyle = "#000";
						myc.stroke();
					};
				};
				//绘制中心圆
				myc.beginPath();
				myc.arc(width/2, height/2, width*0.03/2, 0 ,2*Math.PI);
				myc.fillStyle = "#fff";
				myc.fill();
				myc.beginPath();
				myc.arc(width/2, height/2, width*0.018/2, 0 ,2*Math.PI);
				myc.fillStyle = "#000";
				myc.fill();
				myc.beginPath();
				myc.arc(width/2, height/2, width*0.005/2, 0 ,2*Math.PI);
				myc.fillStyle = "#fff";
				myc.fill();
			};
			function setcoords(){
				var r1 = height/2*0.85;
				var r2 = height/2*0.8;
				var r3 = height/2*0.75;
				for( var i=1; i<61; i++ ){
					var angle = i*6*Math.PI/180;
					var x1 = width/2 + r1*Math.sin(angle);
					var y1 = height/2 - r1*Math.cos(angle);
					var x2 = width/2 + r2*Math.sin(angle);
					var y2 = height/2 - r2*Math.cos(angle);
					var tmp = [x1, y1, x2, y2];
					if( i%5 == 0 ){
						x2 = width/2 + r3*Math.sin(angle);
						y2 = height/2 - r3*Math.cos(angle);
						tmp.splice(2,1,x2);
						tmp.splice(3,1,y2);
						tmp.push(1);
					};
					coords.push(tmp);
				};
			};
			function getPoint(){
				var angle = getTimeAngle();
				var bLength = 0.05*width;
				var hX1 = width/2 + bLength*Math.sin( (angle.h+180)*Math.PI/180 );
				var hY1 = width/2 - bLength*Math.cos( (angle.h+180)*Math.PI/180 );
				var hX2 = width/2 + 0.15*width*Math.sin( angle.h*Math.PI/180 );
				var hY2 = height/2 - 0.15*width*Math.cos( angle.h*Math.PI/180 );
				var mX1 = width/2 + bLength*Math.sin( (angle.m+180)*Math.PI/180 );
				var mY1 = width/2 - bLength*Math.cos( (angle.m+180)*Math.PI/180 );
				var mX2 = width/2 + 0.28*width*Math.sin( angle.m*Math.PI/180 );
				var mY2 = height/2 - 0.28*width*Math.cos( angle.m*Math.PI/180 );
				var sX1 = width/2 + bLength*Math.sin( (angle.s+180)*Math.PI/180 );
				var sY1 = width/2 - bLength*Math.cos( (angle.s+180)*Math.PI/180 );
				var sX2 = width/2 + 0.35*width*Math.sin( angle.s*Math.PI/180 );
				var sY2 = height/2 - 0.35*width*Math.cos( angle.s*Math.PI/180 );
				var rX1 = width/2 + 0.28*width*Math.sin( angle.s*Math.PI/180 );
				var rY1 = height/2 - 0.28*width*Math.cos( angle.s*Math.PI/180 );
				return [
					[hX1, hY1, hX2, hY2],
					[mX1, mY1, mX2, mY2],
					[sX1, sY1, sX2, sY2, rX1, rY1]
				];
			};
			function getTimeAngle(){
				var now = new Date();
				var s = now.getSeconds();
				var m = now.getMinutes() + s/60;
				var h = (now.getHours()>=12?now.getHours()-12:now.getHours()) + m/60;
				return {
					h: h*30,
					m: m*6,
					s: s*6
				};
			};
		}
	};
	function Clock(e){
		this.init(e)
	};
	Clock.prototype = proto;
	Clock.prototype.constructor = Clock;
	window.Clock = Clock;
})(window);

 

 

逻辑部分:

myc是获取canvas绘图环境

width,height是等值,因为绘图都是以圆心为基准,所以要用到

coords = [] 标记时间的点都是小的线段,起点和终点,所以数组结构为2次数组,[ [x1,y1,x2,y2] ... ],当5分,10分这些长时间点,额外添加一个参数,绘图时加粗

setcoords() 设置时间点函数

 

 

  1. function setcoords(){  
  2.     var r1 = height/2*0.85;<span style="white-space:pre">     </span>//height/2,为绘图环境高度的一半,用来设置圆的半径(时间点的轨迹),*0.85,因为时钟外面有圆圈,所以缩小  
  3.     var r2 = height/2*0.8;<span style="white-space:pre">      </span>//获取短点的的假数值  
  4.     var r3 = height/2*0.75;<span style="white-space:pre">     </span>//获取长点的假数值  
  5.     for( var i=1; i<61; i++ ){  
  6.         var angle = i*6*Math.PI/180;<span style="white-space:pre">    </span>//时间点之间共用60个小格,每个小格的弧度为6,角度转弧度 *π/180;  
  7.         var x1 = width/2 + r1*Math.sin(angle);<span style="white-space:pre">      </span>//以0点为例,获取0点的头部x坐标,加width/2,是因为canvas绘图环境都是默认左上角为基点  
  8.         var y1 = height/2 - r1*Math.cos(angle);<span style="white-space:pre">     </span>//获取头部y坐标  
  9.         var x2 = width/2 + r2*Math.sin(angle);<span style="white-space:pre">      </span>//获取底部x坐标  
  10.         var y2 = height/2 - r2*Math.cos(angle);<span style="white-space:pre">     </span>//获取底部y坐标  
  11.         var tmp = [x1, y1, x2, y2];  
  12.         if( i%5 == 0 ){<span style="white-space:pre">                 </span>//这里为五分,十分的时间点,比常规的时间点要长,数据替换,额外添加一个参数  
  13.             x2 = width/2 + r3*Math.sin(angle);  
  14.             y2 = height/2 - r3*Math.cos(angle);  
  15.             tmp.splice(2,1,x2);  
  16.             tmp.splice(3,1,y2);  
  17.             tmp.push(1);  
  18.         };  
  19.         coords.push(tmp);<span style="white-space:pre">               </span>//到这里,coords的数据就完成了  
  20.     };  
  21. };  
function setcoords(){
	var r1 = height/2*0.85;<span style="white-space:pre">		</span>//height/2,为绘图环境高度的一半,用来设置圆的半径(时间点的轨迹),*0.85,因为时钟外面有圆圈,所以缩小
	var r2 = height/2*0.8;<span style="white-space:pre">		</span>//获取短点的的假数值
	var r3 = height/2*0.75;<span style="white-space:pre">		</span>//获取长点的假数值
	for( var i=1; i<61; i++ ){
		var angle = i*6*Math.PI/180;<span style="white-space:pre">	</span>//时间点之间共用60个小格,每个小格的弧度为6,角度转弧度 *π/180;
		var x1 = width/2 + r1*Math.sin(angle);<span style="white-space:pre">		</span>//以0点为例,获取0点的头部x坐标,加width/2,是因为canvas绘图环境都是默认左上角为基点
		var y1 = height/2 - r1*Math.cos(angle);<span style="white-space:pre">		</span>//获取头部y坐标
		var x2 = width/2 + r2*Math.sin(angle);<span style="white-space:pre">		</span>//获取底部x坐标
		var y2 = height/2 - r2*Math.cos(angle);<span style="white-space:pre">		</span>//获取底部y坐标
		var tmp = [x1, y1, x2, y2];
		if( i%5 == 0 ){<span style="white-space:pre">					</span>//这里为五分,十分的时间点,比常规的时间点要长,数据替换,额外添加一个参数
			x2 = width/2 + r3*Math.sin(angle);
			y2 = height/2 - r3*Math.cos(angle);
			tmp.splice(2,1,x2);
			tmp.splice(3,1,y2);
			tmp.push(1);
		};
		coords.push(tmp);<span style="white-space:pre">				</span>//到这里,coords的数据就完成了
	};
};

 

 

这个函数作用,获取小时,分钟,秒钟所对应的角度


这个函数是获取指针的坐标

bLength 为端点值,等下用来获取绘图起点,如果端点设置为圆心,这部就可以省略了。

 

 

h,m,s分别对应时针,分针,秒针,这是获取指针坐标的函数

以时针为例。

因为秒针上有一个圆圈,所以额外增加参数。



 

数据都设置完毕,现在开始绘图start函数

 

  1. //绘制点  
  2. myc.clearRect(0, 0, width, height);  
  3. myc.lineCap = 'round';  
  4. myc.beginPath();  
  5. myc.fillStyle = "#000";  
  6. myc.arc(width/2, height/2, height/2, 0, 2*Math.PI);  
  7. myc.fill();  
  8. myc.beginPath();  
  9. myc.fillStyle = "#fff";  
  10. myc.arc(width/2, height/2, height/2*0.9, 0, 2*Math.PI);  
  11. myc.fill();<span style="white-space:pre">             </span>//到这里完毕,绘制黑色圆圈  
  12. for( var i=0; i<coords.length; i++ ){<span style="white-space:pre">    </span>//绘制每个时间点  
  13.     myc.beginPath();  
  14.     var tmp = coords[i];  
  15.     myc.moveTo(tmp[0], tmp[1]);  
  16.     myc.lineTo(tmp[2], tmp[3]);  
  17.     myc.strokeStyle = "#000";  
  18.     myc.lineWidth = tmp[4]?width*0.02:width*0.01;<span style="white-space:pre">   </span>//当为五分,十分这些长点的时候,根据是否有额外参数,加粗  
  19.     myc.stroke();  
  20. };  
//绘制点
myc.clearRect(0, 0, width, height);
myc.lineCap = 'round';
myc.beginPath();
myc.fillStyle = "#000";
myc.arc(width/2, height/2, height/2, 0, 2*Math.PI);
myc.fill();
myc.beginPath();
myc.fillStyle = "#fff";
myc.arc(width/2, height/2, height/2*0.9, 0, 2*Math.PI);
myc.fill();<span style="white-space:pre">				</span>//到这里完毕,绘制黑色圆圈
for( var i=0; i<coords.length; i++ ){<span style="white-space:pre">	</span>//绘制每个时间点
	myc.beginPath();
	var tmp = coords[i];
	myc.moveTo(tmp[0], tmp[1]);
	myc.lineTo(tmp[2], tmp[3]);
	myc.strokeStyle = "#000";
	myc.lineWidth = tmp[4]?width*0.02:width*0.01;<span style="white-space:pre">	</span>//当为五分,十分这些长点的时候,根据是否有额外参数,加粗
	myc.stroke();
};

 

 

 

  1. //绘制指针  
  2. var tmp = getPoint();<span style="white-space:pre">   </span>//获取指针数据,下面开始绘制  
  3. for( var i=0, l=tmp.length; i<l; i++ ){  
  4.     myc.beginPath();  
  5.     myc.moveTo(tmp[i][0],tmp[i][1]);  
  6.     myc.lineTo(tmp[i][2],tmp[i][3]);  
  7.     if( i == 0 ){  
  8.         myc.lineWidth = width*0.03;<span style="white-space:pre"> </span>//时针,分针,秒针,分别设置不同的宽度值  
  9.     }else if( i==1 ){  
  10.         myc.lineWidth = width*0.02;  
  11.     }else if( i==2 ){  
  12.         myc.lineWidth = width*0.01;  
  13.     }  
  14.     myc.strokeStyle = "#000";<span style="white-space:pre">       </span>//在指针外绘制白色阴影,让看起来更有层次感  
  15.     myc.shadowBlur = 4;  
  16.     myc.shadowColor = "#fff";  
  17.     myc.stroke();  
  18.     //指针圆  
  19.     if( i==2 ){<span style="white-space:pre"> </span>//这里是判断是否是秒针,秒针会绘制指针上面的圆圈  
  20.         myc.beginPath();  
  21.         var x = tmp[i][4];  
  22.         var y = tmp[i][5];  
  23.         myc.arc(x, y, width*0.03, 0 , 2*Math.PI);  
  24.         myc.fillStyle = "#fff";  
  25.         myc.fill();  
  26.         myc.strokeStyle = "#000";  
  27.         myc.stroke();  
  28.     };  
  29. };  
//绘制指针
var tmp = getPoint();<span style="white-space:pre">	</span>//获取指针数据,下面开始绘制
for( var i=0, l=tmp.length; i<l; i++ ){
	myc.beginPath();
	myc.moveTo(tmp[i][0],tmp[i][1]);
	myc.lineTo(tmp[i][2],tmp[i][3]);
	if( i == 0 ){
		myc.lineWidth = width*0.03;<span style="white-space:pre">	</span>//时针,分针,秒针,分别设置不同的宽度值
	}else if( i==1 ){
		myc.lineWidth = width*0.02;
	}else if( i==2 ){
		myc.lineWidth = width*0.01;
	}
	myc.strokeStyle = "#000";<span style="white-space:pre">		</span>//在指针外绘制白色阴影,让看起来更有层次感
	myc.shadowBlur = 4;
	myc.shadowColor = "#fff";
	myc.stroke();
	//指针圆
	if( i==2 ){<span style="white-space:pre">	</span>//这里是判断是否是秒针,秒针会绘制指针上面的圆圈
		myc.beginPath();
		var x = tmp[i][4];
		var y = tmp[i][5];
		myc.arc(x, y, width*0.03, 0 , 2*Math.PI);
		myc.fillStyle = "#fff";
		myc.fill();
		myc.strokeStyle = "#000";
		myc.stroke();
	};
};

 

 

  1. //绘制中心圆  
  2. myc.beginPath();  
  3. myc.arc(width/2, height/2, width*0.03/2, 0 ,2*Math.PI);  
  4. myc.fillStyle = "#fff";  
  5. myc.fill();  
  6. myc.beginPath();  
  7. myc.arc(width/2, height/2, width*0.018/2, 0 ,2*Math.PI);  
  8. myc.fillStyle = "#000";  
  9. myc.fill();  
  10. myc.beginPath();  
  11. myc.arc(width/2, height/2, width*0.005/2, 0 ,2*Math.PI);  
  12. myc.fillStyle = "#fff";  
  13. myc.fill();  
//绘制中心圆
myc.beginPath();
myc.arc(width/2, height/2, width*0.03/2, 0 ,2*Math.PI);
myc.fillStyle = "#fff";
myc.fill();
myc.beginPath();
myc.arc(width/2, height/2, width*0.018/2, 0 ,2*Math.PI);
myc.fillStyle = "#000";
myc.fill();
myc.beginPath();
myc.arc(width/2, height/2, width*0.005/2, 0 ,2*Math.PI);
myc.fillStyle = "#fff";
myc.fill();

 

这是绘制函数的最后部分,绘制中心点,更好看

 

canvas时钟制作完毕,这就是整个运行的过程,主要是算好坐标点。

posted @ 2015-09-30 10:26  《从容面对》  阅读(348)  评论(0)    收藏  举报