初學者也許會誤認為canvas中save方法是用來保存繪圖狀態的圖形,而restore方法是用來還原之前保存的繪圖狀態的圖形,其實不然。
save():保存當前的繪圖狀態。
restore():恢復之前保存的繪圖狀態。
在Canvas環境中繪圖時,可以利用所謂的繪圖堆棧狀態。每個狀態隨時存儲Canvas上下文數據。下面是存儲在狀態堆棧的數據列表。
- 當前的坐標變換(變換矩陣)信息,比如旋轉或平移時使用的
rotate()
和setTransform()
方法 - 當前剪貼區域clip()
- 圖形上下文對象(
CanvasRenderingContext2D
)的當前屬性值
CanvasRenderingContext2D
的當前屬性值主要包括:
屬性 | 描述 |
---|---|
canvas |
取得畫布<canvas> 元素 |
fillStyle |
填充路徑的當前的顏色、模式或漸變 |
globalCompositeOperation |
指定顏色如何與畫布上已有顏色組合(合成) |
lineCap |
指定線段端點的繪制方式 |
lineJoin |
指定線段連接的繪制方式 |
lineWidth |
繪制線段的寬度 |
miterLimit |
當lineJoin 為miter 時,這個屬性指定斜連接長度和二分之一線寬的最大比率 |
shadowBlur |
指定陰影模糊度 |
shadowColor |
指定陰影顏色 |
shadowOffsetX |
指定陰影水平偏移值 |
shadowOffsetY |
指定陰影垂直偏移值 |
strokeStyle |
指定線段顏色 |
上面是Canvas繪圖中的狀態,那么什么情形不屬於Canvas狀態?
在Canvas中當前路徑和當前位圖受Canvas環境控制,不屬於保存狀態。這個重要的功能允許在畫布上對單個對象進行繪畫和制作動畫。
如上所述用堆棧的原理來解釋,就是調用save()方法時,將記錄當前的繪圖狀態,並壓入一個堆棧中;接着調用restore()方法時,就會把上一次記錄的繪圖狀態從堆棧中彈出。
需要注意的是,出棧的次數不能多於入棧的次數,故程序中restore()方法調用的次數不應該比save()方法多。
畫張圖來幫助理解:
如果上面的描述還是無法幫助你理解save()
和restore()
兩個方法的話,那我們來寫一個簡單的示例來幫助大家理解:
1 <body> 2 <!--創建一個邊長為200的正方形畫布--> 3 <canvas id="mc" width="200" height="200" style="border:1px solid black"></canvas> 4 5 <script type="text/javascript"> 6 var canvas = document.getElementById('mc'); //獲取Canvas元素對應的DOM對象 7 var ctx = canvas.getContext('2d');//獲取Canvas上的繪圖的CanvasRenderingContext2D對象 8 ctx.lineWidth=3; //設置筆觸線條的寬度 9 ctx.translate(100,100); //將原點左邊設置到畫布的中間 10 ctx.save(); //保存當前畫布的狀態,該狀態包含了lineWidth=3,translate(100,100),然后其他那些屬性為默認值. 11 ctx.strokeStyle='red'; //設置線條顏色為紅色 12 //坐標系統旋轉90° 13 ctx.rotate(Math.PI/2); 14 //畫第一條直線 15 ctx.beginPath(); 16 ctx.moveTo(-100,0); 17 ctx.lineTo(100,0); 18 ctx.closePath(); 19 ctx.stroke(); 20 //恢復之前保存的繪圖狀態 21 ctx.restore(); 22 //再畫第二條直線 23 ctx.beginPath(); 24 ctx.moveTo(-100,0); 25 ctx.lineTo(100,0); 26 ctx.closePath(); 27 ctx.stroke(); 28 </script> 29 </body>
在瀏覽器中看到的效果如下:
看代碼可知,畫兩條線的代碼是一樣的,可是畫出來的一條是垂直的紅線,一條是水平的黑線。調用save()方法時,保存的狀態是lineWidth=3,translate(100,100),然后其他那些屬性為默認值,如默認的lineStyle為黑色。
畫第一條線時,是將坐標系統旋轉了90°,設置了lineStyle="red",故畫出來的是垂直的紅色線;畫第二條線前調用了restore()方法,即恢復為了之前保存的繪圖狀態,該繪圖狀態是坐標系統沒有經過旋轉的,線條顏色也默認為黑色,所以畫出來的先就是我們想要得到的水平的黑色線。