用画布画一个时钟。查询save()

时间:2016-03-31 21:08:46

标签: html canvas save clock

我知道save()和restore()的功能,它们保存并恢复当前的画布状态。但对这些仍然没有深刻的理解。当程序调用函数绘制时钟时,它会在重绘之前清除所有画布。为什么还应该在这里添加save()。有人能解释一下吗?谢谢。

window.onload=function(){

			var oCan=document.getElementById('clock');
			var oCanPen=oCan.getContext('2d');
			drawClock();
			setInterval(function(){
				drawClock();
			},1000);
			function drawClock(){
				// oCanPen.save();
				oCanPen.clearRect(0,0,oCan.width,oCan.height);
				var time=new Date();
				var second=time.getSeconds();
				var minute=time.getMinutes();
				var hour=time.getHours()+minute/60;

			oCanPen.save();

			oCanPen.beginPath();
			oCanPen.arc(200,200,100,0,360*Math.PI/180,false);
			oCanPen.closePath();
			oCanPen.stroke();

			oCanPen.beginPath();
			for (var i = 0; i < 60; i++) {
				oCanPen.moveTo(200,200);
				oCanPen.arc(200,200,100,i*6*Math.PI/180,i*6*Math.PI/180,false);
				}
			oCanPen.closePath();
			oCanPen.stroke();

			oCanPen.beginPath();
			oCanPen.fillStyle='#fff';
			oCanPen.arc(200,200,90,0,360*Math.PI/180,false);
			oCanPen.closePath();
			oCanPen.fill();

			oCanPen.beginPath();
				for (var i = 0; i < 12; i++) {
				oCanPen.moveTo(200,200);
				oCanPen.arc(200,200,100,i*30*Math.PI/180,i*30*Math.PI/180,false);
				}
			oCanPen.closePath();
			oCanPen.stroke();


			oCanPen.beginPath();
			oCanPen.fillStyle='#fff';
			oCanPen.arc(200,200,80,0,360*Math.PI/180,false);
			oCanPen.closePath();
			oCanPen.fill();
			

			oCanPen.beginPath();
			oCanPen.strokeStyle='red';
			var iSecond=(-90+second*6)*Math.PI/180;
			oCanPen.moveTo(200,200);
			oCanPen.arc(200,200,85,iSecond,iSecond,false);
			oCanPen.closePath();
			oCanPen.stroke();

			oCanPen.beginPath();
			oCanPen.lineWidth=4;
			oCanPen.strokeStyle='blue';
			var iMinute=(-90+minute*6)*Math.PI/180;
			oCanPen.moveTo(200,200);
			oCanPen.arc(200,200,60,iMinute,iMinute,false);
			oCanPen.closePath();
			oCanPen.stroke();

			oCanPen.beginPath();
			oCanPen.lineWidth=6;
			var iHour=(-90+hour*30)*Math.PI/180;
			oCanPen.strokeStyle='black';
			oCanPen.moveTo(200,200);
			oCanPen.arc(200,200,40,iHour,iHour,false);
			oCanPen.closePath();
			oCanPen.stroke();

			oCanPen.restore();
		}

		};
	body{
		background: #333;
	}
	canvas{
		background: #f2f2f2;
	}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
	<title></title>

</head>
<body>

<canvas id="clock" width="400" height="400"></canvas>

</body>
</html>

1 个答案:

答案 0 :(得分:0)

保存和恢复不受位图内容的影响 - 它们只是处理您所说的状态,或“设置”,如颜色样式,线宽,当前字体等。

清除画布时,状态保持不变。反之亦然,在恢复状态时,它不会影响画布上的任何现有内容。

典型的用法是,如果你有一个你喜欢的状态,但需要临时更改转换,样式等绘制,然后恢复,这样你就可以回到你拥有的状态,而无需重置这些值。

在您的情况下,您可以更改lineWidth和strokeStyles而不必担心以后的情况。

另一方面,如果能够跟踪所有更改的状态值,则可以避免保存/恢复。这在许多情况下比保存/恢复更快,因为后者保存完整状态,而不仅仅是样式和行宽。

在您的情况下,您可以简单地删除保存/恢复并使用这一新的代码行来避免这一切:

..
var hour=time.getHours()+minute/60;

oCanPen.lineWidth = 1;

oCanPen.beginPath();
..              

window.onload=function(){

			var oCan=document.getElementById('clock');
			var oCanPen=oCan.getContext('2d');
			drawClock();
			setInterval(function(){
				drawClock();
			},1000);
			function drawClock(){
				// oCanPen.save();
				oCanPen.clearRect(0,0,oCan.width,oCan.height);
				var time=new Date();
				var second=time.getSeconds();
				var minute=time.getMinutes();
				var hour=time.getHours()+minute/60;

            oCanPen.lineWidth = 1;
              
			oCanPen.beginPath();
			oCanPen.arc(200,200,100,0,360*Math.PI/180,false);
			oCanPen.closePath();
			oCanPen.stroke();

			oCanPen.beginPath();
			for (var i = 0; i < 60; i++) {
				oCanPen.moveTo(200,200);
				oCanPen.arc(200,200,100,i*6*Math.PI/180,i*6*Math.PI/180,false);
				}
			oCanPen.closePath();
			oCanPen.stroke();

			oCanPen.beginPath();
			oCanPen.fillStyle='#fff';
			oCanPen.arc(200,200,90,0,360*Math.PI/180,false);
			oCanPen.closePath();
			oCanPen.fill();

			oCanPen.beginPath();
				for (var i = 0; i < 12; i++) {
				oCanPen.moveTo(200,200);
				oCanPen.arc(200,200,100,i*30*Math.PI/180,i*30*Math.PI/180,false);
				}
			oCanPen.closePath();
			oCanPen.stroke();


			oCanPen.beginPath();
			oCanPen.fillStyle='#fff';
			oCanPen.arc(200,200,80,0,360*Math.PI/180,false);
			oCanPen.closePath();
			oCanPen.fill();
			

			oCanPen.beginPath();
			oCanPen.strokeStyle='red';
			var iSecond=(-90+second*6)*Math.PI/180;
			oCanPen.moveTo(200,200);
			oCanPen.arc(200,200,85,iSecond,iSecond,false);
			oCanPen.closePath();
			oCanPen.stroke();

			oCanPen.beginPath();
			oCanPen.lineWidth=4;
			oCanPen.strokeStyle='blue';
			var iMinute=(-90+minute*6)*Math.PI/180;
			oCanPen.moveTo(200,200);
			oCanPen.arc(200,200,60,iMinute,iMinute,false);
			oCanPen.closePath();
			oCanPen.stroke();

			oCanPen.beginPath();
			oCanPen.lineWidth=6;
			var iHour=(-90+hour*30)*Math.PI/180;
			oCanPen.strokeStyle='black';
			oCanPen.moveTo(200,200);
			oCanPen.arc(200,200,40,iHour,iHour,false);
			oCanPen.closePath();
			oCanPen.stroke();

		}

		};
body{
		background: #333;
	}
	canvas{
		background: #f2f2f2;
	}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
	<title></title>

</head>
<body>

<canvas id="clock" width="400" height="400"></canvas>

</body>
</html>