recursal/MDN huggingface dataset:
BarcodeDetector：detect() 方法
===========================

**安全上下文:** 此项功能仅在一些支持的浏览器的安全上下文（HTTPS）中可用。

**备注：** 此特性在 Web Worker 中可用

**实验性:** **这是一项实验性技术**  
在将其用于生产之前，请仔细检查浏览器兼容性表格。

`BarcodeDetector` 接口的 **`detect()`** 方法返回一个 `Promise`，它兑现一个从图像中检测到的条形码的数组。

语法
--


```js
detect(imageBitmapSource)
```

### 参数

`imageBitmapSource`

接受一个图像源作为参数；它可以是以下对象之一：`HTMLImageElement`、`SVGImageElement` (en-US)、`HTMLVideoElement`、`HTMLCanvasElement`、`ImageBitmap`、`OffscreenCanvas`、`VideoFrame` (en-US)、`Blob` 格式的图像或 `ImageData`。

### 返回值

返回一个 `Promise`，它兑现一个具有以下属性的 `DetectedBarcode` 对象数组：

`boundingBox`

一个 `DOMRectReadOnly`，返回表示检测到的条形码范围的矩形尺寸，与图像对齐。

`cornerPoints`

检测到的条形码的四个角点相对于图像的 x 和 y 坐标，从左上角开始顺时针旋转。由于图像内的透视变形，这可能不是方形的。

`format`

检测到的条形码格式。（有关格式的完整列表，请参阅受支持的条形码格式类型）

`rawValue`

一个从条形码数据解码的字符串。

### 异常

`TypeError`

如果未指定参数或 `type` 参数不是一个 `ImageBitmapSource` 类型，抛出此异常。

`SecurityError` `DOMException`

如果 `imageBitmapSource` 有源并且与文档的源不同，或者如果 `imageBitmapSource` 是一个 `HTMLCanvasElement` 及其 origin-clean 标志设置为 `false`，抛出此异常。

`InvalidStateError` `DOMException`

如果 `imageBitmapSource` 是一个 `HTMLImageElement` 并且未完全解码或解码失败，或者是一个 `HTMLVideoElement` 并且其 `readyState` 属性是 `HAVE_NOTHING` 或 `HAVE_METADATA`，抛出此异常。

示例
--

此示例使用 `detect()` 方法来检测给定图像中的条形码。识别结果被迭代并且条形码数据被记录到控制台。


```js
barcodeDetector
  .detect(imageEl)
  .then((barcodes) => {
    barcodes.forEach((barcode) => console.log(barcode.rawValue));
  })
  .catch((err) => {
    console.error(err);
  });
```

规范
--

| Specification |
| --- |
| Accelerated Shape Detection in Images # dom-barcodedetector-detect |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.
BarcodeDetector：getSupportedFormats() 静态方法
==========================================

**安全上下文:** 此项功能仅在一些支持的浏览器的安全上下文（HTTPS）中可用。

**备注：** 此特性在 Web Worker 中可用

**实验性:** **这是一项实验性技术**  
在将其用于生产之前，请仔细检查浏览器兼容性表格。

`BarcodeDetector` 接口的 **`getSupportedFormats()`** 静态方法返回一个 `Promise`，它兑现一个包含受支持的条形码格式类型的数组。

语法
--


```js
BarcodeDetector.getSupportedFormats()
```

### 参数

该方法不接收任何参数。

### 返回值

一个 `Promise`，它兑现一个包含受支持的条形码格式类型的数组。

### 异常

不会抛出任何异常。

示例
--

以下示例调用 `getSupportedFormats()` 方法并将结果记录到控制台。


```js
// 检查支持的类型
BarcodeDetector.getSupportedFormats().then((supportedFormats) => {
  supportedFormats.forEach((format) => console.log(format));
});
```

规范
--

| Specification |
| --- |
| Accelerated Shape Detection in Images # dom-barcodedetector-getsupportedformats |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.
DataTransferItemList.length
===========================

`DataTransferItemList` 接口的只读属性\*\*`length`\*\* 返回当前拖动项列表中项目的数量。

语法
--
```

length = DataTransferItemList.length;
```

### 值

列表中拖动项的数量，如果列表为空或禁用则为 0。如果列表的`DataTransfer`对象未与拖动数据存储关联，则认为拖动列表被禁用。

示例
--

这个例子演示了 `length` 属性的用法。

### JavaScript


```js
function dragstart\_handler(ev) {
  console.log("dragStart");
  // Add this element's id to the drag payload so the drop handler will
  // know which element to add to its tree
  var dataList = ev.dataTransfer.items;
  dataList.add(ev.target.id, "text/plain");
  // Add some other items to the drag payload
  dataList.add("<p>... paragraph ...</p>", "text/html");
  dataList.add("http://www.example.org", "text/uri-list");
}

function drop\_handler(ev) {
  console.log("Drop");
  ev.preventDefault();
  var data = ev.dataTransfer.items;
  // Loop through the dropped items and log their data
  for (var i = 0; i < data.length; i++) {
    if (data[i].kind == "string" && data[i].type.match("^text/plain")) {
      // This item is the target node
      data[i].getAsString(function (s) {
        ev.target.appendChild(document.getElementById(s));
      });
    } else if (data[i].kind == "string" && data[i].type.match("^text/html")) {
      // Drag data item is HTML
      data[i].getAsString(function (s) {
        console.log("... Drop: HTML = " + s);
      });
    } else if (
      data[i].kind == "string" &&
      data[i].type.match("^text/uri-list")
    ) {
      // Drag data item is URI
      data[i].getAsString(function (s) {
        console.log("... Drop: URI = " + s);
      });
    }
  }
}

function dragover\_handler(ev) {
  console.log("dragOver");
  ev.preventDefault();
  // Set the dropEffect to move
  ev.dataTransfer.dropEffect = "move";
}

function dragend\_handler(ev) {
  console.log("dragEnd");
  var dataList = ev.dataTransfer.items;
  // Clear any remaining drag data
  dataList.clear();
}
```

### HTML


```html
<div>
  <p
 id="source"
 ondragstart="dragstart\_handler(event);"
 ondragend="dragend\_handler(event);"
 draggable="true">
    Select this element, drag it to the Drop Zone and then release the selection
    to move the element.
  </p>
</div>
<div
 id="target"
 ondrop="drop\_handler(event);"
 ondragover="dragover\_handler(event);">
  Drop Zone
</div>
```

### CSS


```css
div {
  margin: 0em;
  padding: 2em;
}

#source {
  color: blue;
  border: 1px solid black;
}

#target {
  border: 1px solid black;
}
```

### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-datatransferitemlist-length-dev |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.
结构化克隆算法
=======

**结构化克隆算法**用于复制复杂 JavaScript 对象的算法。通过来自 Worker 的 `postMessage()` 或使用 IndexedDB 存储对象时在内部使用。它通过递归输入对象来构建克隆，同时保持先前访问过的引用的映射，以避免无限遍历循环。

结构化克隆所不能做到的
-----------

* `Function` 对象是不能被结构化克隆算法复制的；如果你尝试这样子去做，这会导致抛出 `DATA_CLONE_ERR` 的异常。
* 企图去克隆 DOM 节点同样会抛出 `DATA_CLONE_ERR` 异常。
* 对象的某些特定参数也不会被保留
    + `RegExp` 对象的 `lastIndex` 字段不会被保留
    + 属性描述符，setters 以及 getters（以及其他类似元数据的功能）同样不会被复制。例如，如果一个对象用属性描述符标记为 read-only，它将会被复制为 read-write，因为这是默认的情况下。
    + 原形链上的属性也不会被追踪以及复制。
支持的类型
-----

### JavaScript 类型

* `Array`
* `ArrayBuffer`
* `Boolean`
* `DataView`
* `Date`
* `Error` 类型（仅限部分 Error 类型）。
* `Map`
* `Object` 对象：仅限简单对象（如使用对象字面量创建的）。
* 除 `symbol` 以外的基本类型。
* `RegExp`：`lastIndex` 字段不会被保留。
* `Set`
* `String`
* `TypedArray`

#### Error 类型

仅支持以下 `Error` 类型：Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError（或其他会被设置为 `Error` 的）。

浏览器必须序列化 `name` 和 `message` 字段，其他有意义的字段则可能会序列化，如 `stack`、`cause` 等。

AggregateError 预计会在 whatwg/html#5749 被添加到标准中（并且已被部分浏览器所支持）。

参见
--

* HTML 规范：安全地传递结构化数据
* 可转移对象
* `structuredClone()`
* `window.history`
* `window.postMessage()`
* Web Worker
* IndexedDB
可转移对象
=====

**可转移的对象**（Transferable object）是拥有属于自己的资源的对象，这些资源可以从一个上下文*转移*到另一个，确保资源一次仅在一个上下文可用。传输后，原始对象不再可用；它不再指向转移后的资源，并且任何读取或者写入该对象的尝试都将抛出异常。

*可转移对象*通常用于共享资源，该资源一次仅能安全地暴露在一个 JavaScript 线程中。例如，`ArrayBuffer` 是一个拥有内存块的可转移对象。当此类缓冲区（buffer）在线程之间传输时，相关联的内存资源将从原始的缓冲区分离出来，并且附加到新线程创建的缓冲区对象中。原始线程中的缓冲区对象不再可用，因为它不再拥有属于自己的内存资源了。

使用 `structuredClone()` 创建对象的深层拷贝时，也可以使用转移。克隆操作后，传输的资源将被移动到克隆的对象，而不是复制。

使用转移对象资源的机制取决于对象自身。例如，当 `ArrayBuffer` 在线程之间转移时，它指向的内存资源*实际上*以快速且高效的零拷贝操作在上下文之间移动。其他对象可以通过拷贝关联的资源，然后将它从旧的上下文中删除来转移它。

并不是所有的对象都是可转移的。下面提供了可转移对象的列表。

在线程之间传输对象
---------

以下代码演示了当消息从主线程发送到 web worker 线程时，传输是如何工作的。`Uint8Array` 在其缓冲区被转移时，被拷贝到 worker 中。传输后，任何尝试从主线程读或者写 `uInt8Array` 都将抛出错误，但是你仍然可以检查 `byteLength` 以确定它现在是 0。


```js
// Create an 8MB "file" and fill it. 8MB = 1024 \* 1024 \* 8 B
const uInt8Array = new Uint8Array(1024 \* 1024 \* 8).map((v, i) => i);
console.log(uInt8Array.byteLength); // 8388608

// Transfer the underlying buffer to a worker
worker.postMessage(uInt8Array, [uInt8Array.buffer]);
console.log(uInt8Array.byteLength); // 0
```


**备注：** 像 `Int32Array` 和 `Uint8Array` 等类型化数组是可序列化的，但是不能转移。然而，它们的底层缓冲区是一个 `ArrayBuffer`，它是一个可转移对象。我们可以在数据参数中发送 `uInt8Array.buffer`，但是不能在传输数组中发送 `uInt8Array`。

### 在进行克隆操作时转移

以下代码展示了 `structuredClone()` 操作，将底层缓冲区从原始对象复制到克隆对象（`clone`）。


```js
const original = new Uint8Array(1024);
const clone = structuredClone(original);
console.log(original.byteLength); // 1024
console.log(clone.byteLength); // 1024

original[0] = 1;
console.log(clone[0]); // 0

// Transferring the Uint8Array would throw an exception as it is not a transferable object
// const transferred = structuredClone(original, {transfer: [original]});

// We can transfer Uint8Array.buffer.
const transferred = structuredClone(original, { transfer: [original.buffer] });
console.log(transferred.byteLength); // 1024
console.log(transferred[0]); // 1

// After transferring Uint8Array.buffer cannot be used.
console.log(original.byteLength); // 0
```

支持的对象
-----

以下是可以被*转移*的不同规范的对象：

* `ArrayBuffer`
* `MessagePort`
* `ReadableStream`
* `WritableStream`
* `TransformStream`
* `AudioData` (en-US)
* `ImageBitmap`
* `VideoFrame` (en-US)
* `OffscreenCanvas`
* `RTCDataChannel`

在各自对象的兼容性信息中，如果拥有 `transferable` 子特性，浏览器的支持应该被展示（示例请参阅 `RTCDataChannel`）。在撰写本文时，并非所有可转移对象都已更新此信息。

**备注：** 可转移的对象在 Web IDL 文件中用属性 `[Transferable]` 标记。

参见
--

* 可转移对象：像闪电一样快！
* 使用 Web Worker
* HTML 规范中的可转移对象
* `DedicatedWorkerGlobalScope.postMessage()` (en-US)
Web Workers 可以使用的函数和类
=====================

除了标准的 JavaScript 函数集（例如 `String`、`Array`、`Object`、`JSON` 等）DOM 中的许多函数都可在 worker 中使用。本文列出了这些函数。

Worker 上下文和函数
-------------

**Worker 在另一个全局上下文中运行，与当前的 window 不同！**`Window` 并不直接在 worker 中可用，其中的很多方法都通过共享的混入（`WindowOrWorkerGlobalScope`）定义，并通过 worker 派生的 `WorkerGlobalScope` (en-US) 上下文提供这些方法：

* `DedicatedWorkerGlobalScope` 用于专用 worker
* `SharedWorkerGlobalScope` (en-US) 用于共享 worker
* `ServiceWorkerGlobalScope` 用于 service worker

一些函数在所有的 worker 和主线程中均可用（来自 `WindowOrWorkerGlobalScope`）：

* `atob()`
* `btoa()`
* `clearInterval()`
* `clearTimeout()`
* `dump()` 
非标准
* `queueMicrotask()`
* `setInterval()`
* `setTimeout()`
* `structuredClone()`
* `window.requestAnimationFrame`（仅专用 worker）
* `window.cancelAnimationFrame`（仅专用 worker）

以下函数**仅**在 worker 中可用：

* `WorkerGlobalScope.importScripts()`（所有的 worker）
* `DedicatedWorkerGlobalScope.postMessage` (en-US)（仅专用 worker）
Worker 中可用的 Web API
-------------------

**备注：** 如果列出的 API 被某一平台的特定版本所支持，那么一般可以认为它在 web worker 中是可用的。你也可以使用网站来测试对某个特定对象/函数的支持：https://worker-playground.glitch.me/

以下 Web API 在 worker 中可用：

* `Barcode Detection API`
* `Broadcast Channel API`
* `Cache API`
* `Channel Messaging API`
* `Console API`
* Web Crypto API（例如 `Crypto`）
* CSS Font Loading API
* `CustomEvent`
* `Encoding API`（例如 `TextEncoder`、`TextDecoder`）
* `Fetch API`
* `FileReader`
* `FileReaderSync`（仅在 worker 中有效！）
* `FormData`
* `ImageBitmap`
* `ImageData`
* `IndexedDB`
* Media Source Extensions API（仅限专用 worker）
* Network Information API
* `Notifications API`
* `OffscreenCanvas`（和所有的 canvas context API）
* `Performance API`，包括：
    + `Performance`
    + `PerformanceEntry`
    + `PerformanceMeasure` (en-US)
    + `PerformanceMark` (en-US)
    + `PerformanceObserver`
    + `PerformanceResourceTiming`
* Server-sent 事件
* `ServiceWorkerRegistration` (en-US)
* `URL API`（例如 `URL`）
* WebCodecs\_API
* `WebSocket`
* `XMLHttpRequest`

worker 也可以派生其他 worker，所以这些 API 也是可用的：

* `Worker`
* `WorkerGlobalScope` (en-US)
* `WorkerLocation` (en-US)
* `WorkerNavigator` (en-US)
参见
--

* 使用 web worker
* `Worker`
Canvas 教程
=========

**`<canvas>`**是一个可以使用脚本 (通常为JavaScript) 来绘制图形的 HTML 元素。例如，它可以用于绘制图表、制作图片构图或者制作简单的动画。右边的图片展示了一些 `<canvas>` 的实现示例，在这个教程后面我们将看到。

本篇教程从一些基础开始，描述了如何使用<canvas>元素来绘制 2D 图形。教程中提供的例子，会让你明白可以用 canvas 做什么，也会提供一些代码片段来帮助你开始构建自己的内容。

`<canvas>` 最早由 Apple 引入 WebKit，用于 Mac OS X 的 Dashboard，随后被各个浏览器实现。如今，所有主流的浏览器都支持它。

开始之前
----

使用 `<canvas>` 元素不是非常难，但你需要一些基本的HTML和JavaScript知识。除一些过时的浏览器不支持`<canvas>` 元素外，所有的新版本主流浏览器都支持它。Canvas 的默认大小为 300 像素 ×150 像素（宽 × 高，像素的单位是 px）。但是，可以使用 HTML 的高度和宽度属性来自定义 Canvas 的尺寸。为了在 Canvas 上绘制图形，我们使用一个 JavaScript 上下文对象，它能动态创建图像（creates graphics on the fly）。

本教程包含
-----

* 基本用法
* 绘制图形
* 使用样式与颜色
* 绘制文本
* 使用图像
* 变形
* 合成和剪辑
* 基本动画
* 高级动画
* 像素处理
* 优化 canvas
* 终曲
参见
--

* Canvas 专题页
* Adobe Illustrator to Canvas plug-in
* HTML5 Canvas 教程
* 下一页 »
终曲
==

* « 上一页

恭喜你！你已经结束了 Canvas 的教程！这些知识将帮助你在 web 中创建优秀的 2D 图形。

更多的例子以及教程
---------

下面这些网站里有关于 canvas 的各种各样的演示以及更进一步的说明：

Codepen.io

前端开发人员操练场和浏览器内的代码编辑器。

Canvasdemos.com(域名已失效)

关于 HTML5 canvas 元素的应用程序，游戏，工具和教程。

HTML5CanvasTutorials

包括大多数 canvas API 的示例。

31 days of Canvas tutorials

JavaScript 可视化编程入门的不错选择。

Game development

玩游戏是最热门的计算机活动之一。新技术不断诞生，以使开发更好更强、且能在任何符合标准的浏览器上运行的游戏变得可能。

其他的 Web API
-----------

当和 canvas 和图形进一步打交道时，这些 API 可能会排上用场。

WebGL

用于渲染交互式 3D 图形的 API.

SVG

可缩放矢量图形（简称 SVG）允许你使用矢量线，矢量图形，确保无论图片大小都可以比例平滑地显示。

Web Audio

Web Audio API 提供了 Web 上的音频控制——个强大和灵活的系统，允许开发人员选择的音频源，添加效果的音频，创建音频可视化，应用空间效应（如平移）等等。

解惑
--

Stackoverflow

到"canvas"标签来提问

Comments about this tutorial – the MDN documentation community

如果你对本教程有任何意见，或是想感谢我们，在此畅所欲言吧！

* « 上一页
组合 Compositing
==============

* « 上一页
* 下一页 »

在之前的例子里面，我们总是将一个图形画在另一个之上，对于其他更多的情况，仅仅这样是远远不够的。比如，对合成的图形来说，绘制顺序会有限制。不过，我们可以利用 `globalCompositeOperation` 属性来改变这种状况。此外，`clip`属性允许我们隐藏不想看到的部分图形。

`globalCompositeOperation`
--------------------------

我们不仅可以在已有图形后面再画新图形，还可以用来遮盖指定区域，清除画布中的某些部分（清除区域不仅限于矩形，像`clearRect()`方法做的那样）以及更多其他操作。

`globalCompositeOperation = type`

这个属性设定了在画新图形时采用的遮盖策略，其值是一个标识 12 种遮盖方式的字符串。

裁切路径
----

![](/zh-CN/docs/Web/API/Canvas_API/Tutorial/Compositing/canvas_clipping_path.png)裁切路径和普通的 canvas 图形差不多，不同的是它的作用是遮罩，用来隐藏不需要的部分。如右图所示。红边五角星就是裁切路径，所有在路径以外的部分都不会在 canvas 上绘制出来。

如果和上面介绍的 `globalCompositeOperation` 属性作一比较，它可以实现与 `source-in` 和 `source-atop`差不多的效果。最重要的区别是裁切路径不会在 canvas 上绘制东西，而且它永远不受新图形的影响。这些特性使得它在特定区域里绘制图形时相当好用。

在 绘制图形 一章中，我只介绍了 `stroke` 和 `fill` 方法，这里介绍第三个方法`clip`。

`clip()`

将当前正在构建的路径转换为当前的裁剪路径。

我们使用 `clip()`方法来创建一个新的裁切路径。

默认情况下，canvas 有一个与它自身一样大的裁切路径（也就是没有裁切效果）。

### `clip` 的例子

这个例子，我会用一个圆形的裁切路径来限制随机星星的绘制区域。


```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  ctx.fillRect(0, 0, 150, 150);
  ctx.translate(75, 75);

  // Create a circular clipping path
  ctx.beginPath();
  ctx.arc(0, 0, 60, 0, Math.PI \* 2, true);
  ctx.clip();

  // draw background
  var lingrad = ctx.createLinearGradient(0, -75, 0, 75);
  lingrad.addColorStop(0, "#232256");
  lingrad.addColorStop(1, "#143778");

  ctx.fillStyle = lingrad;
  ctx.fillRect(-75, -75, 150, 150);

  // draw stars
  for (var j = 1; j < 50; j++) {
    ctx.save();
    ctx.fillStyle = "#fff";
    ctx.translate(
      75 - Math.floor(Math.random() \* 150),
      75 - Math.floor(Math.random() \* 150),
    );
    drawStar(ctx, Math.floor(Math.random() \* 4) + 2);
    ctx.restore();
  }
}
function drawStar(ctx, r) {
  ctx.save();
  ctx.beginPath();
  ctx.moveTo(r, 0);
  for (var i = 0; i < 9; i++) {
    ctx.rotate(Math.PI / 5);
    if (i % 2 == 0) {
      ctx.lineTo((r / 0.525731) \* 0.200811, 0);
    } else {
      ctx.lineTo(r, 0);
    }
  }
  ctx.closePath();
  ctx.fill();
  ctx.restore();
}
```


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


```
draw();
```


首先，我画了一个与 canvas 一样大小的黑色方形作为背景，然后移动原点至中心点。然后用 `clip` 方法创建一个弧形的裁切路径。裁切路径也属于 canvas 状态的一部分，可以被保存起来。如果我们在创建新裁切路径时想保留原来的裁切路径，我们需要做的就是保存一下 canvas 的状态。

裁切路径创建之后所有出现在它里面的东西才会画出来。在画线性渐变时我们就会注意到这点。然后会绘制出 50 颗随机位置分布（经过缩放）的星星，当然也只有在裁切路径里面的星星才会绘制出来。

| Screenshot | Live sample |
| --- | --- |
|  |  |

* « 上一页
* 下一页 »
canvas 的优化
==========

* « 上一页
* 下一页 »

`<canvas>`元素是众多广泛使用的网络 2D 图像渲染标准之一。它被广泛用于游戏及复杂的图像可视化中。然而，随着网站和应用将 canvas 画布推至极限，性能开始成为问题。此文目标是给使用 canvas 画布元素的优化带来建议，去保证你的网站或者应用表现卓越。

性能贴士
----

下面是一些改善性能的建议

### 在离屏 canvas 上预渲染相似的图形或重复的对象

如果发现自己在每个动画帧上重复了一些相同的绘制操作，请考虑将其分流到屏幕外的画布上。然后，你可以根据需要频繁地将屏幕外图像渲染到主画布上，而不必首先重复生成该图像的步骤。


```js
myEntity.offscreenCanvas = document.createElement("canvas");
myEntity.offscreenCanvas.width = myEntity.width;
myEntity.offscreenCanvas.height = myEntity.height;
myEntity.offscreenContext = myEntity.offscreenCanvas.getContext("2d");

myEntity.render(myEntity.offscreenContext);
```

### 避免浮点数的坐标点，用整数取而代之

当你画一个没有整数坐标点的对象时会发生子像素渲染。


```js
ctx.drawImage(myImage, 0.3, 0.5);
```


浏览器为了达到抗锯齿的效果会做额外的运算。为了避免这种情况，请保证在你调用`drawImage()`函数时，用`Math.floor()`函数对所有的坐标点取整。

### 不要在用`drawImage`时缩放图像

在离屏 canvas 中缓存图片的不同尺寸，而不要用`drawImage()`去缩放它们。

### 使用多层画布去画一个复杂的场景

在你的应用程序中，你可能会发现某些对象需要经常移动或更改，而其他对象则保持相对静态。在这种情况下，可能的优化是使用多个`<canvas>`元素对你的项目进行分层。

例如，假设你有一个游戏，其 UI 位于顶部，中间是游戏性动作，底部是静态背景。在这种情况下，你可以将游戏分成三个`<canvas>`层。UI 将仅在用户输入时发生变化，游戏层随每个新框架发生变化，并且背景通常保持不变。


```html
<div id="stage">
  <canvas id="ui-layer" width="480" height="320"></canvas>
  <canvas id="game-layer" width="480" height="320"></canvas>
  <canvas id="background-layer" width="480" height="320"></canvas>
</div>

<style>
 #stage {
 width: 480px;
 height: 320px;
 position: relative;
 border: 2px solid black;
 }
 canvas {
 position: absolute;
 }
 #ui-layer {
 z-index: 3;
 }
 #game-layer {
 z-index: 2;
 }
 #background-layer {
 z-index: 1;
 }
</style>
```

### 用 CSS 设置大的背景图

如果像大多数游戏那样，你有一张静态的背景图，用一个静态的`<div>`元素，结合`background` 特性，以及将它置于画布元素之后。这么做可以避免在每一帧在画布上绘制大图。

### 用 CSS transforms 特性缩放画布

CSS transforms 使用 GPU，因此速度更快。最好的情况是不直接缩放画布，或者具有较小的画布并按比例放大，而不是较大的画布并按比例缩小。


```js
var scaleX = window.innerWidth / canvas.width;
var scaleY = window.innerHeight / canvas.height;

var scaleToFit = Math.min(scaleX, scaleY);
var scaleToCover = Math.max(scaleX, scaleY);

stage.style.transformOrigin = "0 0"; //scale from top left
stage.style.transform = "scale(" + scaleToFit + ")";
```

### 关闭透明度

如果你的游戏使用画布而且不需要透明，当使用 `HTMLCanvasElement.getContext()` 创建一个绘图上下文时把 `alpha` 选项设置为 `false` 。这个选项可以帮助浏览器进行内部优化。


```js
var ctx = canvas.getContext("2d", { alpha: false });
```

### 更多的贴士

* 将画布的函数调用集合到一起（例如，画一条折线，而不要画多条分开的直线）
* 避免不必要的画布状态改变
* 渲染画布中的不同点，而非整个新状态
* 尽可能避免 `shadowBlur`特性
* 尽可能避免text rendering
* 尝试不同的方法来清除画布 (`clearRect()` vs. `fillRect()` vs. 调整 canvas 大小)
* 有动画，请使用`window.requestAnimationFrame()` 而非`window.setInterval()`
* 请谨慎使用大型物理库
参见
--

* Improving HTML5 Canvas Performance – HTML5 Rocks
* Optimizing your JavaScript game for Firefox OS – Mozilla Hacks
* « 上一页
* 下一页 »
Coordinates.latitude
====================

**安全上下文:** 此项功能仅在一些支持的浏览器的安全上下文（HTTPS）中可用。

**`Coordinates.latitude`** 只读属性，十进制双精度浮点数来表示纬度坐标

语法
--
```

lat = coordinates.latitude
```

规范
--

| Specification |
| --- |
| Geolocation API # latitude-longitude-and-accuracy-attributes |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* Using geolocation
* The `Coordinates` interface it belongs to.
DocumentType：after() 方法
=======================

**`DocumentType.after()`** 方法在 `DocumentType` 的父级的子列表中插入一组 `Node` 对象或字符串，紧跟在 `DocumentType` 之后。字符串将作为等效的 `Text` (en-US) 节点插入。

语法
--


```js
after(param1)
after(param1, param2)
after(param1, param2, /\* … ,\*/ paramN)
```

### 参数

`param1`, …, `paramN`

要插入的一组 `Node` 对象或字符串。

### 返回值

无 (`undefined`)。

### 异常

`HierarchyRequestError` `DOMException`

当无法将节点插入到层次结构的指定点时抛出。

示例
--


```js
let docType = document.implementation.createDocumentType("html", "", "");
let myDoc = document.implementation.createDocument("", "", docType);

docType.after(document.createElement("html"));

myDoc.childNodes;
// 节点列表 [<!DOCTYPE html>, <html>]
```

规范
--

| Specification |
| --- |
| DOM Standard # ref-for-dom-childnode-after① |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `DocumentType.before()` (en-US)
Option()
========

用于创建`HTMLOptionElement`的构造函数。

句法
--
```

var optionElementReference = new Option(text, value, defaultSelected, selected);
```

### 参数

文字可选

表示元素内容的`DOMString`，即显示的文本。如果没有指定，则使用默认值""(空字符串)。

值可选

表示`HTMLOptionElement`的值的`DOMString`，即`value`等价的`<option>` 的属性。如果未指定，则将文本的值用作值，例如，将表单提交给服务器时，相关联的`<select>`元素的值。

defaultSelected 可选

设置`selected`属性值的`Boolean` (en-US)，也就是说这个`<option>`是默认值当第一次加载页面时，在`<select>`元素中选择。如果没有指定，`false`则使用默认值。请注意，`true` 如果选项尚未被选中，则该值不会将选项设置为选中状态。

选中可选

A `Boolean` (en-US)设置选项的选择状态; 默认是`false`(未选中)。如果省略，即使`defaultSelected`参数是`true`，该选项没有被选中。

规范
--

| Specification |
| --- |
| HTML Standard # dom-option-dev |
ContentVisibilityAutoStateChangeEvent：skipped 属性
================================================

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
若用户代理跳过元素内容，则 `ContentVisibilityAutoStateChangeEvent` 接口的只读属性 `skipped` 返回 `true`，否则返回 `false`。

值
-

布尔值。若用户代理跳过元素内容则返回 `true`，否则返回 `false`。

示例
--


```js
const canvasElem = document.querySelector("canvas");

canvasElem.addEventListener("contentvisibilityautostatechange", stateChanged);
canvasElem.style.contentVisibility = "auto";

function stateChanged(event) {
  if (event.skipped) {
    stopCanvasUpdates(canvasElem);
  } else {
    startCanvasUpdates(canvasElem);
  }
}

// 在画布需要开始更新时调用此方法。
function startCanvasUpdates(canvas) {
  // …
}

// 在画布需要停止更新时调用此方法。
function stopCanvasUpdates(canvas) {
  // …
}
```

规范
--

| Specification |
| --- |
| CSS Containment Module Level 2 # dom-contentvisibilityautostatechangeevent-skipped |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `contentvisibilityautostatechange` 事件
* CSS 局限
* `content-visibility` 属性
* `contain` 属性
ContentVisibilityAutoStateChangeEvent：ContentVisibilityAutoStateChangeEvent() 构造函数
==================================================================================

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
构造函数 **`ContentVisibilityAutoStateChangeEvent()`** 创建新的 `ContentVisibilityAutoStateChangeEvent` 对象实例。

语法
--


```js
new ContentVisibilityAutoStateChangeEvent(type, options)
```

### 参数

`type`

表示事件类型的字符串。对于 `ContentVisibilityAutoStateChangeEvent`，此参数恒为 `event`。

`options` 可选

包含下列属性的对象：

`skipped`

布尔值，若用户代理跳过元素内容则设置为 `true`，否则为 `false`。


示例
--

开发者不会手动使用此构造函数。当触发 `contentvisibilityautostatechange` 事件导致调用事件处理器时将构造新的 `ContentVisibilityAutoStateChangeEvent` 对象。


```js
canvasElem.addEventListener("contentvisibilityautostatechange", (event) => {
  // …
});
```

规范
--

| Specification |
| --- |
| CSS Containment Module Level 2 # dom-contentvisibilityautostatechangeevent-contentvisibilityautostatechangeevent |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `contentvisibilityautostatechange` 事件
* CSS 局限
* `content-visibility` 属性
* `contain` 属性
InputEvent.inputType
====================

Baseline 2023
-------------

Newly availableSince March 2023, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
`InputEvent` 接口中的只读属性 **`inputType`** 返回对可编辑内容所做更改的类型。可能的更改包括插入、删除和格式化文本。

语法
--


```js
var aString = inputEvent.inputType;
```

### 返回值

一个包含所做输入的类型的字符串。有许多可能的值，例如 `insertText`、`deleteContentBackward`、`insertFromPaste` 和 `formatBold`。有关可用输入类型的完整列表，请参阅 Input Events Level 1 规范的属性部分。

示例
--

此示例记录一个可编辑的 `<div>` 所触发的 input 事件的 `inputType`。

### HTML


```html
<p id="log">Input type:</p>
<div
 contenteditable="true"
 style="margin: 20px;padding: 20px;border:2px dashed red;">
  <p>
    Some sample text. Try inserting line breaks, or deleting text in different
    ways, or pasting different content in.
  </p>
  <hr />
  <ul>
    <li>A sample</li>
    <li>bulleted</li>
    <li>list.</li>
  </ul>
  <p>Another paragraph.</p>
</div>
```

### JavaScript


```js
const log = document.getElementById("log");
const editable = document.querySelector("div[contenteditable]");
editable.addEventListener("input", logInputType);

function logInputType(event) {
  log.textContent = `Input type: ${event.inputType}`;
}
```

### 结果

尝试编辑 `<div>` 中的文本，并看看发生了什么事。

**备注：** 有关更详细的示例，请参见 Masayuki Nakano 的 InputEvent 测试套件。

规范
--

| Specification |
| --- |
| UI Events # dom-inputevent-inputtype |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.