快速入门:绘制到画布 (HTML)
[ 本文适用于编写 Windows 运行时应用的 Windows 8.x 和 Windows Phone 8.x 开发人员。如果你要针对 Windows 10 进行开发,请参阅 最新文档 ]
canvas 元素在页面上生成一个矩形的位图画布,在该画布上,可以使用 JavaScript 实时绘制图形图像。画布非常适合创建游戏,还非常适合实时收集图形或定期更改图形的情形。
本快速入门包含以下部分:
- 先决条件
- canvas 元素
- 呈现上下文
- 绘制矩形
- 使用路径
- 绘制弧形
- 绘制曲线
- 二次曲线
- 贝赛尔三次曲线
- 后续步骤
先决条件
本主题假设你可以创建包含 Windows JavaScript 库模板且采用 JavaScript 的基本 Windows 应用商店风格应用,而且你对 HTML 和 JavaScript 有基本的了解。有关创建第一个采用 JavaScript 的 Windows 应用商店应用的说明,请参阅创建第一个 Web 应用。有关使用 WinJS 模板的说明,请参阅“如何获取和使用 WinJS 工具包”。
canvas 元素
canvas 元素在你的页面上生成一个矩形的位图画布,在该画布上,可以使用 JavaScript 实时呈现图形图像。
canvas 元素具有 width 和 height 属性。 这两个属性都是可选的,而且都可以使用文档对象模型 (DOM) 属性进行设置。 如果你未设置 width 和 height 属性,则画布会以其默认大小(width 和 height 分别为 300 个像素和 150 个像素)显示。
<canvas id="canvas" width="150" height="150"></canvas>
id 属性不属于 canvas 元素,但它可用于标识脚本中的 canvas 元素。
你可以使用级联样式表 (CSS) 设置画布的大小。默认情况下,你的应用呈现没有任何内容和边框的 canvas 元素(即完全透明的 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 参数是用来在画布上对矩形进行定位的坐标,它们是相对于画布的左上角的。 width 和 height 是以像素度量的。
-
strokeRect(x, y, width, height)
strokeRect 的参数与 fillRect 的参数基本相同, 区别位于 strokeRect 仅绘制矩形的轮廓。
以下方法设置指定形状的颜色:
-
fillStyle = color
fillStyle 方法使用单个参数来用颜色填充形状。颜色可以使用 RGB、预定义的颜色(如红色、蓝色等)、十六进制颜色或者甚至渐变来设置。有关 fillStyle 示例,请参阅下面的“绘制矩形”示例。
以下方法清除指定的区域并使其完全透明:
-
clearRect(x, y, width, height)
与 fillRect 和 strokeRect 与方法一样,clearRect 的 x 和 y 参数用来定位要清除的矩形区域,width 和 height 用来设置该矩形的宽度和高度。
示例
让我们从这样一个示例开始:创建一个画布,并绘制两个填充正方形(一个是金色正方形,一个是透明的紫色正方形)。我们将使用 CSS 在画布周围创建黑色边框:
该示例首先在 HTML 的 <body> 部分中声明一个 canvas 元素。为该 canvas 元素分配一个名为“canvas”的 id 属性,并将该元素的 height 和 width 属性设置为 100 个像素:
<body>
<canvas id="canvas" width="100" height="100" />
</body>
该 canvas 元素是使用 CSS 创建的,它的宽度为 1 个像素,而且具有黑色实线边框。该 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 方法来获取绘制上下文。 你必须向 getContext 方法传递字符串“2d”。
每个画布都有一个绘制上下文。绘制上下文是指在其中定义所有绘制方法和属性的位置。
// 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:RGBA 中的第四个值“A”(表示 Alpha)设置为 0.5,用来确定颜色的不透明度。有效 Alpha 值的范围是从 0.0(完全透明)到 1.0(完全不透明):
context.fillStyle = "rgba(0, 0, 200, 0.5)"
fillRect 值首先在“40, 40”处绘制矩形左上角的 x 和 y 坐标。矩形的宽度和高度分别设置为 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 文件中,我们将使用与第一个示例中相同的 draw 函数,而且将在加载 HTML 之后再次调用该函数。
在获取 canvas 元素并指定 2D 画布类型之后,我们将通过调用 beginPath 方法来开始绘制棕色三角形。
context.beginPath();
在内部,路径存储为在一起构成形状的子路径(直线、弧等)的列表。每当调用 beginPath 方法时,该列表都会重置,我们都将开始绘制新形状。
在绘制任何直线之前,都将需要调用 moveTo 函数。 moveTo 函数不绘制任何内容,它类似于将钢笔或铅笔放在要开始绘制三角形的点。
context.moveTo(28, 20);
moveTo 采用两个参数:x 坐标和 y 坐标。 在这里,我们已将 x 坐标和 y 坐标分别设置为 28 和 20。这两个坐标相对于要在其上进行绘制的画布的边框。
现在,我们将使用 lineTo 函数绘制三角形的边。 与 moveTo 函数一样,lineTo 函数也包含两个参数(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 是圆心的坐标。
- radius 是圆心距离圆上各点的距离。
- 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)";
arc 函数按如下方式定义:
// 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 代码。 此代码也是将包含在一个 draw 函数中,该函数将在加载 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 和 y 坐标分别设置为 75 和 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();
请注意,在此示例和下一个示例中,画布的大小已经增加至 150x150 像素:
<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 和 y 坐标分别设置为 75 和 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();
请注意,在此示例中,画布的大小已经增加至 150x150 像素:
<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 来绘制矩形。我们以各种图形着色方式(如 RGB、十六进制值、预定义颜色和渐变)设置了 fillStyle。
我们看到了如何使用 beginPath 方法开始绘制新路径,以及如何使用其他方法(如 moveTo、lineTo 或 arc)绘制直线、圆和曲线的组合。
在创建路径之后,我们使用 fillStyle 和 strokeStyle 方法将路径呈现到了画布上。
接着,你将学习如何对画布图形进行动画处理,以及如何创建渐变。