快速入門:繪製至畫布 (HTML)
[ 本文的目標對象是撰寫 Windows 執行階段 App 的 Windows 8.x 和 Windows Phone 8.x 開發人員。如果您正在開發適用於 Windows 10 的 App,請參閱 最新文件 ]
Canvas 元素會在頁面上產生矩形的點陣圖畫布,您可以在畫布上使用 JavaScript 動態繪製圖形影像。畫布非常適用於建立遊戲,或者即時產生圖形或定期變更圖形。
這個快速入門包含以下幾節:
- 先決條件
- Canvas 元素
- 轉譯內容
- 繪製矩形
- 使用路徑
- 繪製弧形
- 繪製曲線
- 二次方曲線
- 貝茲立方曲線
- 後續步驟
先決條件
這個主題假設您可以利用 JavaScript,以適用於 JavaScript 的 Windows Library 範本建立基本的 Windows 市集應用程式,而且對於 HTML 和 JavaScript 有基本的認識。如需使用 JavaScript 建立您的第一個 Windows 市集應用程式的指示,請參閱建立您的第一個 Web 應用程式。如需使用 WinJS 範本的指示,請參閱<如何取得和使用 WinJS 工具組>。
Canvas 元素
Canvas 元素會在頁面上產生矩形的點陣圖畫布,您可以在畫布上使用 JavaScript 動態產生圖形影像。
Canvas 元素有寬度和高度屬性。 這兩者都是選擇性的,而且可以使用文件物件模型 (DOM) 屬性設定。 如果未設定寬度和高度屬性,畫布會以其預設大小 (寬度為 300 像素,高度為 150 個像素) 顯示。
<canvas id="canvas" width="150" height="150"></canvas>
識別碼屬性不是 Canvas 元素的一部分,但可用來識別指令碼中的 Canvas 元素。
您可以使用階層式樣式表 (CSS) 設定畫布的大小。根據預設,您的應用程式會呈現沒有內容或框線的 Canvas 元素,它是完全透明的。不過,您可以指定邊界、框線、背景等等來設定 Canvas 元素的樣式,就像任何一般影像一樣。設定樣式不會影響畫布上的實際繪圖。
轉譯內容
將 Canvas 元素新增到應用程式,只建立透明的繪圖表面。若要繪製到畫布,您要從畫布取得轉譯內容,然後使用該內容繪製。有多種可以讓您使用不同方式繪製的轉譯內容。例如,2D 圖形使用的 2D 內容和 3D 圖形使用的 3D 內容。這個主題中的範例使用 2D 轉譯內容。
若要取得轉譯內容,您要呼叫畫布的 getContext 方法,如以下範例所示:
var canvas = document.getElementById("quickstart");
var context = canvas.getContext("2d");
在我們的範例中,我們開始使用 getElementById 抓取畫布 DOM 節點,然後使用 getContext 方法存取轉譯內容。getContent 方法接受一個參數,也就是內容的類型。在我們的範例中為 ‘2d’。
取得轉譯內容之後,您可以使用該內容來繪製。下列幾節描述如何繪製不同類型的形狀。
繪製矩形
有兩個函式可用來在畫布上繪製矩形:
-
fillRect (x, y, width, height)
這個方法可以繪製實心矩形。
x、y 參數是在畫布上為矩形定位的座標,相對於畫布的左上角。 寬度和高度是以像素測量。
-
strokeRect(x, y, width, height)
strokeRect 參數對於 fillRect 而言是相同的。 差異在於 strokeRect 僅繪製矩形的外框。
這個方法會為指定的形狀著色:
-
fillStyle = color
fillStyle 方法使用單一參數將形狀填滿色彩。您可以使用 RGB、預先定義的色彩 (例如 "red"、"blue" 等)、十六進位色彩,甚至漸層設定色彩。如需 fillStyle 範例,請參閱底下的繪製矩形範例。
這個方法會清除指定的區域,並使其變成完全透明:
-
clearRect(x, y, width, height)
如同使用 fillRect 和 strokeRect 方法,clearRect 參數 x 和 y 會為要清除的矩形區域定位,並設定矩形的寬度和高度。
範例
讓我們從產生畫布的範例開始,然後繪製兩個實心正方形;一個金色正方形,以及一個透明的紫色正方形。CSS 將用來建立畫布周圍的黑色框線:
此範例會從在 HTML 的 <body> 中宣告 Canvas 元素開始。此 Canvas 元素會被指定一個稱為 "canvas" 的識別碼屬性,而且該元素的高度和寬度屬性會設為 100 個像素:
<body>
<canvas id="canvas" width="100" height="100" />
</body>
Canvas 元素是使用 CSS,以一個像素寬度的實心黑框建立。CSS 應該包含在外部檔案中,以便使檔案的載入盡可能地有效率:
/* style the canvas element with a black border. */
canvas { border: 1px solid black; }
我們這個在畫布上繪製兩個實心矩形的 JavaScript 程式碼也是包含在外部檔案中。此程式碼會在載入 HTML 文件之後開始,使用 window onload 事件處理常式呼叫 draw 函式。
window.onload = draw;
draw 方法使用 getElementById 方法取得 Canvas 元素。接著,它會呼叫 getContext 方法來取得繪製內容。 您必須將字串 "2d" 傳遞至 getContext 方法。
每個畫布都有一個繪圖內容。繪圖內容是定義所有繪圖方法和屬性的地方。
// Get the canvas element.
var canvas = document.getElementById("canvas");
// Specify a 2-D drawing context.
var context = canvas.getContext("2d");
若要開始繪製第一個正方形,fillStyle 要設定成某個色彩。填滿矩形有好幾種方式。在我們的範例中是使用等同於金色的 RGB:
context.fillStyle = "rgb(255, 215, 0)";
以下是設定 fillStyle 的其他幾種方式。
如果可用,您可以使用預先定義的色彩,例如 "yellow"、"orange"、"purple" 等等:
context.fillStyle = "gold";
或者,使用十六進位的形式來表示 #RRGGBB 色彩:
context.fillStyle = "#FFD700";
這個十六進位的數字代表深金色。
雖然不算是一種色彩,但是您可以為您的 fillStyle 使用漸層:
var myGradient=context.createLinearGradient(20, 20, 100, 0); myGradient.addColorStop(0,"goldenrod"); myGradient.addColorStop(1,"white"); context.fillStyle = myGradient;
這個範例會建立線性漸層、設定色彩漸變點,然後使用從金黃色漸淡到白色的色彩繪製矩形。
預設 fillStyle 為純黑。
接下來,我們要使用 fillRect 方法,實際繪製矩形。fillRect 值會將矩形左上角的 x 和 y 座標設定為 15, 15,以開始繪製實心矩形。x, y 座標相對於畫布的左上角。 矩形的寬度和高度分別設定成 55 和 50 個像素:
context.fillRect (15, 15, 55, 50);
對於第二個矩形,fillStyle 則設為相當於紫色的 RGB。第四個值 “A” (或 RGBA 的 Alpha) 設為 0.5,並決定色彩不透明度。有效的 Alpha 值為 0.0 (完全透明) 到 1.0 (完全不透明):
context.fillStyle = "rgba(0, 0, 200, 0.5)"
fillRect 值會從矩形左上角的 x 和 y 座標 (40, 40) 開始繪製。矩形的寬度和高度分別設定成 45 和 40 個像素:
context.fillRect (40, 40, 45, 40);
以下是完整的程式碼範例:
這是 JavaScript 程式碼。在我們的範例中,此檔案命名為 myJavascript.js:
window.onload = draw;
// This function is called on page load.
function draw() {
// Get the canvas element.
var canvas = document.getElementById("canvas");
// Specify a 2d drawing context.
var context = canvas.getContext("2d");
// Set the color to the RGB equivalent of gold.
context.fillStyle = "rgb(255, 215, 0)";
// Draw the rectangle.
context.fillRect (15, 15, 55, 50);
// Set the color to the RGB equivalent of purple and
// set the opacity of the rectangle to 50 percent.
context.fillStyle = "rgba(0, 0, 200, 0.5)"
// Draw the rectangle.
context.fillRect (40, 40, 45, 40);
}
這是 HTML 檔案:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="myJavascript.js" defer="defer"></script>
<link Rel="stylesheet" Href="myStyle.css" Type="text/css">
</head>
<body>
<canvas id="canvas" width="100" height="100" />
</body>
</html>
使用路徑
beginPath 方法會開始一個新路徑,並使用其他方法 (例如 moveTo、lineTo 或 arc) 來繪製線條、曲線和其他形狀的組合。
一旦路徑建立之後,您就可以使用 fillStyle 或 strokeStyle 方法,將路徑轉譯為畫布。
範例
此範例將使用繪製棕色三角形:
我們將使用第一個範例所使用的相同 HTML 和 CSS 檔案。 在我們的 myJavascript JavaScript 檔案中,我們將使用相同的繪製函式,在載入 HTML 之後再次進行呼叫。
取得 Canvas 元素並指定 2D 畫布類型之後,我們透過呼叫 beginPath 方法開始繪製棕色三角形。
context.beginPath();
路徑在內部會儲存為子路徑的清單 (線條、弧形等),這些路徑結合在一起會形成形狀。每次呼叫 beginPath 方法時都會重設此清單,讓我們可以開始繪製新的形狀。
繪製任何線條之前,您需要呼叫 moveTo 函式。 moveTo 函式不會繪製任何東西,它就像是在您要開始繪製三角形的點上放一支筆一樣。
context.moveTo(28, 20);
moveTo 接受兩個引數,也就是 x 和 y 座標。 這裡,我們已經將 x 座標設為 28,y 座標設為 20。這些座標相對於您要在畫布上繪製的框線。
現在,我們將使用 lineTo 函式來繪製三角形的線條。 lineTo 函式就像 moveTo 函式一樣,有兩個引數,也就是 x 和 y 座標,這兩個座標是我們要繪製的線條的端點:
context.lineTo(78, 50);
context.lineTo(28, 78);
context.lineTo(28, 20);
在我們的範例中,我們將 fillStyle 屬性設定為表示棕色的十六進位值。 如同我們在<繪製矩形>一節的討論,fillStyle 屬性可以是 RGB、十六進位色彩、預先定義的色彩或漸層。
context.fillStyle = "#996633";
我們將使用 fillStyle,將三角形繪製成純棕色。 我們可以使用只繪製形狀外框的 strokeStyle 函式。
現在,繪製三角形。
context.fill();
以下是完整的 JavaScript 程式碼:
// Get the canvas element.
var canvas = document.getElementById("canvas");
// Specify a 2-D canvas type.
var context = canvas.getContext("2d");
// Add the brown triangle.
context.beginPath();
context.moveTo(28, 20);
context.lineTo(78, 50);
context.lineTo(28, 78);
context.lineTo(28, 20);
// Set the color to the hexadecimal equivalent of brown.
// Omit this step and the triangle will render
// the default color of black.
context.fillStyle = "#996633";
// Draw the triangle.
context.fill();
繪製弧形
若要繪製弧形或圓形,我們使用 arc 方法:
context.arc(x, y, radius, startingAngle, endingAngle, antiClockwise);
此方法需要五個參數:
- x 和 y 是圓心的座標。
- 半徑是圓心到圓形上某一點的距離。
- startingAngle 和 endingAngle 參數會定義弧形中弧度的起點和終點,這些弧度都是從 x 軸計算得來的。
- anticlockwise 參數是一個布林值,如果為 true,會以逆時針方向繪製弧形,否則以順時針方向繪製。
範例
此範例將繪製藍色圓形。
取得 Canvas 元素並指定 2D 畫布類型之後,我們透過呼叫 beginPath 方法開始繪製圓形。
context.beginPath();
在先前的矩形和三角形範例中,我們使用 fillStyle 函式填入形狀,並為其著色。 在此範例中,我們將 RGB 色彩設定為藍色,並使用 strokeStyle 只繪製圓形的外框。
// Define the stroke color in RGB for blue.
context.strokeStyle = "rgb(0, 162, 232)";
弧形函式的定義如下:
// Define the circle using an arc.
context.arc(50, 50, 32, 0, 2 * Math.PI, true);
其中:
- x 和 y 座標將圓心分別放在 50, 50。
- 圓形的半徑設定為 32。
- 圓形的開頭與結尾分別設定為 0 和 "2 * Math.PI" 半徑,這就是一個完整的圓形。
- anticlockwise 參數設定為 true,繪製完整的圓形時不是非常重要,但在繪製弧形部分時,這就非常重要。
最後,stroke 函式是用來繪製我們剛才所定義的圓形:
// draw the circle.
context.stroke();
以下是我們僅繪製 ½ 的弧形,或從零繪製到 Math.PI 時的圓形外觀:
// Define the circle using an arc.
context.arc(50, 50, 32, 0, Math.PI, true);
以下是 JavaScript 程式碼。 再說一次,這個程式碼會包含在載入 HTML 頁面之後呼叫的繪製函式中。 如需 HTML 或 JavaScript 檔案的完整範例,請參閱<繪製矩形>一節。
// Get the canvas element.
var canvas = document.getElementById("canvas");
// Specify a 2-D canvas type.
var context = canvas.getContext("2d");
// Start the path.
context.beginPath();
// Define the stroke color in RGB for blue.
context.strokeStyle = "rgb(0, 162, 232)";
// Define the circle using an arc.
context.arc(50, 50, 32, 0, 2 * Math.PI, true);
// draw the circle.
context.stroke();
繪製曲線
曲線是用來繪製複雜的形狀。 曲線有兩種,分別是貝茲曲線 (或立方曲線) 和 quadratic 曲線。 兩者在畫布上都有起點和終點,不過,曲線的繪製方式取決於一個或多個控制點。quadratic 曲線有一個控制點,而貝茲立方曲線則使用兩個控制點。曲線永遠包含在路徑中。
二次方曲線
以下是 quadraticCurveTo 方法:
quadraticCurveTo(cp1x, cp1y, X, Y)
四個參數是兩組 X, Y 座標,第一組 cp1x 和 cp1y 是控制點在曲線上的位置,而第二組則是曲線終點的位置。
如同所有形狀,曲線是從 moveTo(x, y) 方法開始,這個方法會為曲線的起點提供 x 和 y 座標。
兩條正切虛線是從終點繪製到控制點。 此曲線是在線條圍繞著正切移動時,透過該線條所繪製:
範例
此範例使用一連串的 quadraticCurveTo 方法來繪製具有波浪基底的抽象圖形。請注意,控制點到終點的距離越近,曲線在波浪基底中會變得越小。
我們從取得 Canvas 元素,然後指定 2D 畫布類型開始。接著,我們要透過呼叫 beginPath 方法建立路徑。
context.beginPath();
然後,將第一條曲線的起點分別設定在 x 座標的 75 和 y 座標的 25。
context.moveTo(75, 25);
每條 quadratic 曲線的設定如下:
context.quadraticCurveTo(10, 80, 40, 130);
context.quadraticCurveTo(30, 90, 50, 130);
context.quadraticCurveTo(50, 100, 70, 130);
context.quadraticCurveTo(80, 110, 100, 130);
context.quadraticCurveTo(120, 120, 140, 130);
其中,每一個參數是:
cp1x
控制點的 x-座標。cp1y
控制點的 y-座標。x
曲線終點的 x 座標。y
曲線終點的 y 座標。
請注意,曲線的繪製順序很重要。 您可以移除一或二條曲線,或者變更它們的繪製順序,就可以看到曲線的構成方式。
將 fillStyle 設定為等同於綠色的 RGB 值,就可以將色彩設定為綠色。
context.fillStyle = "rgb(100, 200, 50)";
最後,此形狀是以 fill 函式著色:
context.fill();
請注意,針對這一個和下一個範例,此曲線的大小已增加到 150 x 150 個像素:
<canvas id="canvas" width="150" height="150" />
以下是完整的範例:
// Get the canvas element.
var canvas = document.getElementById("canvas");
// Specify a 2-D canvas type.
var context = canvas.getContext("2d");
// Create the path.
context.beginPath();
// Set the starting point for the curve.
context.moveTo(75,25);
// Set each of the curves.
context.quadraticCurveTo(10, 80, 40, 130);
context.quadraticCurveTo(30, 90, 50, 130);
context.quadraticCurveTo(50, 100, 70, 130);
context.quadraticCurveTo(80, 110, 100, 130);
context.quadraticCurveTo(120, 120, 140, 130);
// Set the color of the image to green.
context.fillStyle = "rgb(100, 200, 50)";
// Draw the image.
context.fill();
貝茲立方曲線
以下是 bezierCurveTo 方法:
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
六個參數是三組 X, Y 座標;cp1x 和 cp1y 是第一個控制點在曲線上的位置、cp2x 和 cp2y 是第二個控制點的位置,而第三組則是曲線終點的位置。
曲線從 moveTo(x, y) 方法中的 x 和 y 座標開始。
正切虛線是從控制點繪製到終點。 此曲線是在線條圍繞著正切線條移動時,透過該線條所繪製,如圖例中的紫色線條所示:
範例
此範例使用一連串的 bezierCurveTo 方法來繪製具有波浪基底的抽象圖形。
取得 Canvas 元素並指定 2D 畫布類型之後,我們透過呼叫 beginPath 方法來建立路徑。
context.beginPath();
然後,將第一條曲線的起點分別設定在 x 座標的 75 和 y 座標的 25。
context.moveTo(75, 25);
每條貝茲立方曲線的設定如下:
context.bezierCurveTo(10, 100, 10, 122, 20, 130);
context.bezierCurveTo(20, 100, 20, 122, 30, 130);
context.bezierCurveTo(40, 100, 40, 122, 50, 130);
context.bezierCurveTo(70, 100, 70, 122, 80, 130);
context.bezierCurveTo(110, 100, 110, 122, 120, 130);
context.bezierCurveTo(160, 100, 160, 122, 170, 130);
其中,每一個參數是:
cp1x
第一個貝茲控制點的 x-座標。cp1y
第一個貝茲控制點的 y-座標。cp2x
第二個貝茲控制點的 x-座標。cp2y
第二個貝茲控制點的 y-座標。x
曲線終點的 x 座標。y
曲線終點的 y 座標。
請注意,曲線的繪製順序很重要。 您可以移除一或二條曲線,或者變更它們的繪製順序,就可以看到曲線的構成方式。
將 fillStyle 設定為等同於紅色的 RGB 值,就可以將色彩設定為紅色。
context.fillStyle = "rgb(200, 0, 0)";
最後,此形狀是以 fill 函式著色:
context.fill();
請注意,針對這個範例,此曲線的大小已增加到 150 x 150 個像素:
<canvas id="canvas" width="150" height="150" />
以下是完整的程式碼範例:
// Get the canvas element.
var canvas = document.getElementById("canvas");
// Specify a 2-D canvas type.
var context = canvas.getContext("2d");
// Create the path.
context.beginPath();
// Set the starting point for the curve.
context.moveTo(75, 25);
// Set each of the curves.
context.bezierCurveTo(10, 100, 10, 122, 20, 130);
context.bezierCurveTo(20, 100, 20, 122, 30, 130);
context.bezierCurveTo(40, 100, 40, 122, 50, 130);
context.bezierCurveTo(70, 100, 70, 122, 80, 130);
context.bezierCurveTo(110, 100, 110, 122, 120, 130);
context.bezierCurveTo(160, 100, 160, 122, 170, 130);
// Set the color of the image to red.
context.fillStyle = "rgb(200, 0, 0)";
// Draw the image.
context.fill();
後續步驟
在此快速入門中,我們新增 Canvas 元素來建立透明的繪圖表面、使用 CSS 在 Canvas 元素周圍建立框線,而且使用 JavaScript 在 Canvas 元素上繪製圖形影像。
我們從 Canvas 元素取得 2D 繪圖內容,讓我們可以設定 fillRect 和 fillStyle 來繪製矩形。我們使用多種方式設定 fillStyle 為圖形著色,例如 RGB、十六進位值、預先定義的色彩以及漸層。
我們看到 beginPath 方法如何開始新路徑,並使用其他方法 (例如 moveTo、lineTo 或 arc) 繪製線條、圓形和曲線的組合。
一旦路徑建立之後,我們就使用 fillStyle 和 strokeStyle 方法,將路徑轉譯為畫布。
接下來,您將學習如何讓畫布圖形產生動畫效果,以及如何建立漸層。