canvas 的基本用法

在本教程的开头,我们将了解 <canvas> HTML 元素本身。在本页的结尾,您将知道如何设置 canvas 2D 上下文,并已在浏览器中绘制了第一个示例。

<canvas> 元素

html
<canvas id="canvas" width="150" height="150"></canvas>

乍一看,<canvas> 看起来像 <img> 元素,唯一的明显区别是它没有 srcalt 属性。事实上,<canvas> 元素只有两个属性:widthheight。这两个属性都是可选的,也可以使用 DOM 属性设置。如果没有指定 widthheight 属性,canvas 的初始宽度将是300 像素,高度将是150 像素。该元素可以通过 CSS 任意调整大小,但在渲染时,图像会被缩放到以适应其布局大小:如果 CSS 大小不遵循初始 canvas 的比例,它就会显得失真。

注意:如果您的渲染看起来失真,请尝试在 <canvas> 属性中显式指定 widthheight 属性,而不是使用 CSS。

id 属性不特定于 <canvas> 元素,而是 全局 HTML 属性之一,可以应用于任何 HTML 元素(例如,class)。提供 id 始终是个好主意,因为这使得在脚本中识别它更加容易。

<canvas> 元素可以像任何普通图像一样进行样式设置(marginborderbackground…)。然而,这些规则不会影响 canvas 上的实际绘制。我们将在本教程的专门章节中了解如何进行绘制。当没有将任何样式规则应用于 canvas 时,它最初将是完全透明的。

可访问内容

<canvas> 元素,与其他元素如 <img><video><audio><picture> 元素一样,必须通过提供备用文本来使其可访问,以便在媒体加载失败或用户无法按预期体验时显示。您应始终提供备用内容、字幕和替代文本,具体取决于媒体类型。

提供备用内容非常简单:只需将替代内容插入到 <canvas> 元素内部,供屏幕阅读器、爬虫和其他自动化机器人访问。默认情况下,浏览器会忽略容器内的内容,正常渲染 canvas,除非 <canvas> 不受支持。

例如,我们可以提供 canvas 内容的文本描述,或提供动态渲染内容的静态图像。这看起来可能像这样

html
<canvas id="stockGraph" width="150" height="150">
  current stock price: $3.15 + 0.15
</canvas>

<canvas id="clock" width="150" height="150">
  <img src="images/clock.png" width="150" height="150" alt="A clock" />
</canvas>

告诉用户使用支持 canvas 的不同浏览器,对完全无法读取 canvas 的用户没有帮助。提供有用的备用文本或子 DOM 会为本来不可访问的元素增加可访问性。

必需的 </canvas> 标签

由于备用内容提供的机制,与 <img> 元素不同,<canvas> 元素需要闭合标签(</canvas>)。如果缺少此标签,则文档的其余部分将被视为备用内容,并且不会显示。

如果不需要备用内容,一个简单的 <canvas id="foo" role="presentation" …></canvas> 与所有支持 canvas 的浏览器完全兼容。这仅应用于 canvas 纯粹用于展示的情况。

渲染上下文

<canvas> 元素创建了一个固定大小的绘图表面,它公开了一个或多个渲染上下文,用于创建和操作显示的内容。在本教程中,我们将重点介绍 2D 渲染上下文。其他上下文可能提供不同类型的渲染;例如,WebGL 使用基于 OpenGL ES 的 3D 上下文。

canvas 最初是空白的。要显示内容,脚本首先需要访问渲染上下文并在其上绘制。<canvas> 元素有一个名为 getContext() 的方法,用于获取渲染上下文及其绘图功能。getContext() 接受一个参数,即上下文的类型。对于本教程涵盖的 2D 图形,您指定 "2d" 来获取一个 CanvasRenderingContext2D

js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

脚本中的第一行通过调用 document.getElementById() 方法来检索 DOM 中表示 <canvas> 元素的节点。一旦您获得了元素节点,就可以通过其 getContext() 方法访问绘图上下文。

检查支持情况

在不支持 <canvas> 的浏览器中会显示备用内容。脚本也可以通过测试 getContext() 方法的存在来以编程方式检查支持情况。我们上面的代码片段会变成这样

js
const canvas = document.getElementById("canvas");

if (canvas.getContext) {
  const ctx = canvas.getContext("2d");
  // drawing code here
} else {
  // canvas-unsupported code here
}

一个骨架模板

这是一个极简的模板,我们将以此为基础进行后续示例。

注意:将脚本嵌入 HTML 中不是一个好做法。我们在这里这样做是为了保持示例简洁。

html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>Canvas tutorial</title>
    <style>
      canvas {
        border: 1px solid black;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas" width="150" height="150"></canvas>
    <script>
      function draw() {
        const canvas = document.getElementById("canvas");
        const ctx = canvas.getContext("2d");
      }
      draw();
    </script>
  </body>
</html>

该脚本包含一个名为 draw() 的函数,该函数在页面加载完成后执行;这是通过将脚本放在主要内容之后实现的。此函数或类似函数也可以使用 setTimeout()setInterval()load 事件处理程序调用,只要页面已先加载。

此时,此文档应显示为空白。

一个简单的例子

首先,让我们看一个绘制两个相交矩形的示例,其中一个矩形具有 alpha 透明度。我们将在后面的示例中详细探讨其工作原理。将您的 script 元素内容更新为此

js
function draw() {
  const canvas = document.getElementById("canvas");
  const ctx = canvas.getContext("2d");

  ctx.fillStyle = "rgb(200 0 0)";
  ctx.fillRect(10, 10, 50, 50);

  ctx.fillStyle = "rgb(0 0 200 / 50%)";
  ctx.fillRect(30, 30, 50, 50);
}
draw();

这个示例看起来是这样的