我知道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>
答案 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>