canvas 案例——时钟

首先先理解几个方法:

1、save()和restore():这对法宝非常有用,两个配对使用,saved方法用于临时保存画布的坐标系统的状态;restore方法用来恢复save之后保存的状态。可以简单的理解为,save之后的一系列的操作,比如translate和rotate等,在restore后,都会被释放恢复到原来的坐标状态。

eg:

        ctx.strokeStyle = '#000';
        ctx.strokeRect(10,10,200,100);	//空心矩形
		ctx.translate(10,10);	//改变坐标原点
		ctx.strokeStyle = 'red';
		ctx.strokeRect(10,10,200,100);	//实心矩形

效果:

接下来加上save和restore

ctx.strokeStyle = '#000';
		ctx.strokeRect(10,10,200,100);	//空心矩形
		ctx.save();
		ctx.translate(10,10);	//改变坐标原点
		ctx.restore();
		ctx.strokeStyle = 'red';
		ctx.strokeRect(10,10,200,100);	//实心矩形

效果:

从图一不难发现没加save和restore之前,红色的矩形已经是以(10,10)为原点来绘制了,加了之后画布恢复到translate的操作之前,原点仍然是(0,0),因此图二的红色矩形才会把上一个矩形给覆盖了。

2、translate():默认画布的原点为(0,0),调用此方法可改变画布坐标原点的位置。调用此方法后,x坐标往左的位置以及y坐标往上的位置都为负值。

eg:可以从上面的图一来理解,红色的矩形已经以(10,10)为原点来绘制了。负值的理解如下:假如把原点的位置放到画布的正中间,那么各区间的坐标如下:

3、rotate(angle):此方法用来对画布执行旋转操作,默认旋转的中心点为画布的坐标原点,可以通过translate来改变旋转中心的位置。angle为旋转的角度,以弧度计算,旋转30度的话angle就是20*Math.PI/180。

eg:让一个正方形围绕着自己的中心点旋转30度,

ctx.strokeRect(100,100,200,100);
		ctx.save();
		ctx.strokeStyle = 'red';
		ctx.translate(200,150);
		ctx.rotate(30*Math.PI/180);
		ctx.strokeRect(-100,-50,200,100);
		ctx.restore();

效果:

接下来说下时钟的主要思路:就是每隔一秒把当前的时分秒对应的时针、分针、秒针绘制到画布上就可以了,时针对应12个刻度,因此每个刻度旋转30度,当前小时对应的旋转角度就应该是rotate(hour*30*Math.PI/180);分针和秒针一样对应60个刻度,每个刻度旋转6度,当前分钟和秒对应的旋转角度是rotate(minute*6*Math.PI/180)以及rotate(seconds*6*Math.PI/180)。

具体代码如下:

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>canvas 时钟</title>
	<style>
		*{margin: 0; padding: 0;}
		.main{
			width: 1000px;
			padding: 50px 0;
			border: 1px solid #ccc;
			margin: 0 auto;
			text-align: center;
		}
		#canvas{
			margin: 50px 0;
			background-color: deepskyblue;
		}
	</style>
</head>
<body>
<div class="main">	
	<canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
</div>
<script>
	window.onload = function(){
		var canvas = document.getElementById('canvas');
		var ctx = canvas.getContext('2d');
		
		function drawClock(){
			//获取当前的时分秒
			var now = new Date();
			var seconds = now.getSeconds();
			var minute = now.getMinutes();
			var hour = now.getHours();
            //小时必须获取浮点类型,产生偏移(小时+分钟比)
			hour = hour+minute/60;
			//将24小时转换为12小时
			hour = hour>12?hour-12:hour;
			
			//填写标题
			ctx.font = '36px 微软雅黑';			
			var grident = ctx.createLinearGradient(0,0,300,0);	//创建渐变
				grident.addColorStop(0.5,'yellow');
				grident.addColorStop(0.8,'blue');
				grident.addColorStop(1,'red');			
				ctx.fillStyle = grident;	//用渐变来填充颜色
				ctx.fillText	('canvas 时钟',200,60);
				
				//画圆			
				ctx.save();
				ctx.beginPath();
				ctx.lineWidth = 5;
				ctx.arc(300,300,200,0,Math.PI*360/180,false);
				ctx.strokeStyle = 'blue';
				ctx.stroke();
				ctx.closePath();
				ctx.restore();
				
				//画时钟的刻度	12个刻度,每个刻度旋转30度	
				for(var i=0;i<=12;i++){
					ctx.save();
					ctx.strokeStyle = 'black';
					ctx.lineWidth = 7;
					ctx.translate(300,300);	//设置画布的原点
					ctx.rotate(i*Math.PI*30/180,300,300);	//rotate()后两个参数设置旋转的中心点
					ctx.beginPath();	
					ctx.moveTo(0,-172);
					ctx.lineTo(0,-192);
					ctx.stroke();
					ctx.closePath();
					ctx.restore();
				}
				
				//画秒钟的刻度	60个刻度,每个刻度旋转6度	
				for(var i=0;i<=60;i++){
					ctx.save();
					ctx.strokeStyle = 'black';
					ctx.lineWidth = 3;
					ctx.translate(300,300);	//设置画布的原点
					ctx.rotate(i*Math.PI*6/180,300,300);	//rotate()后两个参数设置旋转的中心点
					ctx.beginPath();	
					ctx.moveTo(0,-182);
					ctx.lineTo(0,-192);
					ctx.stroke();
					ctx.closePath();
					ctx.restore();
				}
				
				//标注小时
				ctx.save();
				ctx.fillStyle = 'deeppink';
				ctx.font = '22px 微软雅黑';
				ctx.lineWidth = 6;
				ctx.fillText(12,286,150);
				ctx.fillText(1,370,170);
				ctx.fillText(2,430,230);
				ctx.fillText(3,456,310);
				ctx.fillText(4,430,390);
				ctx.fillText(5,380,440);
				ctx.fillText(6,295,468);
				ctx.fillText(7,215,446);
				ctx.fillText(8,158,390);
				ctx.fillText(9,132,310);
				ctx.fillText(10,156,230);
				ctx.fillText(11,210,176);
				ctx.restore();				
				
				//画时针
				ctx.save();
				ctx.lineWidth = 7;
				ctx.strokeStyle = 'yellow';
				ctx.translate(300,300);
				ctx.rotate(hour*30*Math.PI/180);
				ctx.beginPath();
				ctx.moveTo(0,20);
				ctx.lineTo(0,-140);
				ctx.stroke();
				ctx.closePath();
				ctx.restore();
				
				//画分针
				ctx.save();
				ctx.lineWidth = 5;
				ctx.strokeStyle = 'blue';
				ctx.translate(300,300);
				ctx.rotate(minute*6*Math.PI/180);
				ctx.beginPath();
				ctx.moveTo(0,20);
				ctx.lineTo(0,-168);
				ctx.stroke();
				ctx.closePath();
				ctx.restore();
				
				//画秒针
				ctx.save();
				ctx.lineWidth = 3;
				ctx.strokeStyle = 'red';
				ctx.translate(300,300);
				ctx.rotate(seconds*6*Math.PI/180);
				ctx.beginPath();
				ctx.moveTo(0,20);
				ctx.lineTo(0,-186);
				ctx.stroke();
				ctx.closePath();
				ctx.restore();
				
				//圈出时针,分针,秒针的交叉点
				ctx.save();
				ctx.beginPath();
				ctx.lineWidth = 3;
				ctx.strokeStyle = 'red';
				ctx.arc(300,300,5,0,360*Math.PI/180,false);
				ctx.fillStyle = '#fff';
				ctx.fill();
				ctx.stroke();
				ctx.closePath();
				
				//装饰秒针
				ctx.save();
				ctx.beginPath();				
				ctx.lineWidth = 3;
				ctx.strokeStyle = 'red';
				ctx.translate(300,300);
				ctx.rotate(seconds*6*Math.PI/180);	//让当前的装饰跟着秒针一起转动
				ctx.arc(0,-160,5,0,360*Math.PI/180,false);
				ctx.fillStyle = '#fff';
				ctx.fill();
				ctx.stroke();
				ctx.restore();
		}
		
		drawClock();
		setInterval(function(){
			ctx.clearRect(0,0,canvas.width,canvas.height);
			drawClock();
		},1000);
	}
</script>
</body>
</html>

效果:

猜你喜欢

转载自blog.csdn.net/yemuxia_sinian/article/details/81317426
今日推荐