1. 開始使用 canvas 元素 canvas 元素非常簡單,這是指它所有的功能都體現在一個JavaScript對象上,因此該元素本身只有兩個屬性:width 和 height。 canvas 元素里的內容會在瀏覽器不支持此元素時作為備用內容顯示。下麵例子展示了canvas 元素和一些簡單的備用內 ...
1. 開始使用 canvas 元素
canvas 元素非常簡單,這是指它所有的功能都體現在一個JavaScript對象上,因此該元素本身只有兩個屬性:width 和 height。
canvas 元素里的內容會在瀏覽器不支持此元素時作為備用內容顯示。下麵例子展示了canvas 元素和一些簡單的備用內容。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用帶有基本備用內容的canvas元素</title> <style> canvas {border: medium double black;margin: 4px;} </style> </head> <body> <canvas width="500" height="200"> Your browser doesn't support the <code>canvas</code> element </canvas> </body> </html>
其顯示效果如下:
2. 獲取畫布上的上下文
為了在canvas元素上繪圖,需要獲得一個上下文對象,這個對象會開放針對特定圖形樣式的繪圖函數。
通過在DOM里代表canvas元素的對象獲得上下文。下表介紹了這個對象:HTMLCanvasElement。
其中關鍵的方法是getContext。為了獲得二維上下文對象,需要給這個方法傳遞參數2d。一旦得到這個上下文,就可以開始繪圖了。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>為畫布獲取二維上下文對象</title> <style> canvas {border: medium double black;margin: 4px;} </style> </head> <body> <canvas id="canvas" width="500" height="200"> Your browser doesn't support the <code>canvas</code> element </canvas> <script> var ctx = document.getElementById("canvas").getContext("2d"); ctx.fillRect(10,10,50,50); </script> </body> </html>
此例中,用document 對象找到DOM里代表canvas元素的對象,並使用參數2d調用了getContext方法得到上下文對象。然後調用 fillRect方法,它會在畫布上繪製一個實心矩形。
3. 繪製圖形
這裡先從canvas對矩形的支持開始。下表介紹了相關方法,所有的這些方法要用在上下文對象上(而不是畫布本身)。
所有這三個方法都要四個參數。前兩個(如表格所示的x和y)是從canvas元素左上角算起的偏移量。w和h參數指定了待繪製矩形的寬度和高度。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用fillRect和strokeRect方法</title> <style> canvas {border: medium double black;margin: 4px;} </style> </head> <body> <canvas id="canvas" width="500" height="200"> Your browser doesn't support the <code>canvas</code> element </canvas> <script> var ctx = document.getElementById("canvas").getContext("2d"); var offset = 10; var size = 50; var count = 5; for(var i=0;i<count;i++){ ctx.fillRect(i*(offset+size)+offset,offset,size,size); ctx.strokeRect(i*(offset+size)+offset,(2*offset)+size,size,size); } </script> </body> </html>
此例中的腳本用fillRect 和strokeRect 方法來創建一系列實現和空心的矩形。
用這種方式編寫腳本是為了突出canvas 元素的編程本質。使用JavaScript的for迴圈繪製這些矩形。其實本可以使用10條獨立的語句,每一條都帶有特定的坐標參數,但是canvas的一大樂趣就是可以不必這麼做。
clearRect 方法會清楚指定矩形里已繪製的所有內容。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用clearRect方法</title> <style> canvas {border: medium double black;margin: 4px;} </style> </head> <body> <canvas id="canvas" width="500" height="200"> Your browser doesn't support the <code>canvas</code> element </canvas> <script> var ctx = document.getElementById("canvas").getContext("2d"); var offset = 10; var size = 50; var count = 5; for(var i=0;i<count;i++){ ctx.fillRect(i*(offset+size)+offset,offset,size,size); ctx.strokeRect(i*(offset+size)+offset,(2*offset)+size,size,size); ctx.clearRect(i*(offset+size)+offset,offset+5,size,size); } </script> </body> </html>
此例用clearRect方法清楚了之前被fillRect方法繪製過的一片畫布區域。從下圖可以看到效果:
4. 設置畫布繪製狀態
繪製操作有繪製狀態(drawing state)加以配置。後者是一組屬性,指定了從線條寬度到填充色的所有參數。當繪製一個圖形時,就會用到繪製狀態的當前設置。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>在執行操作前設置繪製狀態</title> <style> canvas {border: medium double black;margin: 4px;} </style> </head> <body> <canvas id="canvas" width="500" height="200"> Your browser doesn't support the <code>canvas</code> element </canvas> <script> var ctx = document.getElementById("canvas").getContext("2d"); ctx.lineWidth = 2; ctx.strokeRect(10,10,50,50); ctx.lineWidth = 4; ctx.strokeRect(70,10,50,50); ctx.lineWidth = 6; ctx.strokeRect(130,10,50,50); ctx.strokeRect(190,10,50,50); </script> </body> </html>
此例使用了lineWidth屬性,此屬性是繪製狀態的一部分,負責設置用於圖形(比如strokeRect方法生成的那些)的線條寬。當使用strokeRect方法時,lineWidth屬性的當前值就會用於繪製矩形。
下表展示了基本的繪製狀態屬性。
4.1 設置線條連接樣式
lineJoin 屬性決定了相互連接的線條應該如何繪製,它有三個值:round、bevel和 miter,預設值是miter。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>設置lineJoin屬性</title> <style> canvas {border: medium double black;margin: 4px;} </style> </head> <body> <canvas id="canvas" width="500" height="140"> Your browser doesn't support the <code>canvas</code> element </canvas> <script> var ctx = document.getElementById("canvas").getContext("2d"); ctx.lineWidth = 20; ctx.lineJoin = "round"; ctx.strokeRect(20,20,100,100); ctx.lineJoin = "bevel"; ctx.strokeRect(160,20,100,100); ctx.lineJoin = "miter"; ctx.strokeRect(300,20,100,100); </script> </body> </html>
其顯示效果如下所示:
4.2 設置填充和筆觸樣式
當用fillStyle 或strokeStyle 屬性設置樣式時, 可以用CSS顏色值來指定一種顏色,名稱或顏色模型都可以。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用fillStyle和strokeStyle屬性設置顏色</title> <style> canvas {border: medium double black;margin: 4px;} </style> </head> <body> <canvas id="canvas" width="500" height="140"> Your browser doesn't support the <code>canvas</code> element </canvas> <script> var ctx = document.getElementById("canvas").getContext("2d"); var offset = 10; var size = 50; var count = 5; ctx.lineWidth = 3; var fillColors = ["black","gray","lightgray","red","blue"]; var strokeColors = ["rgb(0,0,0)","rgb(100,100,100)","rgb(200,200,200)","rgb(255,0,0)","rgb(0,0,255)"]; for(var i=0;i<count;i++){ ctx.fillStyle = fillColors[i]; ctx.strokeStyle = strokeColors[i]; ctx.fillRect(i*(offset+size)+offset,offset,size,size); ctx.strokeRect(i*(offset+size)+offset,(2*offset)+size,size,size); } </script> </body> </html>
此例中,用CSS顏色名和 rgb模型定義了兩個顏色數組。然後再 for迴圈中把這些顏色指派給 fillStyle和 strokeStyle屬性,並調用了 fillRect和 strokeRect方法。
4.3 使用漸變
除了純色,還可以把填充和筆觸樣式設置為漸變色。漸變是兩種或更多顏色之間的漸進轉變。canvas 元素支持兩類漸變:線性和徑向。
這兩個方法都返回一個CanvasGradient對象,它定義了 addColorStop方法。其中參數描述了漸變使用的線條或圓。
(1) 使用線性漸變
線性漸變(linear gradient)指的是沿著一條線設定要用的若幹顏色。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>創建線性漸變</title> <style> canvas {border: medium double black;margin: 4px;} </style> </head> <body> <canvas id="canvas" width="500" height="140"> Your browser doesn't support the <code>canvas</code> element </canvas> <script> var ctx = document.getElementById("canvas").getContext("2d"); var grad = ctx.createLinearGradient(0,0,500,140); grad.addColorStop(0,"red"); grad.addColorStop(0.5,"white"); grad.addColorStop(1,"black"); ctx.fillStyle = grad; ctx.fillRect(0,0,500,140); </script> </body> </html>
使用createLinearGradient 方法時,提供的四個值會作為畫布上一條線段的開始和結束坐標。在這個例子中,用坐標描述了一條開始於(0,0),結束於(500,140)的線段。這些點分別對應畫布的左上角和右下角,如下圖所示:
這條線就代表了漸變。現在可以在createLinearGradient 方法返回的CanvasGradient上使用 addColorStop方法,沿著梯度線添加各種顏色了,就像這樣:
grad.addColorStop(0,"red");
grad.addColorStop(0.5,"white");
grad.addColorStop(1,"black");
addColorStop方法的第一個參數是想要線上段上應用顏色的位置,顏色則由第二個參數指定。線段的起點(此例中是坐標(0,0))由0這個值代表,1則代表終點。此例中,告訴canvas想讓red(紅色)處於線段起點,white(白色)處於線段中點,而black(黑色)處於線段終點。然後畫布會計算出如何在這些點上逐漸轉變這些顏色。想要指定多少個顏色點都可以。
定義漸變並添加顏色之後,就可以用CanvasGradient對象來設置fillStyle或strokeStyle屬性了,就像這樣:
ctx.fillStyle = grad;
最後,可以繪製一個圖形。此例中,繪製了一個實心的矩形:
ctx.fillRect(0,0,500,140);
從下圖可以看到這個矩形填滿了畫布,並展示出完整的漸變。
(2) 在更小的圖形里使用線性漸變
在定義梯度線時要相對於畫布進行設置,而不是繪製圖形。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>在不填滿畫布的圖形中使用漸變</title> <style type="text/css"> canvas {border: thin solid black;margin: 4px;} </style> </head> <body> <canvas id="canvas" width="500" height="140"> Your browser doesn't support the <code>canvas</code> element </canvas> <script> var ctx = document.getElementById(