canvas save()

admin發表於2019-08-27

save()方法可以儲存前面圖案的繪製狀態。

特別注意的是,save()方法儲存的是繪製狀態,而不是圖形本身。

比如我們可以儲存圖形的填充顏色、描邊顏色、位移或者縮放,這些都圖案的狀態。

通過restore()方法可以還原通過save()方法儲存的狀態。

語法結構:

[JavaScript] 純文字檢視 複製程式碼
ctx.save();

每呼叫一次save()方法儲存一次canvas圖案的狀態。

記憶體中專門開闢一個狀態棧用於儲存狀態,簡單圖示如下:

a:3:{s:3:\"pic\";s:43:\"portal/201908/27/225239ymhjr499zoipgc4x.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

圖示簡單分析如下:

(1).每呼叫一次save()方法,在棧中儲存一次狀態。

(2).存入的時間越早,狀態在棧中的位置越靠下。

(3).如果儲存的順序是0、1、2、3,那麼彈出的順序就是3、2、1、0。

瀏覽器相容:

(1).IE9+瀏覽器支援此方法。

(2).edge瀏覽器支援此方法。

(3).谷歌瀏覽器支援此方法。

(4).火狐瀏覽器支援此方法。

(5).Opera瀏覽器支援此方法。

(6).Safari瀏覽器支援此方法。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style>
canvas{
  border: 1px solid #000;
}
</style>
<script>
window.onload = () => {
  let cvs=document.querySelector('canvas');
  let ctx=cvs.getContext('2d');

  ctx.save();
  
  ctx.setLineDash([5]);
  ctx.lineWidth=4;
  ctx.strokeStyle='green';
  ctx.strokeRect(10,10,100,100);

  ctx.restore();
  ctx.arc(150,150,50,0,2*Math.PI);
  ctx.stroke();
}
</script>
</head>
<body>
<canvas height="200"></canvas>
</body>
</html>

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201908/27/225321ccg21zbs2szaw6oz.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

程式碼分析如下:

[JavaScript] 純文字檢視 複製程式碼
ctx.save();

上述可以儲存前面的狀態,前面沒有人為定義狀態,所以都是預設狀態。

[JavaScript] 純文字檢視 複製程式碼
ctx.setLineDash([5]);
ctx.lineWidth=4;
ctx.strokeStyle='green';
ctx.strokeRect(10,10,100,100);

上述程式碼繪製一個虛線、邊框寬度為4和邊框顏色為綠色的矩形。

但是後面並沒有呼叫save()方法,所以這些狀態並沒有被儲存起來。

[JavaScript] 純文字檢視 複製程式碼
ctx.restore();
ctx.arc(150,150,50,0,2*Math.PI);
ctx.stroke();

前面程式碼呼叫restore()方法,可以從改狀態棧中彈出儲存的狀態。

下面繪製一個圓形,那麼這個圓形會應用這個彈出恢復的狀態。

前面儲存的狀態是預設的,所以圓形的描邊是黑色,而不是前面規定的綠色描邊。

[HTML] 純文字檢視 複製程式碼執行程式碼
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style>
canvas{
  border: 1px solid black;
}
</style>
<script>
window.onload = () => {
  let cvs=document.querySelector('canvas');
  let ctx=cvs.getContext('2d');
  //儲存狀態一
  ctx.save();

  ctx.lineWidth=2;
  ctx.strokeStyle='green';
  ctx.strokeRect(10,10,100,100);
  //儲存狀態二
  ctx.save();
  ctx.lineWidth=8;
  ctx.strokeStyle='blue';
  ctx.strokeRect(50,50,100,100);
  //儲存狀態三
  ctx.save();
  //彈出還原狀態三
  ctx.restore();
  ctx.strokeRect(200,200,100,100);
  //彈出還原狀態二
  ctx.restore();
  ctx.strokeRect(250,250,100,100);
  //彈出還原狀態一
  ctx.restore();
  ctx.strokeRect(300,300,100,100);
}
</script>
</head>
<body>
  <canvas width="800" height="600"></canvas>
</body>
</html>

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201908/27/225429eas1uhiwpsguwtlr.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

上面程式碼多次使用save()方法儲存狀態,然後再使用restore()方法彈出還原狀態。

首先儲存的狀態會被最後彈出,遵循棧記憶體先進後出的規則。

(1).第一個儲存的是預設黑色描邊,描邊的寬度是1px。

(2).第二個儲存的是綠色描邊,描邊的寬度是2px。

(3).第三個儲存的是藍色描邊,描邊的寬度是8px。

(4).當使用restore()方法彈出還原的時候,順序是三、二、一,恰好和儲存順序相反。

相關文章