canvas时钟

效果图

http://www.hui12.com/nbin/csdn/canvasClock/demo.html

https://nbin2008.github.io/demo/canvasClock/index.html




html代码



js代码

(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() 设置时间点函数


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函数

//绘制点
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();
};



//绘制指针
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();
	};
};


//绘制中心圆
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时钟制作完毕,这就是整个运行的过程,主要是算好坐标点。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值