HTMLMediaElement: timeupdate - Web API 接口参考

HTMLMediaElement: timeupdate
============================

当`currentTime`更新时会触发`timeupdate`事件。

这个事件的触发频率由系统决定，但是会保证每秒触发 4-66 次（前提是每次事件处理不会超过 250ms）。鼓励用户代理根据系统的负载和处理事件的平均成本来改变事件的频率，保证 UI 更新不会影响视频的解码。

|  |  |
| --- | --- |
| Bubbles | No |
| Cancelable | No |
| Interface | `Event` |
| Target | Element |
| Default Action | None |
| Event handler property | `GlobalEventHandlers.ontimeupdate` |
| Specification | HTML5 media |

示例
--

These examples add an event listener for the HTMLMediaElement's `timeupdate` event, then post a message when that event handler has reacted to the event firing. Remember, the event frequency is dependant on the system load.

Using `addEventListener()`:

```js
const video = document.querySelector("video");

video.addEventListener("timeupdate", (event) => {
  console.log("The currentTime attribute has been updated. Again.");
});
```

Using the `ontimeupdate` event handler property:

```js
const video = document.querySelector("video");

video.ontimeupdate = (event) => {
  console.log("The currentTime attribute has been updated. Again.");
};
```

规范
--

| Specification |
| --- |
| HTML Standard # event-media-timeupdate |
| HTML Standard # handler-ontimeupdate |

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

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

相关事件
----

* `HTMLMediaElement: playing event`
* `HTMLMediaElement: waiting event` (en-US)
* `HTMLMediaElement: seeking event` (en-US)
* `HTMLMediaElement: seeked event` (en-US)
* `HTMLMediaElement: ended event`
* `HTMLMediaElement: loadedmetadata event`
* `HTMLMediaElement: loadeddata event`
* `HTMLMediaElement: canplay event`
* `HTMLMediaElement: canplaythrough event`
* `HTMLMediaElement: durationchange event`
* `HTMLMediaElement: timeupdate event`
* `HTMLMediaElement: play event`
* `HTMLMediaElement: pause event`
* `HTMLMediaElement: ratechange event` (en-US)
* `HTMLMediaElement: volumechange event` (en-US)
* `HTMLMediaElement: suspend event` (en-US)
* `HTMLMediaElement: emptied event` (en-US)
* `HTMLMediaElement: stalled event` (en-US)
更多
--

* `HTMLAudioElement`
* `HTMLVideoElement`
* `<audio>`
* `<video>`


HTMLMediaElement: ended 事件 - Web API 接口参考

HTMLMediaElement: ended 事件
==========================

`ended` 事件会在媒体回放或者媒体流因达到了媒体的未尾或者没有更多可用的数据而停止时被触发。

该事件会在回放或媒体文件播放结束时，在`媒体元素`（`<audio>` 和 `<video>`）上触发。

|  |  |
| --- | --- |
| 是否冒泡 | 否 |
| 是否可取消 | 否 |
| 接口 | `Event` |
| 目标 | 元素 |
| 默认行为 | 无 |
| 事件处理器属性 | `GlobalEventHandlers.onended` |

**备注：** 该事件也在媒体捕捉与媒体流和 Web Audio 这两个 API 中定义。

示例
--

以下示例展示了如何为媒体元素的 `ended` 事件添加一个事件监听器，以在该事件触发时发送一条消息。

使用 `addEventListener()`：

```js
const video = document.querySelector("video");

video.addEventListener("ended", (event) => {
  console.log(
    "Video stopped either because 1) it was over, " +
      "or 2) no further data is available.",
  );
});
```

使用 `onended` 事件处理器属性：

```js
const video = document.querySelector("video");

video.onended = (event) => {
  console.log(
    "Video stopped either because 1) it was over, " +
      "or 2) no further data is available.",
  );
};
```

规范
--

| Specification |
| --- |
| HTML Standard # event-media-ended |
| HTML Standard # handler-onended |

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

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

相关事件
----

* 媒体元素 `playing` 事件
* 媒体元素 `waiting` (en-US) 事件
* 媒体元素 `seeking` (en-US) 事件
* 媒体元素 `seeked` (en-US) 事件
* 媒体元素 `ended` 事件
* 媒体元素 `loadedmetadata` 事件
* 媒体元素 `loadeddata` 事件
* 媒体元素 `canplay` 事件
* 媒体元素 `canplaythrough` 事件
* 媒体元素 `durationchange` 事件
* 媒体元素 `timeupdate` 事件
* 媒体元素 `play` 事件
* 媒体元素 `pause` 事件
* 媒体元素 `ratechange` (en-US) 事件
* 媒体元素 `volumechange` (en-US) 事件
* 媒体元素 `suspend` (en-US) 事件
* 媒体元素 `emptied` (en-US) 事件
* 媒体元素 `stalled` (en-US) 事件
参见
--

* `HTMLAudioElement`
* `HTMLVideoElement`
* `<audio>`
* `<video>`
* 媒体捕捉与媒体流
    + 媒体捕捉与媒体流：ended 事件 (en-US)
* Web Audio API
    + Web audio API: ended 事件 (en-US)


HTMLMediaElement.currentSrc - Web API 接口参考

HTMLMediaElement.currentSrc
===========================

**`HTMLMediaElement.currentSrc`** 属性包含所选媒体源的绝对 URL 路径。例如当程序会根据用户显示器分辨率选择不同媒体文件时会用到这个属性，显然它是只读的。当 **`networkState`** 值为 **`EMPTY`** 时，本属性值为空字符串（empty string）.

语法
--
```

var mediaUrl = audioObject.currentSrc;
```

### 值

一个 `DOMString` 对象包含所选媒体源的绝对 URL 路径。当 `networkState` ＝＝ `EMPTY 时，其值为空字符串（empty string）`; 否则，它会是 `HTMLSourceElement` (en-US) 所包含媒体列表中的一个，或者是 `<source>` 标签的 src 值。

示例
--

```js
var obj = document.createElement("video");
console.log(obj.currentSrc); // ""
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-media-currentsrc-dev |

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

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

参考
--

* The interface defining it, `HTMLMediaElement`.


HTMLMediaElement.videoTracks - Web API 接口参考

HTMLMediaElement.videoTracks
============================

**`videoTracks`** 为 `HTMLMediaElement` 的只读属性，它是一个 `VideoTrackList` (en-US) 列表，列表中包含相应媒体元素的视频轨，视频轨为`VideoTrack` (en-US) 类型对象。

它是一个实时列表; 当相应的媒体元素增加或删除视频轨时，返回列表会发生动态的改变。由此你可以监控和检测视频轨发生的变化。学习 VideoTrackList 事件 (en-US)可以获得更多关于 media element 视频轨的知识。

Syntax
------
```

var videoTracks = mediaElement.videoTracks;
```

### 返回值

返回的是一个`VideoTrackList` (en-US) 类型值，为相应媒体元素的视频轨列表。可以用访问数组的方法访问这个值，或 `getTrackById()` (en-US) 方法访问它。

列表中包含的每一个 `VideoTrack` (en-US) 代表其中的一个视频轨。

Specifications
--------------

| Specification |
| --- |
| HTML Standard # dom-media-videotracks-dev |

Browser compatibility
---------------------

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

See also
--------

* The interface defining it, `HTMLMediaElement`.
* `<video>`
* `VideoTrack` (en-US) and `VideoTrackList` (en-US)


srcObject - Web API 接口参考

srcObject
=========

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

`HTMLMediaElement` 接口的 **`srcObject`** 属性设定或返回一个对象，这个对象提供了一个与`HTMLMediaElement`关联的媒体源，这个对象通常是 `MediaStream` ，但根据规范可以是 `MediaSource`， `Blob` 或者 `File`。

**备注：** 截至 2020 年 3 月，只有 Safari 支持设置 `MediaStream` 之外的对象。在其他浏览器跟上之前，对`MediaSource`, `Blob` 和 `File`, 请考虑返回创建具有{domxref("URL.createObjectURL()")}} 的 URL，并将其赋值给`HTMLMediaElement.src` 有关示例，请参阅下文。

语法
--
```

var mediaStream = HTMLMediaElement.srcObject
HTMLMediaElement.srcObject = mediaStream
```

### 值

一个 `MediaStream`，`MediaSource`，`Blob` 或者 `File` 对象（具体支持请参见兼容表）。

规范
--

| Specification |
| --- |
| HTML Standard # dom-media-srcobject-dev |

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

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


HTMLMediaElement.readyState - Web API 接口参考

HTMLMediaElement.readyState
===========================

**`HTMLMediaElement.readyState`** 属性返回音频/视频的当前就绪状态。

语法
--
```

var readyState = audioOrVideo.readyState;
```

### 返回值

无符号整型 An `unsigned short`.

| Constant | Value | Description |
| --- | --- | --- |
| HAVE\_NOTHING | 0 | 没有关于音频/视频是否就绪的信息 |
| HAVE\_METADATA | 1 | 音频/视频已初始化 |
| HAVE\_CURRENT\_DATA | 2 | 数据已经可以播放 (当前位置已经加载) 但没有数据能播放下一帧的内容 |
| HAVE\_FUTURE\_DATA | 3 | 当前及至少下一帧的数据是可用的 (换句话来说至少有两帧的数据) |
| HAVE\_ENOUGH\_DATA | 4 | 可用数据足以开始播放 - 如果网速得到保障 那么视频可以一直播放到底 |

实例
--

这个例子会监听 id 为 example 的 audio 的数据。他会检查当前位置是否可以播放，会的话执行播放。

```html
<audio id="example" preload="auto">
  <source src="sound.ogg" type="audio/ogg" />
</audio>
```

```js
var obj = document.getElementById("example");

obj.addEventListener("loadeddata", function () {
  if (obj.readyState >= 2) {
    obj.play();
  }
});
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-media-readystate-dev |

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

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

你或许还可以看看
--------

* The interface defining it, `HTMLMediaElement`.


HTMLMediaElement: progress event - Web API 接口参考

HTMLMediaElement: progress event
================================

**`progress`** 事件在浏览器加载一个资源的时候周期性触发。

|  |  |
| --- | --- |
| Bubbles | No |
| Cancelable | No |
| Interface | `Event` |
| Event handler property | `onprogress` |

示例
--

### HTML

```html
<div class="example">
  <button type="button">Load video</button>
  <video controls width="250"></video>

  <div class="event-log">
    <label>Event log:</label>
    <textarea readonly class="event-log-contents"></textarea>
  </div>
</div>
```

```
.event-log-contents {
  width: 18rem;
  height: 5rem;
  border: 1px solid black;
  margin: 0.2rem;
  padding: 0.2rem;
}

.example {
  display: grid;
  grid-template-areas:
    "button log"
    "video log";
}

button {
  grid-area: button;
  width: 10rem;
  margin: 0.5rem 0;
}

video {
  grid-area: video;
}

.event-log {
  grid-area: log;
}

.event-log > label {
  display: block;
}
```

### JavaScript

```js
const loadVideo = document.querySelector("button");
const video = document.querySelector("video");
const eventLog = document.querySelector(".event-log-contents");
let source = null;

function handleEvent(event) {
  eventLog.textContent = eventLog.textContent + `${event.type}\n`;
}

video.addEventListener("loadstart", handleEvent);
video.addEventListener("progress", handleEvent);
video.addEventListener("canplay", handleEvent);
video.addEventListener("canplaythrough", handleEvent);

loadVideo.addEventListener("click", () => {
  if (source) {
    document.location.reload();
  } else {
    loadVideo.textContent = "Reset example";
    source = document.createElement("source");
    source.setAttribute(
      "src",
      "https://mdn.github.io/learning-area/html/multimedia-and-embedding/video-and-audio-content/rabbit320.mp4",
    );
    source.setAttribute("type", "video/mp4");

    video.appendChild(source);
  }
});
```

### 结果

规范
--

| Specification |
| --- |
| HTML Standard # event-media-progress |
| HTML Standard # handler-onprogress |

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

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

参见
--

* `HTMLAudioElement`
* `HTMLVideoElement`
* `<audio>`
* `<video>`


HTMLMediaElement：error 事件 - Web API 接口参考

HTMLMediaElement：error 事件
=========================

**`error`** 事件会在因为一些错误（如网络连接错误）导致无法加载资源的时候触发。

事件不可取消也不会冒泡。

语法
--

在类似 `addEventListener()` 这样的方法中使用事件名称，或设置事件处理器属性。

```js
addEventListener("error", (event) => {});

onerror = (event) => {};
```

事件类型
----

一个通用的 `Event`。

示例
--

```js
const video = document.querySelector("video");
const videoSrc = "https://path/to/video.webm";

video.addEventListener("error", () => {
  console.error(`Error loading: ${videoSrc}`);
});

video.setAttribute("src", videoSrc);
```

规范
--

| Specification |
| --- |
| HTML Standard # event-media-error |
| HTML Standard # handler-window-onmessageerror |

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

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

参见
--

* `HTMLAudioElement`
* `HTMLVideoElement`
* `<audio>`
* `<video>`


HTMLMediaElement: durationchange 事件 - Web API 接口参考

HTMLMediaElement: durationchange 事件
===================================

`durationchange` 事件会在 `duration` 属性更新时被触发。

|  |  |
| --- | --- |
| Bubbles | No |
| Cancelable | No |
| Interface | `Event` |
| Target | Element |
| Default Action | None |
| Event handler property | `GlobalEventHandlers.ondurationchange` (en-US) |
| Specification | HTML5 media |

例子
--

下面的例子为 HTMLMediaElement 的 `durationchange` 事件添加事件监听器，然后在事件触发时发送一个消息。

使用 `addEventListener()`:

```js
const video = document.querySelector("video");

video.addEventListener("durationchange", (event) => {
  console.log("Not sure why, but the duration of the video has changed.");
});
```

使用 `ondurationchange` 事件处理器属性：

```js
const video = document.querySelector("video");

video.ondurationchange = (event) => {
  console.log("Not sure why, but the duration of the video has changed.");
};
```

Specifications
--------------

| Specification |
| --- |
| HTML Standard # event-media-durationchange |
| HTML Standard # handler-ondurationchange |

Browser compatibility
---------------------

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

Related Events
--------------

* `HTMLMediaElement: playing event`
* `HTMLMediaElement: waiting event` (en-US)
* `HTMLMediaElement: seeking event` (en-US)
* `HTMLMediaElement: seeked event` (en-US)
* `HTMLMediaElement: ended event`
* `HTMLMediaElement: loadedmetadata event`
* `HTMLMediaElement: loadeddata event`
* `HTMLMediaElement: canplay event`
* `HTMLMediaElement: canplaythrough event`
* `HTMLMediaElement: durationchange event`
* `HTMLMediaElement: timeupdate event`
* `HTMLMediaElement: play event`
* `HTMLMediaElement: pause event`
* `HTMLMediaElement: ratechange event` (en-US)
* `HTMLMediaElement: volumechange event` (en-US)
* `HTMLMediaElement: suspend event` (en-US)
* `HTMLMediaElement: emptied event` (en-US)
* `HTMLMediaElement: stalled event` (en-US)
See Also
--------

* `HTMLAudioElement`
* `HTMLVideoElement`
* `<audio>`
* `<video>`


HTMLMediaElement: canplay - Web API 接口参考

HTMLMediaElement: canplay
=========================

`canplay` 事件在终端可以播放媒体文件时（但估计还没有加载足够的数据来播放媒体直到其结束，即后续可能需要停止以进一步缓冲内容）被触发。

|  |  |
| --- | --- |
| 是否冒泡 | 否 |
| 是否可取消 | 否 |
| 接口 | `Event` |
| 目标 | 元素 |
| 默认行为 | 无 |
| 事件处理器属性 | `GlobalEventHandlers.oncanplay` |

示例
--

以下示例展示了如何为媒体元素的 `canplay` 事件添加一个事件监听器，以在该事件触发时发送一条消息。

使用 `addEventListener()`：

```js
const video = document.querySelector("video");

video.addEventListener("canplay", (event) => {
  console.log("Video can start, but not sure it will play through.");
});
```

使用 `oncanplay` 事件处理器属性：

```js
const video = document.querySelector("video");

video.oncanplay = (event) => {
  console.log("Video can start, but not sure it will play through.");
};
```

规范
--

| Specification |
| --- |
| HTML Standard # event-media-canplay |
| HTML Standard # handler-oncanplay |

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

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

相关事件
----

* 媒体元素 `playing` 事件
* 媒体元素 `waiting` (en-US) 事件
* 媒体元素 `seeking` (en-US) 事件
* 媒体元素 `seeked` (en-US) 事件
* 媒体元素 `ended` 事件
* 媒体元素 `loadedmetadata` 事件
* 媒体元素 `loadeddata` 事件
* 媒体元素 `canplay` 事件
* 媒体元素 `canplaythrough` 事件
* 媒体元素 `durationchange` 事件
* 媒体元素 `timeupdate` 事件
* 媒体元素 `play` 事件
* 媒体元素 `pause` 事件
* 媒体元素 `ratechange` (en-US) 事件
* 媒体元素 `volumechange` (en-US) 事件
* 媒体元素 `suspend` (en-US) 事件
* 媒体元素 `emptied` (en-US) 事件
* 媒体元素 `stalled` (en-US) 事件
参见
--

* `HTMLAudioElement`
* `HTMLVideoElement`
* `<audio>`
* `<video>`


HTMLMediaElement: loadstart event - Web API 接口参考

HTMLMediaElement: loadstart event
=================================

**`loadstart`** 事件当浏览器开始载入一个资源文件时 fired.

|  |  |
| --- | --- |
| Bubbles | No |
| 可撤销 | No |
| Interface | `Event` |
| Event handler property | `onloadstart` |

Examples
--------

### Live example

#### HTML

```html
<div class="example">
  <button type="button">Load video</button>
  <video controls width="250"></video>

  <div class="event-log">
    <label>Event log:</label>
    <textarea readonly class="event-log-contents"></textarea>
  </div>
</div>
```

```
.event-log-contents {
  width: 18rem;
  height: 5rem;
  border: 1px solid black;
  margin: 0.2rem;
  padding: 0.2rem;
}

.example {
  display: grid;
  grid-template-areas:
    "button log"
    "video log";
}

button {
  grid-area: button;
  width: 10rem;
  margin: 0.5rem 0;
}

video {
  grid-area: video;
}

.event-log {
  grid-area: log;
}

.event-log > label {
  display: block;
}
```

#### JS

```js
const loadVideo = document.querySelector("button");
const video = document.querySelector("video");
const eventLog = document.querySelector(".event-log-contents");
let source = null;

function handleEvent(event) {
  eventLog.textContent = eventLog.textContent + `${event.type}\n`;
}

video.addEventListener("loadstart", handleEvent);
video.addEventListener("progress", handleEvent);
video.addEventListener("canplay", handleEvent);
video.addEventListener("canplaythrough", handleEvent);

loadVideo.addEventListener("click", () => {
  if (source) {
    document.location.reload();
  } else {
    loadVideo.textContent = "Reset example";
    source = document.createElement("source");
    source.setAttribute(
      "src",
      "https://interactive-examples.mdn.mozilla.net/media/examples/flower.webm",
    );
    source.setAttribute("type", "video/webm");

    video.appendChild(source);
  }
});
```

#### Result

Specifications
--------------

| Specification |
| --- |
| HTML Standard # event-media-loadstart |
| HTML Standard # handler-onloadstart |

Browser compatibility
---------------------

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

See also
--------

* `HTMLAudioElement`
* `HTMLVideoElement`
* `<audio>`
* `<video>`


forward() - Web API 接口参考

forward()
=========

在会话历史中向前移动一页。它与使用`delta`参数为 1 时调用 `history.go(delta)`的效果相同。

语法
--

```js
window.history.forward();
```

示例
--

下述例子创建了一个按钮，该按钮会在会话历史中向前移动一步。

### HTML

```html
<button id="go-forward">Go Forward!</button>
```

### JavaScript

```js
window.onload = function (e) {
  document.getElementById("go-forward").addEventListener("click", (e) => {
    window.history.forward();
  });
};
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-history-forward-dev |

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

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


back() - Web API 接口参考

back()
======

`back()`方法会在会话历史记录中向后移动一页。如果没有上一页，则此方法调用不执行任何操作。

语法
--

```js
back()
```

示例
--

下述简短示例使页面上的按钮导航页面至会话历史的后一项。

### HTML

```html
<button id="go-back">Go back!</button>
```

### JavaScript

```js
window.onload = function (e) {
  document.getElementById("go-back").addEventListener("click", (e) => {
    window.history.back();
  });
};
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-history-back-dev |

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

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


History.length - Web API 接口参考

History.length
==============

History.length 是一个只读属性，返回当前 session 中的 history 个数，包含当前页面在内。举个例子，对于新开一个 tab 加载的页面当前属性返回值 1。

语法
--
```

length = history.length;
```

例子
--

```js
var result = window.history.length; // 返回当前 session 中的 history 个数
```

规范
--

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

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

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

参考
--

* The `History` interface it belongs to.


History.scrollRestoration - Web API 接口参考

History.scrollRestoration
=========================

`History` 的接口——\*\*`滚动恢复属性`\*\*允许 web 应用程序在历史导航上显式地设置默认滚动恢复行为

语法
--
```

const scrollRestore = history.scrollRestoration
```

### 值

`auto`

将恢复用户已滚动到的页面上的位置。

`manual`

未还原页上的位置。用户必须手动滚动到该位置。

案例
--

### 查看当前页面滚动恢复行为

```js
const scrollRestoration = history.scrollRestoration;
if (scrollRestoration === "manual") {
  console.log(
    "The location on the page is not restored, user will need to scroll manually.",
  );
}
```

### 防止自动恢复页面位置

```js
if (history.scrollRestoration) {
  history.scrollRestoration = "manual";
}
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-history-scroll-restoration-dev |

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

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


go() - Web API 接口参考

go()
====

`go()`方法从会话历史记录中加载特定页面。你可以使用它在历史记录中前后移动，具体取决于`delta`参数的值。

语法
--

```js
window.history.go(delta);
```

### 参数

`delta` 可选

相对于当前页面你要去往历史页面的位置。负值表示向后移动，正值表示向前移动。因此，例如：`history.go(2)`向前移动两页，`history.go(-2)`则向后移动两页。如果未向该函数传参或`delta`相等于 0，则该函数与调用`location.reload()`具有相同的效果。

**备注：** 相等于 0 是采用宽松相等进行比较的。另外，JavaScript 值古怪的隐式转换在这里也是可用的。

示例
--

向后移动一页（等价于调用`back()`）：

```js
window.history.go(-1);
```

向前移动一页，就像调用了`forward()`：

```js
window.history.go(1);
```

向前移动两页：

```js
window.history.go(2);
```

向后移动两页：

```js
window.history.go(-2);
```

最后，以下任意一条语句都会重新加载当前页面：

```js
window.history.go();
window.history.go(0);
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-history-go-dev |

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

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


History：replaceState() 方法 - Web API 接口参考

History：replaceState() 方法
=========================

`History` 接口的 **`replaceState()`** 方法使用状态对象和 URL 作为参数来修改当前的历史记录条目。当你想要更新当前历史记录条目的状态对象或者 URL 来响应用户的动作时，这个方法非常有用。

语法
--

```js
replaceState(state, unused)
replaceState(state, unused, url)
```

### 参数

`state`

一个与传递给 `replaceState()` 方法的历史记录条目相关联的对象。状态对象可以是 `null`。

`unused`

该参数由于历史原因而存在，不能省略；传递空字符串是传统的做法，也可以安全地应对未来对该方法的变更。

`url` 可选

历史记录条目的 URL。新的 URL 跟当前的 URL 必须同源；否则 `replaceState()` 方法将抛出异常。

### 返回值

无（`undefined`）。

### 异常

`SecurityError` `DOMException`

如果关联的文档没有完全激活，或者提供的 `url` 参数不是有效的 URL，则抛出该异常。

`DataCloneError` `DOMException`

如果提供的 `state` 参数不可序列化，则抛出该异常。

示例
--

假设 `https://www.mozilla.org/foo.html` 执行了以下 JavaScript 代码：

```js
const stateObj = { foo: "bar" };
history.pushState(stateObj, "", "bar.html");
```

在下一个页面，你可以使用 `history.state` 来访问刚刚添加的 `stateObj`。

上面这两行的解释可以在使用历史记录 API 一文中找到。然后假设 `https://www.mozilla.org/bar.html` 执行了下面的 JavaScript 代码：

```js
history.replaceState(stateObj, "", "bar2.html");
```

这会让 URL 栏显示 `https://www.mozilla.org/bar2.html`，但是不会加载 `bar2.html` 页面，甚至不会检查 `bar2.html` 是否存在。

假设用户跳转到 `https://www.microsoft.com`，然后点击返回按钮。这时，URL 栏将会显示 `https://www.mozilla.org/bar2.html`。如果用户此时再次点击返回按钮，URL 栏将会显示 `https://www.mozilla.org/foo.html` 页面，而完全绕过了 bar.html 页面。

规范
--

| Specification |
| --- |
| HTML Standard # dom-history-replacestate-dev |

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

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


History：pushState() 方法 - Web API 接口参考

History：pushState() 方法
======================

在 HTML 文档中，**`history.pushState()`** 方法向浏览器的会话历史栈增加了一个条目。

该方法是异步的。为 `popstate` 事件增加监听器，以确定导航何时完成。`state` 参数将在其中可用。

语法
--

```js
pushState(state, unused)
pushState(state, unused, url)
```

### 参数

`state`

`state` 对象是一个 JavaScript 对象，其与通过 `pushState()` 创建的新历史条目相关联。每当用户导航到新的 `state`，都会触发 `popstate` 事件，并且该事件的 `state` 属性包含历史条目 `state` 对象的副本。

`state` 对象可以是任何可以序列化的对象。因为 Firefox 将 `state` 对象保存到用户的磁盘上，以便用户重启浏览器可以恢复，我们对 `state` 对象序列化的表示施加了 16 MiB 的限制。如果你传递的 `state` 对象的序列化表示超出了 `pushState()` 可接受的大小，该方法将抛出异常。如果你需要更多的空间，建议使用 `sessionStorage` 和/或 `localStorage`。

`unused`

由于历史原因，该参数存在且不能忽略；传递一个空字符串是安全的，以防将来对该方法进行更改。

`url` 可选

新历史条目的 URL。请注意，浏览器不会在调用 `pushState()` 之后尝试加载该 URL，但是它可能会在以后尝试加载该 URL，例如，在用户重启浏览器之后。新 URL 可以不是绝对路径；如果它是相对的，它将相对于当前的 URL 进行解析。新的 URL 必须与当前 URL 同源；否则，`pushState()` 将抛出异常。如果该参数没有指定，则将其设置为当前文档的 URL。

### 返回值

无（`undefined`）。

描述
--

从某种程度来说，调用 `pushState()` 类似于 `window.location = "#foo"`，它们都会在当前的文档中创建和激活一个新的历史条目。但是 `pushState()` 有以下优势：

* 新的 URL 可以是任何和当前 URL 同源的 URL。然而，如果你仅修改 hash，将其设置到 `window.location`，将使你留在同一文档中。
* 改变页面的 URL 是可选的。相反，设置 `window.location = "#foo";` 仅仅会在当前 hash 不是 `#foo` 情况下，创建一条新的历史条目。
* 你可以使用你的新历史条目关联任意数据。使用基于 hash 的方式，你需要将所有相关的数据编码为一个短字符串。

注意，`pushState()` 从未引起 `hashchange` 事件的触发，即使新 URL 与旧 URL 仅在 hash 上不同。

示例
--

该示例通过设置 *state* 和 *url* 创建一条新的历史条目。

### JavaScript

```js
const state = { page\_id: 1, user\_id: 5 };
const url = "hello-world.html";

history.pushState(state, "", url);
```

### 改变查询参数

```js
const url = new URL(location);
url.searchParams.set("foo", "bar");
history.pushState({}, "", url);
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-history-pushstate-dev |

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

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

参见
--

* 使用 History API
* Window：popstate 事件


state - Web API 接口参考

state
=====

返回在 history 栈顶的 `任意` 值的拷贝。通过这种方式可以查看 state 值，不必等待 `popstate`事件发生后再查看。

语法
--

```js
let currentState = history.state;
```

如果不进行下面两种类型的调用，state 的值将会是 null

`pushState()` or `replaceState()`.

例子
--

下面 log 例句输出 history.state 的值，首先是在没有执行 `pushState()` 语句进而将值 push 到 history 之前的 log。下面一行 log 语句再次输出 state 值，此时 history.state 已经有值。可以在脚本文件中执行下面语句，或者在控制台直接执行。

```js
// 值为 null 因为我们还没有修改 history 栈
console.log(`History.state before pushState: ${history.state}`);

// 现在 push 一些数据到栈里
history.replaceState({ name: "Example" }, "pushState example", "page3.html");

// 现在 state 已经有值了
console.log(`History.state after pushState: ${history.state}`);
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-history-state-dev |

Browser compatibility
---------------------

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

See also
--------

* Working with the History API


TextDecoder.encoding - Web API 接口参考

TextDecoder.encoding
====================

只读属性 **`TextDecoder.encoding`** 返回一个字符串，其中包含了指定的解码器的解码算法的名称。

编码由构造函数的 `label` 参数设置，并且默认是 `utf-8`。

值
-

小写的 ASCII 字符，可以是以下值之一：

* Web 推荐的编码：`'utf-8'`。
* 传统的单字节编码：
 `'ibm866'`、
 `'iso-8859-2'`、
 `'iso-8859-3'`、
 `'iso-8859-4'`、
 `'iso-8859-5'`、
 `'iso-8859-6'`、
 `'iso-8859-7'`、
 `'iso-8859-8'`、
 `'iso-8859-8i'`、
 `'iso-8859-10'`、
 `'iso-8859-13'`、
 `'iso-8859-14'`、
 `'iso-8859-15'`、
 `'iso-8859-16'`、
 `'koi8-r'`、
 `'koi8-u'`、
 `'macintosh'`、
 `'windows-874'`、
 `'windows-1250'`、
 `'windows-1251'`、
 `'windows-1252'`、
 `'windows-1253'`、
 `'windows-1254'`、
 `'windows-1255'`、
 `'windows-1256'`、
 `'windows-1257'`、
 `'windows-1258'` 或
 `'x-mac-cyrillic'`。
* 传统的多字节中文（简体）编码：
 `'gbk'`、
 `'gb18030'` 和
 `'hz-gb-2312'`。
* 传统的多字节中文（繁体）编码：
 `'big5'`。
* 传统的多字节日语编码：
 `'euc-jp'`、
 `'iso-2022-jp'`
 和 `'shift-jis'`。
* 传统的多字节韩语编码：
 `'euc-kr'` 和
 `'iso-2022-kr'`。
* 传统的其他编码：
 `'utf-16be'`、
 `'utf-16le'`
 和 `'x-user-defined'`。
* 一种特殊的编码，`'replacement'`，它只会发出一个错误和一个 `EOF` 代码点。它用于阻止客户端和服务端之间编码不匹配的攻击。`ISO-2022-CN` 和 `ISO-2022-CN-ext` 可能发生这种情况。
规范
--

| Specification |
| --- |
| Encoding Standard # ref-for-dom-textdecoder-encoding① |

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

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

参见
--

* 属于 `TextDecoder` 接口。


TextDecoder.ignoreBOM - Web API 接口参考

TextDecoder.ignoreBOM
=====================

`TextDecoder` 接口的只读属性 **`ignoreBOM`** 是一个布尔值，表示是否忽略字节顺序标记。

值
-

如果字节顺序标记被忽略，则是 `true`；否则是 `false`。

规范
--

| Specification |
| --- |
| Encoding Standard # ref-for-dom-textdecoder-ignorebom① |

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

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


TextDecoder.decode() - Web API 接口参考

TextDecoder.decode()
====================

**`TextDecoder.decode()`** 方法返回一个字符串，其包含作为参数传递的缓冲区解码后的文本。

解码方法在当前的 `TextDecoder` 对象中定义。这包含了数据的预期编码，以及如何处理解码时发生的错误。

语法
--

```js
decode()
decode(buffer)
decode(buffer, options)
```

### 参数

`buffer` 可选

一个 `ArrayBuffer`、`TypedArray` 或包含要解码的编码文本的 `DataView` 对象。

`options` 可选

具有以下属性的对象：

`stream`

一个布尔标志，表示在后续调用 `decode()` 将跟随附加数据。如果以分块的形式处理数据，则设置为 `true`；如果是最终的分块或者数据没有分块，则设置为 `false`。默认是 `false`。

### 异常

`TypeError`

当 `TextDecoder.fatal` 属性为 `true` 时，若出现解码错误，则抛出该异常。

### 返回值

一个字符串。

示例
--

这个示例编码和解码欧元符号，€。

### HTML

```html
<p>Encoded value: <span id="encoded-value"></span></p>
<p>Decoded value: <span id="decoded-value"></span></p>
```

### JavaScript

```js
const encoder = new TextEncoder();
const array = encoder.encode("€"); // Uint8Array(3) [226, 130, 172]
document.getElementById("encoded-value").textContent = array;

const decoder = new TextDecoder();
const str = decoder.decode(array); // String "€"
document.getElementById("decoded-value").textContent = str;
```

### 结果

规范
--

| Specification |
| --- |
| Encoding Standard # ref-for-dom-textdecoder-decode① |

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

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

参见
--

* 属于 `TextDecoder` 接口。


TextDecoder.fatal - Web API 接口参考

TextDecoder.fatal
=================

`TextDecoder` 接口的只读属性 **`fatal`** 是一个布尔值，表示错误模式是否是致命的。

如果这个值是 `true`，那么当解码器在解码时遇到格式错误的数据时，将抛出 `TypeError` 错误。如果值是 `false`，则解码器将使用替换字符 `U+FFFD`（�）替换无效的数据。属性值在 `TextDecoder()` 构造函数中设置。

值
-

一个布尔值，如果错误模式设置为 `fatal`，它将返回 `true`。否则返回 `false`，表示错误模式是“replacement”。

规范
--

| Specification |
| --- |
| Encoding Standard # ref-for-dom-textdecoder-fatal① |

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

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


TextDecoder() - Web API 接口参考

TextDecoder()
=============

**`TextDecoder()`** 构造函数使用参数中指定的编码返回一个新创建的 `TextDecoder` 对象。

语法
--

```js
new TextDecoder()
new TextDecoder(utfLabel)
new TextDecoder(utfLabel, options)
```

### 参数

`utfLabel` 可选

一个字符串，默认是 `"utf-8"`。可以是任意有效的编码。

`options` 可选

一个具有属性的对象：

`fatal`

一个布尔值，表示在解码无效数据时，`TextDecoder.decode()` 方法是否必须抛出 `TypeError`。默认是 `false`，这意味着解码器将用替换字符替换错误的数据。

### 异常

`RangeError`

如果 `label` 值是未知的，或是使用了 `'replacement'` 解码算法（`"iso-2022-cn"` 或 `"iso-2022-cn-ext"` 两个值之一），则会抛出。

示例
--

```js
const textDecoder1 = new TextDecoder("iso-8859-2");
const textDecoder2 = new TextDecoder();
const textDecoder3 = new TextDecoder("csiso2022kr", { fatal: true }); // Allows TypeError exception to be thrown.
const textDecoder4 = new TextDecoder("iso-2022-cn"); // Throw a RangeError exception.
```

规范
--

| Specification |
| --- |
| Encoding Standard # ref-for-dom-textdecoder① |

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

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

参见
--

* 属于 `TextDecoder` 接口。


CanvasRenderingContext2D.setLineDash() - Web API 接口参考

CanvasRenderingContext2D.setLineDash()
======================================

Canvas 2D API 的`CanvasRenderingContext2D`接口的 **`setLineDash()`** 方法在填充线时使用虚线模式。它使用一组值来指定描述模式的线和间隙的交替长度。

**备注：** 如果要切换回至实线模式，将 dash list 设置为一个空数组即可。

语法
--

```js
setLineDash(segments);
```

### 参数

`segments`

一个`Array`数组。一组描述交替绘制线段和间距（坐标空间单位）长度的数字。如果数组元素的数量是奇数，数组的元素会被复制并重复。例如， `[5, 15, 25]` 会变成 `[5, 15, 25, 5, 15, 25]`。

### 返回值

`undefined`示例
--

### 基本示例

这是一段简单的代码片段，使用 `setLineDash` 方法绘制一条线段。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

// Dashed line
ctx.beginPath();
ctx.setLineDash([5, 15]);
ctx.moveTo(0, 50);
ctx.lineTo(300, 50);
ctx.stroke();

// Solid line
ctx.beginPath();
ctx.setLineDash([]);
ctx.moveTo(0, 100);
ctx.lineTo(300, 100);
ctx.stroke();
```

#### 结果
```

<canvas id="canvas" width="400" height="200" class="playable-canvas"></canvas>
<div class="playable-buttons">
  <input id="edit" type="button" value="Edit" />
  <input id="reset" type="button" value="Reset" />
</div>
<textarea id="code" class="playable-code">
ctx.setLineDash([5, 15]);
ctx.beginPath();
ctx.moveTo(0,100);
ctx.lineTo(400, 100);
ctx.stroke();</textarea
>
```

```
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var edit = document.getElementById("edit");
var code = textarea.value;

function drawCanvas() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  eval(textarea.value);
}

reset.addEventListener("click", function () {
  textarea.value = code;
  drawCanvas();
});

edit.addEventListener("click", function () {
  textarea.focus();
});

textarea.addEventListener("input", drawCanvas);
window.addEventListener("load", drawCanvas);
```

### 一些常见的模式

此示例说明了各种常见的线划线模式。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

下面创建的`drawDashedLine()` 函数使得多个虚线的绘制变得简单。它接收模式数组作为其唯一参数。

```js
function drawDashedLine(pattern) {
  ctx.beginPath();
  ctx.setLineDash(pattern);
  ctx.moveTo(0, y);
  ctx.lineTo(300, y);
  ctx.stroke();
  y += 20;
}

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let y = 15;

drawDashedLine([]);
drawDashedLine([1, 1]);
drawDashedLine([10, 10]);
drawDashedLine([20, 5]);
drawDashedLine([15, 3, 3, 3]);
drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3]);
drawDashedLine([12, 3, 3]); // Equals [12, 3, 3, 12, 3, 3]
```

#### Result

规范描述
----

| Specification |
| --- |
| HTML Standard # dom-context-2d-setlinedash-dev |

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

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

参见
--

* 接口定义，`CanvasRenderingContext2D`
* `CanvasRenderingContext2D.getLineDash()`
* `CanvasRenderingContext2D.lineDashOffset`


CanvasRenderingContext2D.arcTo() - Web API 接口参考

CanvasRenderingContext2D.arcTo()
================================

**`CanvasRenderingContext2D.arcTo()`** 是 Canvas 2D API 根据控制点和半径绘制圆弧路径，使用当前的描点 (前一个 moveTo 或 lineTo 等函数的止点)。根据当前描点与给定的控制点 1 连接的直线，和控制点 1 与控制点 2 连接的直线，作为使用指定半径的圆的**切线**，画出两条切线之间的弧线路径。

语法
--
```

void ctx.arcTo(x1, y1, x2, y2, radius);
```

### Parameters

`x1`

第一个控制点的 x 轴坐标。

`y1`

第一个控制点的 y 轴坐标。

`x2`

第二个控制点的 x 轴坐标。

`y2`

第二个控制点的 y 轴坐标。

`radius`

圆弧的半径。

示例
--

### 使用 `arcTo` 方法

这是一段绘制圆弧的简单的代码片段。基础点是蓝色的，两个控制点是红色的。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

ctx.setLineDash([]);
ctx.beginPath();
ctx.moveTo(150, 20);
ctx.arcTo(150, 100, 50, 20, 30);
ctx.stroke();

ctx.fillStyle = "blue";
// base point
ctx.fillRect(150, 20, 10, 10);

ctx.fillStyle = "red";
// control point one
ctx.fillRect(150, 100, 10, 10);
// control point two
ctx.fillRect(50, 20, 10, 10);
//
ctx.setLineDash([5, 5]);
ctx.moveTo(150, 20);
ctx.lineTo(150, 100);
ctx.lineTo(50, 20);
ctx.stroke();
ctx.beginPath();
ctx.arc(120, 38, 30, 0, 2 \* Math.PI);
ctx.stroke();
```

### 尝试 `arcTo` 参数

修改下面的代码并在线查看 canvas 的变化：
```

<canvas id="canvas" class="playable-canvas" height="200" width="400"></canvas>
<div class="playable-buttons">
  <input id="edit" type="button" value="Edit" />
  <input id="reset" type="button" value="Reset" />
</div>
<textarea id="code" class="playable-code">
ctx.setLineDash([])
ctx.beginPath();
ctx.moveTo(150, 20);
ctx.arcTo(150,100,50,20,30);
ctx.stroke();

ctx.fillStyle = 'blue';
// base point
ctx.fillRect(150, 20, 10, 10);

ctx.fillStyle = 'red';
// control point one
ctx.fillRect(150, 100, 10, 10);
// control point two
ctx.fillRect(50, 20, 10, 10);
//
ctx.setLineDash([5,5])
ctx.moveTo(150, 20);
ctx.lineTo(150,100);
ctx.lineTo(50, 20);
ctx.stroke();
ctx.beginPath();
ctx.arc(120,38,30,0,2*Math.PI);
ctx.stroke();</textarea
>
```

```
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var edit = document.getElementById("edit");
var code = textarea.value;

function drawCanvas() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  eval(textarea.value);
}

reset.addEventListener("click", function () {
  textarea.value = code;
  drawCanvas();
});

edit.addEventListener("click", function () {
  textarea.focus();
});

textarea.addEventListener("input", drawCanvas);
window.addEventListener("load", drawCanvas);
```

规范描述
----

| Specification |
| --- |
| HTML Standard # dom-context-2d-arcto-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`


CanvasRenderingContext2D.textBaseline - Web API 接口参考

CanvasRenderingContext2D.textBaseline
=====================================

**`CanvasRenderingContext2D.textBaseline`** 是 Canvas 2D API 描述绘制文本时，当前文本基线的属性。

>
> 译者注：决定文字垂直方向的对齐方式。
>
>
>

语法
--
```

ctx.textBaseline = "top" || "hanging" || "middle" || "alphabetic" || "ideographic" || "bottom";
```

### 选项

有效值：

top

文本基线在文本块的顶部。

hanging

文本基线是悬挂基线。

middle

文本基线在文本块的中间。

alphabetic

文本基线是标准的字母基线。

ideographic

文字基线是表意字基线；如果字符本身超出了 alphabetic 基线，那么 ideograhpic 基线位置在字符本身的底部。

bottom

文本基线在文本块的底部。与 ideographic 基线的区别在于 ideographic 基线不需要考虑下行字母。

默认值是 `alphabetic`。

示例
--

### 属性值比较

这是一段简单的代码片段，使用 `textBaseline` 属性设置不同的文本基线。

#### HTML

```html
<canvas id="canvas" width="550" height="500"></canvas>
```

#### JavaScript

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

const baselines = [
  "top",
  "hanging",
  "middle",
  "alphabetic",
  "ideographic",
  "bottom",
];
ctx.font = "36px serif";
ctx.strokeStyle = "red";

baselines.forEach((baseline, index) => {
  ctx.textBaseline = baseline;
  const y = 75 + index \* 75;
  ctx.beginPath();
  ctx.moveTo(0, y + 0.5);
  ctx.lineTo(550, y + 0.5);
  ctx.stroke();
  ctx.fillText(`Abcdefghijklmnop (${baseline})`, 0, y);
});
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-textbaseline-dev |

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

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

参见
--

* 接口定义，`CanvasRenderingContext2D`.


CanvasRenderingContext2D.drawFocusIfNeeded() - Web API 接口参考

CanvasRenderingContext2D.drawFocusIfNeeded()
============================================

**`CanvasRenderingContext2D.drawFocusIfNeeded()`** 是 Canvas 2D API 用来给当前路径或特定路径绘制焦点的方法，如果给定的元素获取了焦点。

语法
--
```

void ctx.drawFocusIfNeeded(element);
void ctx.drawFocusIfNeeded(path, element);
```

### 参数

element

是否需要设置焦点的元素。

`path`

`Path2D` 路径。

示例
--

### 控制按钮焦点

这是一段使用 `drawFocusIfNeeded` 方法的简单的代码片段。

#### HTML

```html
<canvas id="canvas">
  <button id="button1">Continue</button>
  <button id="button2">Quit</button>
</canvas>
```

#### JavaScript

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

document.addEventListener("focus", redraw, true);
document.addEventListener("blur", redraw, true);
canvas.addEventListener("click", handleClick, false);
redraw();

function redraw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawButton(button1, 20, 20);
  drawButton(button2, 20, 80);
}

function handleClick(e) {
  // Calculate click coordinates
  const x = e.clientX - canvas.offsetLeft;
  const y = e.clientY - canvas.offsetTop;

  // Focus button1, if appropriate
  drawButton(button1, 20, 20);
  if (ctx.isPointInPath(x, y)) {
    button1.focus();
  }

  // Focus button2, if appropriate
  drawButton(button2, 20, 80);
  if (ctx.isPointInPath(x, y)) {
    button2.focus();
  }
}

function drawButton(el, x, y) {
  const active = document.activeElement === el;
  const width = 150;
  const height = 40;

  // Button background
  ctx.fillStyle = active ? "pink" : "lightgray";
  ctx.fillRect(x, y, width, height);

  // Button text
  ctx.font = "15px sans-serif";
  ctx.textAlign = "center";
  ctx.textBaseline = "middle";
  ctx.fillStyle = active ? "blue" : "black";
  ctx.fillText(el.textContent, x + width / 2, y + height / 2);

  // Define clickable area
  ctx.beginPath();
  ctx.rect(x, y, width, height);

  // Draw focus ring, if appropriate
  ctx.drawFocusIfNeeded(el);
}
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-drawfocusifneeded-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`.


CanvasRenderingContext2D.globalCompositeOperation - Web API 接口参考

CanvasRenderingContext2D.globalCompositeOperation
=================================================

Canvas 2D API 的 **`CanvasRenderingContext2D.globalCompositeOperation`** 属性设置要在绘制新形状时应用的合成操作的类型，其中 type 是用于标识要使用的合成或混合模式操作的字符串。

在 Canvas Tutorial 中查看 Compositing 章节。

值
-

标识要使用的合成或混合模式操作的字符串。可以是以下值之一：

`"source-over"`

这是默认设置，并在现有画布上绘制新图形。

`"source-in"`

仅在新形状和目标画布重叠的地方绘制新形状。其他的都是透明的。

`"source-out"`

在不与现有画布内容重叠的地方绘制新图形。

`"source-atop"`

只在与现有画布内容重叠的地方绘制新图形。

`"destination-over"`

在现有画布内容的后面绘制新的图形。

`"destination-in"`

仅保留现有画布内容和新形状重叠的部分。其他的都是透明的。

`"destination-out"`

仅保留现有画布内容和新形状不重叠的部分。

`"destination-atop"`

仅保留现有画布内容和新形状重叠的部分。新形状是在现有画布内容的后面绘制的。

`"lighter"`

两个重叠图形的颜色是通过颜色值相加来确定的。

`"copy"`

只显示新图形。

`"xor"`

形状在重叠处变为透明，并在其他地方正常绘制。

`"multiply"`

将顶层像素与底层相应像素相乘，结果是一幅更黑暗的图片。

`"screen"`

像素被倒转、相乘、再倒转，结果是一幅更明亮的图片（与 `multiply` 相反）。

`"overlay"`

`multiply` 和 `screen` 的结合。原本暗的地方更暗，原本亮的地方更亮。

`"darken"`

保留两个图层中最暗的像素。

`"lighten"`

保留两个图层中最亮的像素。

`"color-dodge"`

将底层除以顶层的反置。

`"color-burn"`

将反置的底层除以顶层，然后将结果反过来。

`"hard-light"`

类似于 `overlay`，`multiply` 和 `screen` 的结合——但上下图层互换了。

`"soft-light"`

柔和版本的 `hard-light`。纯黑或纯白不会导致纯黑或纯白。

`"difference"`

从顶层减去底层（或反之亦然），始终得到正值。

`"exclusion"`

与 `difference` 类似，但对比度较低。

`"hue"`

保留底层的亮度（luma）和色度（chroma），同时采用顶层的色调（hue）。

`"saturation"`

保留底层的亮度和色调，同时采用顶层的色度。

`"color"`

保留了底层的亮度，同时采用了顶层的色调和色度。

`"luminosity"`

保持底层的色调和色度，同时采用顶层的亮度。

示例
--

### 改变合成操作

这是一段使用 `globalCompositeOperation` 属性的简单的代码片段，绘制了 2 个矩形在重叠时相互排斥的情况。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

ctx.globalCompositeOperation = "xor";

ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);

ctx.fillStyle = "red";
ctx.fillRect(50, 50, 100, 100);
```

#### 结果

### 展示所有值

#### 全局值

这段代码设置了程序的其他部分使用的全局值。

```js
const canvas1 = document.createElement("canvas");
const canvas2 = document.createElement("canvas");
const gco = [
  "source-over",
  "source-in",
  "source-out",
  "source-atop",
  "destination-over",
  "destination-in",
  "destination-out",
  "destination-atop",
  "lighter",
  "copy",
  "xor",
  "multiply",
  "screen",
  "overlay",
  "darken",
  "lighten",
  "color-dodge",
  "color-burn",
  "hard-light",
  "soft-light",
  "difference",
  "exclusion",
  "hue",
  "saturation",
  "color",
  "luminosity",
].reverse();
const gcoText = [
  "这是默认设置，并在现有画布上下文之上绘制新图形。",
  "新图形只在新图形和目标画布重叠的地方绘制。其他的都是透明的。",
  "在不与现有画布内容重叠的地方绘制新图形。",
  "新图形只在与现有画布内容重叠的地方绘制。",
  "在现有的画布内容后面绘制新的图形。",
  "现有的画布内容保持在新图形和现有画布内容重叠的位置。其他的都是透明的。",
  "现有内容保持在新图形不重叠的地方。",
  "现有的画布只保留与新图形重叠的部分，新的图形是在画布内容后面绘制的。",
  "两个重叠图形的颜色是通过颜色值相加来确定的。",
  "只显示新图形。",
  "图像中，那些重叠和正常绘制之外的其他地方是透明的。",
  "将顶层像素与底层相应像素相乘，结果是一幅更黑暗的图片。",
  "像素被倒转，相乘，再倒转，结果是一幅更明亮的图片。",
  "multiply 和 screen 的结合，原本暗的地方更暗，原本亮的地方更亮。",
  "保留两个图层中最暗的像素。",
  "保留两个图层中最亮的像素。",
  "将底层除以顶层的反置。",
  "将反置的底层除以顶层，然后将结果反过来。",
  "multiply 和 screen 的结合，类似于叠加，但上下图层互换了。",
  "用顶层减去底层或者相反来得到一个正值。",
  "一个柔和版本的 hard-light。纯黑或纯白不会导致纯黑或纯白。",
  "和 difference 相似，但对比度较低。",
  "保留了底层的亮度和色度，同时采用了顶层的色调。",
  "保留底层的亮度和色调，同时采用顶层的色度。",
  "保留了底层的亮度，同时采用了顶层的色调和色度。",
  "保持底层的色调和色度，同时采用顶层的亮度。",
].reverse();
const width = 320;
const height = 340;
```

#### 主程序

在页面加载时，该代码设置并运行示例：

```js
window.onload = () => {
  // sRGB 中的 lum
  const lum = {
    r: 0.33,
    g: 0.33,
    b: 0.33,
  };
  // 调整画布大小
  canvas1.width = width;
  canvas1.height = height;
  canvas2.width = width;
  canvas2.height = height;
  lightMix();
  colorSphere();
  runComposite();
  return;
};
```

而这段 `runComposite()` 代码处理了大部分的工作，但需要依赖于许多工具函数来完成复杂的处理工作。

```js
function createCanvas() {
  const canvas = document.createElement("canvas");
  canvas.style.background = `url(${op\_8x8.data})`;
  canvas.style.border = "1px solid #000";
  canvas.style.margin = "5px";
  canvas.width = width / 2;
  canvas.height = height / 2;
  return canvas;
}

function runComposite() {
  const dl = document.createElement("dl");
  document.body.appendChild(dl);
  while (gco.length) {
    const pop = gco.pop();
    const dt = document.createElement("dt");
    dt.textContent = pop;
    dl.appendChild(dt);
    const dd = document.createElement("dd");
    const p = document.createElement("p");
    p.textContent = gcoText.pop();
    dd.appendChild(p);

    const canvasToDrawOn = createCanvas();
    const canvasToDrawFrom = createCanvas();
    const canvasToDrawResult = createCanvas();

    let ctx = canvasToDrawResult.getContext("2d");
    ctx.clearRect(0, 0, width, height);
    ctx.save();
    ctx.drawImage(canvas1, 0, 0, width / 2, height / 2);
    ctx.globalCompositeOperation = pop;
    ctx.drawImage(canvas2, 0, 0, width / 2, height / 2);
    ctx.globalCompositeOperation = "source-over";
    ctx.fillStyle = "rgba(0,0,0,0.8)";
    ctx.fillRect(0, height / 2 - 20, width / 2, 20);
    ctx.fillStyle = "#FFF";
    ctx.font = "14px arial";
    ctx.fillText(pop, 5, height / 2 - 5);
    ctx.restore();

    ctx = canvasToDrawOn.getContext("2d");
    ctx.clearRect(0, 0, width, height);
    ctx.save();
    ctx.drawImage(canvas1, 0, 0, width / 2, height / 2);
    ctx.fillStyle = "rgba(0,0,0,0.8)";
    ctx.fillRect(0, height / 2 - 20, width / 2, 20);
    ctx.fillStyle = "#FFF";
    ctx.font = "14px arial";
    ctx.fillText("现有内容", 5, height / 2 - 5);
    ctx.restore();

    ctx = canvasToDrawFrom.getContext("2d");
    ctx.clearRect(0, 0, width, height);
    ctx.save();
    ctx.drawImage(canvas2, 0, 0, width / 2, height / 2);
    ctx.fillStyle = "rgba(0,0,0,0.8)";
    ctx.fillRect(0, height / 2 - 20, width / 2, 20);
    ctx.fillStyle = "#FFF";
    ctx.font = "14px arial";
    ctx.fillText("新内容", 5, height / 2 - 5);
    ctx.restore();

    dd.appendChild(canvasToDrawOn);
    dd.appendChild(canvasToDrawFrom);
    dd.appendChild(canvasToDrawResult);

    dl.appendChild(dd);
  }
}
```

#### 工具函数

该程序依赖许多工具函数。

```js
const lightMix = () => {
  const ctx = canvas2.getContext("2d");
  ctx.save();
  ctx.globalCompositeOperation = "lighter";
  ctx.beginPath();
  ctx.fillStyle = "rgba(255,0,0,1)";
  ctx.arc(100, 200, 100, Math.PI \* 2, 0, false);
  ctx.fill();
  ctx.beginPath();
  ctx.fillStyle = "rgba(0,0,255,1)";
  ctx.arc(220, 200, 100, Math.PI \* 2, 0, false);
  ctx.fill();
  ctx.beginPath();
  ctx.fillStyle = "rgba(0,255,0,1)";
  ctx.arc(160, 100, 100, Math.PI \* 2, 0, false);
  ctx.fill();
  ctx.restore();
  ctx.beginPath();
  ctx.fillStyle = "#f00";
  ctx.fillRect(0, 0, 30, 30);
  ctx.fill();
};
```

```js
const colorSphere = (element) => {
  const ctx = canvas1.getContext("2d");
  const width = 360;
  const halfWidth = width / 2;
  const rotate = (1 / 360) \* Math.PI \* 2; // 每度的弧度
  const offset = 0; // scrollbar offset
  const oleft = -20;
  const otop = -20;
  for (let n = 0; n <= 359; n++) {
    const gradient = ctx.createLinearGradient(
      oleft + halfWidth,
      otop,
      oleft + halfWidth,
      otop + halfWidth,
    );
    const color = Color.HSV\_RGB({ H: (n + 300) % 360, S: 100, V: 100 });
    gradient.addColorStop(0, "rgba(0,0,0,0)");
    gradient.addColorStop(0.7, `rgba(${color.R}, ${color.G}, ${color.B}, 1)`);
    gradient.addColorStop(1, "rgba(255,255,255,1)");
    ctx.beginPath();
    ctx.moveTo(oleft + halfWidth, otop);
    ctx.lineTo(oleft + halfWidth, otop + halfWidth);
    ctx.lineTo(oleft + halfWidth + 6, otop);
    ctx.fillStyle = gradient;
    ctx.fill();
    ctx.translate(oleft + halfWidth, otop + halfWidth);
    ctx.rotate(rotate);
    ctx.translate(-(oleft + halfWidth), -(otop + halfWidth));
  }
  ctx.beginPath();
  ctx.fillStyle = "#00f";
  ctx.fillRect(15, 15, 30, 30);
  ctx.fill();
  return ctx.canvas;
};
```

```js
// HSV (1978) = H: Hue / S: Saturation / V: Value
Color = {};
Color.HSV\_RGB = (o) => {
  const S = o.S / 100;
  let H = o.H / 360,
    V = o.V / 100;
  let R, G;
  let A, B, C, D;
  if (S === 0) {
    R = G = B = Math.round(V \* 255);
  } else {
    if (H >= 1) H = 0;
    H \*= 6;
    D = H - Math.floor(H);
    A = Math.round(255 \* V \* (1 - S));
    B = Math.round(255 \* V \* (1 - S \* D));
    C = Math.round(255 \* V \* (1 - S \* (1 - D)));
    V = Math.round(255 \* V);
    switch (Math.floor(H)) {
      case 0:
        R = V;
        G = C;
        B = A;
        break;
      case 1:
        R = B;
        G = V;
        B = A;
        break;
      case 2:
        R = A;
        G = V;
        B = C;
        break;
      case 3:
        R = A;
        G = B;
        B = V;
        break;
      case 4:
        R = C;
        G = A;
        B = V;
        break;
      case 5:
        R = V;
        G = A;
        B = B;
        break;
    }
  }
  return { R, G, B };
};

const createInterlace = (size, color1, color2) => {
  const proto = document.createElement("canvas").getContext("2d");
  proto.canvas.width = size \* 2;
  proto.canvas.height = size \* 2;
  proto.fillStyle = color1; // top-left
  proto.fillRect(0, 0, size, size);
  proto.fillStyle = color2; // top-right
  proto.fillRect(size, 0, size, size);
  proto.fillStyle = color2; // bottom-left
  proto.fillRect(0, size, size, size);
  proto.fillStyle = color1; // bottom-right
  proto.fillRect(size, size, size, size);
  const pattern = proto.createPattern(proto.canvas, "repeat");
  pattern.data = proto.canvas.toDataURL();
  return pattern;
};

const op_8x8 = createInterlace(8, "#FFF", "#eee");
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-globalcompositeoperation-dev |

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

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

参见
--

* 接口定义，`CanvasRenderingContext2D`
* `CanvasRenderingContext2D.globalAlpha`


CanvasRenderingContext2D.save() - Web API 接口参考

CanvasRenderingContext2D.save()
===============================

**`CanvasRenderingContext2D.save()`** 是 Canvas 2D API 通过将当前状态放入栈中，保存 canvas 全部状态的方法。

语法
--
```

void ctx.save();
```

绘制状态
----

保存到栈中的绘制状态有下面部分组成：

* 当前的变换矩阵。
* 当前的剪切区域。
* 当前的虚线列表。
* 以下属性当前的值： `strokeStyle`, `fillStyle`, `globalAlpha`, `lineWidth`, `lineCap`, `lineJoin`, `miterLimit`, `lineDashOffset`, `shadowOffsetX`, `shadowOffsetY`, `shadowBlur`, `shadowColor`, `globalCompositeOperation`, `font`, `textAlign`, `textBaseline`, `direction`, `imageSmoothingEnabled`.
示例
--

### 保存绘图状态

这是一段简单的代码片段，使用 `save` 方法保存默认的状态，这样，稍后你就可以使用默认的设置绘制一个矩形。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

// Save the current state
ctx.save();

ctx.fillStyle = "green";
ctx.fillRect(10, 10, 100, 100);

// Restore to the state saved by the most recent call to save()
ctx.restore();

ctx.fillRect(150, 40, 100, 100);
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-save-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`.
* `CanvasRenderingContext2D.restore()`


CanvasRenderingContext2D.createLinearGradient() - Web API 接口参考

CanvasRenderingContext2D.createLinearGradient()
===============================================

Canvas 2D API 的 **`CanvasRenderingContext2D.createLinearGradient()`** 方法会根据两个给定的坐标值所构成的线段创建一个线性渐变。

![](/zh-CN/docs/Web/API/CanvasRenderingContext2D/createLinearGradient/mdn-canvas-lineargradient.png)

该方法返回一个线性 `CanvasGradient`对象。想要应用这个渐变，需要把这个返回值赋值给 `fillStyle` 或者 `strokeStyle`。

语法
--
```

CanvasGradient ctx.createLinearGradient(x0, y0, x1, y1);
```

`createLinearGradient()` 方法需要指定四个参数，分别表示渐变线段的开始和结束点。

### 参数

`x0`

起点的 x 轴坐标。

`y0`

起点的 y 轴坐标。

`x1`

终点的 x 轴坐标。

`y1`

终点的 y 轴坐标。

### 返回值

`CanvasGradient`

一个根据指定线路初始化的线性 `CanvasGradient` 对象。

示例
--

### 使用线性渐变填充一个矩形

这个例子使用`createLinearGradient()` 方法初始化了一个线性渐变。在这个线性渐变中添加了三种色彩。最后，这个渐变被赋值给上下文对应的属性，实现了对矩形的填充。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

// Create a linear gradient
// The start gradient point is at x=20, y=0
// The end gradient point is at x=220, y=0
const gradient = ctx.createLinearGradient(20, 0, 220, 0);

// Add three color stops
gradient.addColorStop(0, "green");
gradient.addColorStop(0.5, "cyan");
gradient.addColorStop(1, "green");

// Set the fill style and draw a rectangle
ctx.fillStyle = gradient;
ctx.fillRect(20, 20, 200, 100);
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-createlineargradient-dev |

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

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

参见
--

* 接口定义： `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.createRadialGradient()`


CanvasRenderingContext2D.restore() - Web API 接口参考

CanvasRenderingContext2D.restore()
==================================

**`CanvasRenderingContext2D.restore()`** 是 Canvas 2D API 通过在绘图状态栈中弹出顶端的状态，将 canvas 恢复到最近的保存状态的方法。如果没有保存状态，此方法不做任何改变。

语法
--
```

void ctx.restore();
```

更多关于 drawing state (en-US) 的信息，请看 `CanvasRenderingContext2D.save()`。

示例
--

### 恢复保存的状态

这是一段简单的代码片段，使用 `save()` 方法保存默认的状态，使用 `restore()` 进行恢复。所以，稍后你可以使用默认的状态绘制一个矩形。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

// Save the current state
ctx.save();

ctx.fillStyle = "green";
ctx.fillRect(10, 10, 100, 100);

// Restore to the state saved by the most recent call to save()
ctx.restore();

ctx.fillRect(150, 40, 100, 100);
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-restore-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`.
* `CanvasRenderingContext2D.save()`


CanvasRenderingContext2D.stroke() - Web API 接口参考

CanvasRenderingContext2D.stroke()
=================================

**`CanvasRenderingContext2D.stroke()`** 是 Canvas 2D API 使用非零环绕规则，根据当前的画线样式，绘制当前或已经存在的路径的方法。

语法
--
```

void ctx.stroke();
void ctx.stroke(path);
```

### Parameters

`path`

绘制的路径`Path2D` 。

示例
--

### 一个简单的矩形轮廓线

这是一段简单的代码片段，使用 `stroke` 方法绘制一条路径。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
ctx.rect(10, 10, 150, 100);
ctx.stroke();
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-stroke-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`.


CanvasRenderingContext2D.direction - Web API 接口参考

CanvasRenderingContext2D.direction
==================================

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

**`CanvasRenderingContext2D.direction`** 是 Canvas 2D API 用来在绘制文本时，描述当前文本方向的属性。

语法
--
```

ctx.direction = "ltr" || "rtl" || "inherit";
```

### 选项

有效值：

ltr

文本方向从左向右。

rtl

文本方向从右向左。

inherit

根据情况继承 `<canvas>` 元素或者 `Document` 。

默认值是 `inherit`。

示例
--

### 使用 `direction` 属性

这是一段简单的代码片段，对文本设置不同的 direction 数值。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

ctx.font = "48px serif";
ctx.fillText("Hi!", 150, 50);
ctx.direction = "rtl";
ctx.fillText("Hi!", 150, 130);
```

```
<canvas id="canvas" width="550" height="500"></canvas>
```

```
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

ctx.font = "48px serif";
ctx.fillText("Hi!", 150, 50);
ctx.direction = "rtl";
ctx.fillText("Hi!", 150, 130);
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-direction-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`.


CanvasRenderingContext2D.ellipse() - Web API 接口参考

CanvasRenderingContext2D.ellipse()
==================================

**`CanvasRenderingContext2D.ellipse()`** 是 Canvas 2D API 添加椭圆路径的方法。椭圆的圆心在（x,y）位置，半径分别是*radiusX* 和 *radiusY*，按照*anticlockwise*（默认顺时针）指定的方向，从 *startAngle* 开始绘制，到 *endAngle* 结束。

语法
--
```

void ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);
```

### 参数

`x`

椭圆圆心的 x 轴坐标。

`y`

椭圆圆心的 y 轴坐标。

`radius`X

椭圆长轴的半径。

`radius`Y

椭圆短轴的半径。

`rotation`

椭圆的旋转角度，以弧度表示 (**非角度度数**)。

`startAngle`

将要绘制的起始点角度，从 x 轴测量，以弧度表示 (**非角度度数**)。

`endAngle`

椭圆将要绘制的结束点角度，以弧度表示 (**非角度度数**)。

`anticlockwise` 可选

`Boolean` 选项，如果为 `true`，逆时针方向绘制椭圆（逆时针），反之顺时针方向绘制。

示例
--

### 画一个完整的椭圆

这是一段绘制椭圆的简单的代码片段。

#### HTML

```html
<canvas id="canvas" width="200" height="200"></canvas>
```

#### JavaScript

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

// Draw the ellipse
ctx.beginPath();
ctx.ellipse(100, 100, 50, 75, Math.PI / 4, 0, 2 \* Math.PI);
ctx.stroke();

// Draw the ellipse's line of reflection
ctx.beginPath();
ctx.setLineDash([5, 5]);
ctx.moveTo(0, 200);
ctx.lineTo(200, 0);
ctx.stroke();
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-ellipse-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`


CanvasRenderingContext2D.createImageData() - Web API 接口参考

CanvasRenderingContext2D.createImageData()
==========================================

**`CanvasRenderingContext2D.createImageData()`** 是 Canvas 2D API 创建一个新的、空白的、指定大小的 `ImageData` 对象。所有的像素在新对象中都是透明的。

语法
--
```

ImageData ctx.createImageData(width, height);
ImageData ctx.createImageData(imagedata);
```

### 参数

`width`

`ImageData` 新对象的宽度。

`height`

`ImageData` 新对象的高度。

`imagedata`

从现有的 `ImageData` 对象中，复制一个和其宽度和高度相同的对象。图像自身不允许被复制。

### 返回值

指定了宽度和高度的，新的 `ImageData` 对象。新对象使用透明的像素进行填充。

### 抛出错误

`IndexSizeError`

如果宽度或者高度变量值为零，会抛出此异常。

示例
--

### 使用 `createImageData` 方法

这是一段简单地使用 `createImageData` 方法的代码片段。获取更多信息，请看 canvas 像素控制 和 `ImageData` 对象。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.rect(10, 10, 100, 100);
ctx.fill();

console.log(ctx.createImageData(100, 100));
// ImageData { width: 100, height: 100, data: Uint8ClampedArray[40000] }
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-createimagedata-dev |

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

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

### 兼容性注解

* 从 Gecko 5.0 开始：
    + 如果矩形小于指定的 1 个像素，`createImageData()` 会返回图像数据至少 1 个像素值。
    + 当调用 `createImageData()` 指定非限制值时，会抛出`NOT_SUPPORTED_ERR` exception 异常。
    + `createImageData()` 根据规定处理负数变量，会围绕对称轴翻转矩形区域。
参见
--

* 接口定义，`CanvasRenderingContext2D`.
* `ImageData`
* canvas 像素控制


CanvasRenderingContext2D.lineTo() - Web API 接口参考

CanvasRenderingContext2D.lineTo()
=================================

**`CanvasRenderingContext2D.lineTo()`** 是 Canvas 2D API 使用直线连接子路径的终点到 x，y 坐标的方法（并不会真正地绘制）。

语法
--
```

void ctx.lineTo(x, y);
```

### 参数

`x`

直线终点的 x 轴坐标。

`y`

直线终点的 y 轴坐标。

示例
--

### 画一条直线

这是一段使用 `lineTo` 方法的简单的代码片段。使用 `beginPath()` 绘制路径的起始点，使用 `moveTo()`移动画笔，使用 `stroke()` 方法真正地画线。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

线从 (30, 50) 处开始，并在 (150, 100) 处结束。

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

ctx.beginPath(); // Start a new path
ctx.moveTo(30, 50); // Move the pen to (30, 50)
ctx.lineTo(150, 100); // Draw a line to (150, 100)
ctx.stroke(); // Render the path
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-lineto-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.moveTo()`
* `CanvasRenderingContext2D.stroke()`


CanvasRenderingContext2D.imageSmoothingQuality - Web API 接口参考

CanvasRenderingContext2D.imageSmoothingQuality
==============================================

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

**CanvasRenderingContext2D.imageSmoothingQuality** 是 Canvas 2D API，用于设置图像平滑度的属性。

语法
--
```

ctx.imageSmoothingQuality = value
value = ctx.imageSmoothingQuality
```

### 选项

`value`

"low","medium","high"

示例
--

### 设置图像平滑质量

这是一段简单的代码片段，对缩放的图片使用 `imageSmoothingQuality` 属性。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

let img = new Image();
img.src = "canvas\_createpattern.png";
img.onload = () => {
  ctx.imageSmoothingQuality = "low";
  ctx.drawImage(img, 0, 0, 300, 150);
};
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-imagesmoothingquality-dev |

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

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

参见
--

* 接口定义，`CanvasRenderingContext2D`
* `image-rendering`


CanvasRenderingContext2D：fillText() 方法 - Web API 接口参考

CanvasRenderingContext2D：fillText() 方法
======================================

`CanvasRenderingContext2D` 对象的方法 **`fillText()`** 是 Canvas 2D API 的一部分，它在指定的坐标上绘制文本字符串，并使用当前的 `fillStyle` 对其进行填充。存在一个可选参数，其指定了渲染文本的最大宽度，用户代理将通过压缩文本或使用较小的字体大小来实现。

此方法会直接绘制到画布上，而不会修改当前路径，因此任何后续的 `fill()` 或 `stroke()` 调用都不会对其产生影响。

文本根据 `font`、`textAlign`、`textBaseline` 和 `direction` 属性所定义的字体和文本布局来渲染。

**备注：** 如果需要绘制字符串中字符的轮廓，需要调用其上下文的 `strokeText()` 方法。

语法
--

```js
fillText(text, x, y)
fillText(text, x, y, maxWidth)
```

### 参数

`text`

要作为渲染上下文的文本字符串。使用当前的 `font`、`textAlign`、`textBaseline` 和 `direction` 设置值对文本进行渲染。

`x`

开始绘制文本的点的 X 轴坐标，单位为像素。

`y`

开始绘制文本的基线的 Y 轴坐标，单位为像素。

`maxWidth` 可选

文本渲染后的最大像素宽度。如果未指定，则文本宽度没有限制。但是，如果提供了该值，用户代理将调整字距，选择水平方向更紧凑的字体（如果有这种字体或可以在不降低质量的情况下生成这种字体），或缩小字体大小，以便在指定宽度内容纳文本。

### 返回值

无（`undefined`）。

示例
--

### 绘制填充文本

这段代码使用 `fillText()` 方法绘制了“Hello World”字符串。

#### HTML

首先，我们需要一个画布来绘图。这段代码将创建一个宽 400 像素，宽 150 像素的背景。

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

#### JavaScript

以下是此示例的 JavaScript 代码。

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

ctx.font = "50px serif";
ctx.fillText("Hello world", 50, 90);
```

这段代码获取 `<canvas>` 的引用，然后获取其 2D 图形上下文的引用。

有了这些，我们将 `font` 设置为 50 像素高的“衬线体”（用户默认的衬线字体），然后调用 `fillText()` 从坐标 (50, 90) 开始绘制文本“Hello world”。

#### 结果

### 限制文本大小

本示例绘制了“Hello world”字符串并将其宽度限制为 140 像素。

#### HTML

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

#### JavaScript

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

ctx.font = "50px serif";
ctx.fillText("Hello world", 50, 90, 140);
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-filltext-dev |

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

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

参见
--

* 绘制文本
* `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.strokeText()`


CanvasRenderingContext2D.rect() - Web API 接口参考

CanvasRenderingContext2D.rect()
===============================

**`CanvasRenderingContext2D.rect()`** 是 Canvas 2D API 创建矩形路径的方法，矩形的起点位置是 *(x, y)*，尺寸为 *width* 和 *height*。矩形的 4 个点通过直线连接，子路径做为闭合的标记，所以你可以填充或者描边矩形。

语法
--
```

void ctx.rect(x, y, width, height);
```

### 参数

`x`

矩形起点的 x 轴坐标。

`y`

矩形起点的 y 轴坐标。

`width`

矩形的宽度。

`height`

矩形的高度。

示例
--

### 绘制矩形

这是一段简单的代码片段，使用 `rect` 方法创建一条路径。实际上，在 canvas 中绘制矩形路径，你可以使用 `fill()` 或者 `stroke()` 方法。参见 `fillRect()` 和`strokeRect()` 方法，只需一步即可绘制。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
ctx.rect(10, 20, 150, 100);
ctx.fill();
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-rect-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.fillRect`
* `CanvasRenderingContext2D.strokeRect()`
* `CanvasRenderingContext2D.fill()`
* `CanvasRenderingContext2D.stroke()`


CanvasRenderingContext2D.shadowOffsetY - Web API 接口参考

CanvasRenderingContext2D.shadowOffsetY
======================================

**`CanvasRenderingContext2D.shadowOffsetY`** 是 Canvas 2D API 描述阴影垂直偏移距离的属性。

语法
--
```

ctx.shadowOffsetY = offset;
```

`offset`

阴影垂直偏移距离的 float 类型的值。默认值是 0。 `Infinity` 或者`NaN` 都会被忽略。

示例
--

### 垂直移动阴影

这是一段简单的代码片段，使用 `shadowOffsetY` 属性绘制阴影垂直偏移量。注意：将 shadowColor 属性设置成不透明，阴影才会被绘制。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

// Shadow
ctx.shadowColor = "red";
ctx.shadowOffsetY = 25;
ctx.shadowBlur = 10;

// Rectangle
ctx.fillStyle = "blue";
ctx.fillRect(20, 20, 150, 80);
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-shadowoffsety-dev |

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

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

参见
--

* 接口定义，`CanvasRenderingContext2D`.
* `CanvasRenderingContext2D.shadowOffsetX`
* `CanvasRenderingContext2D.shadowColor`
* `CanvasRenderingContext2D.shadowBlur`


CanvasRenderingContext2D.createRadialGradient() - Web API 接口参考

CanvasRenderingContext2D.createRadialGradient()
===============================================

**`CanvasRenderingContext2D.createRadialGradient()`** 是 Canvas 2D API 根据参数确定两个圆的坐标，绘制放射性渐变的方法。这个方法返回 `CanvasGradient`。

语法
--
```

CanvasGradient ctx.createRadialGradient(x0, y0, r0, x1, y1, r1);
```

### 参数

`x0`

开始圆形的 x 轴坐标。

`y0`

开始圆形的 y 轴坐标。

r0

开始圆形的半径。

`x1`

结束圆形的 x 轴坐标。

`y1`

结束圆形的 y 轴坐标。

r1

结束圆形的半径。

### 返回值

`CanvasGradient`

由两个指定的圆初始化的放射性 `CanvasGradient` 对象。

示例
--

### 用径向渐变填充矩形

这是一段简单的代码片段，使用 `createRadialGradient` 方法创建一个指定了开始和结束圆的 `CanvasGradient` 对象。一旦创建，你可以使用 `CanvasGradient.addColorStop()` 方法根据指定的偏移和颜色定义一个新的终止。你可以将当前的`fillStyle`设置成此渐变，当使用`fillRect()` 方法时，会在 canvas 上绘制出效果，如示例所示。

#### HTML

```html
<canvas id="canvas" width="200" height="200"></canvas>
```

#### JavaScript

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

// Create a radial gradient
// The inner circle is at x=110, y=90, with radius=30
// The outer circle is at x=100, y=100, with radius=70
const gradient = ctx.createRadialGradient(110, 90, 30, 100, 100, 70);

// Add three color stops
gradient.addColorStop(0, "pink");
gradient.addColorStop(0.9, "white");
gradient.addColorStop(1, "green");

// Set the fill style and draw a rectangle
ctx.fillStyle = gradient;
ctx.fillRect(20, 20, 160, 160);
```

#### 结果

规范描述
----

| Specification |
| --- |
| HTML Standard # dom-context-2d-createradialgradient-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.createLinearGradient()`


CanvasRenderingContext2D.moveTo() - Web API 接口参考

CanvasRenderingContext2D.moveTo()
=================================

**`CanvasRenderingContext2D.moveTo()`** 是 Canvas 2D API 将一个新的子路径的起始点移动到 (x，y) 坐标的方法。

语法
--
```

void ctx.moveTo(x, y);
```

### 参数

`x`

点的 x 轴。

`y`

点的 y 轴。

示例
--

### 绘制多条子路径

这是一段使用 `moveTo` 方法的简单的代码片段，移动画笔到起始点绘制一条线。

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

第一条线从 (50, 50) 处开始，至 (200, 50) 处结束。第二条线从 (50, 90) 处开始，至 (280, 120) 处结束。

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

ctx.beginPath();
ctx.moveTo(50, 50); // Begin first sub-path
ctx.lineTo(200, 50);
ctx.moveTo(50, 90); // Begin second sub-path
ctx.lineTo(280, 120);
ctx.stroke();
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-moveto-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.lineTo()`
* `CanvasRenderingContext2D.stroke()`


CanvasRenderingContext2D.getImageData() - Web API 接口参考

CanvasRenderingContext2D.getImageData()
=======================================

**`CanvasRenderingContext2D.getImageData()`** 返回一个`ImageData`对象，用来描述 canvas 区域隐含的像素数据，这个区域通过矩形表示，起始点为\*(sx, sy)、*宽为*sw、*高为*sh。\*

语法
--
```

ImageData ctx.getImageData(sx, sy, sw, sh);
```

### 参数

`sx`

将要被提取的图像数据矩形区域的左上角 x 坐标。

`sy`

将要被提取的图像数据矩形区域的左上角 y 坐标。

`sw`

将要被提取的图像数据矩形区域的宽度。

`sh`

将要被提取的图像数据矩形区域的高度。

### 返回值

一个`ImageData` 对象，包含 canvas 给定的矩形图像数据。

### 错误抛出

`IndexSizeError`

如果高度或者宽度变量为 0，则抛出错误。

示例
--

### 使用 `getImageData` 方法

这是一段使用 `getImageData` 方法的简单的代码片段。获取更多信息，请看 canvas 像素控制和 `ImageData` 对象。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.rect(10, 10, 100, 100);
ctx.fill();

console.log(ctx.getImageData(50, 50, 100, 100));
// ImageData { width: 100, height: 100, data: Uint8ClampedArray[40000] }
```

规范描述
----

| Specification |
| --- |
| HTML Standard # dom-context-2d-getimagedata-dev |

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

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

### 兼容性注解

* 从 Gecko 5.0 开始，`getImageData()` 可以正确地接受超出 canvas 边界的矩形；canvas 范围外的像素返回值是透明的，并且如果矩形小于一个像素，会返回至少一像素值的图像数据。
参见
--

* 接口定义， `CanvasRenderingContext2D`.
* `ImageData`
* Pixel manipulation with canvas


CanvasRenderingContext2D.fillStyle - Web API 接口参考

CanvasRenderingContext2D.fillStyle
==================================

**`CanvasRenderingContext2D.fillStyle`** 是 Canvas 2D API 使用内部方式描述颜色和样式的属性。默认值是 `#000` （黑色）。

参见 Canvas Tutorial 的 Applying styles and color 章节。

语法
--
```

ctx.fillStyle = color;
ctx.fillStyle = gradient;
ctx.fillStyle = pattern;
```

### 选项

`color`

`DOMString` 字符串，被转换成 CSS `<color>` 颜色值。

`gradient`

`CanvasGradient` 对象（线性渐变或者放射性渐变）.

`pattern`

`CanvasPattern` 对象（可重复图像）。

示例
--

### 改变形状的填充颜色

这是一段简单的代码片段，使用 `fillStyle` 属性设置不同的颜色。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
```

#### 结果

### `fillStyle` 使用 `for` 循环的例子

在这个例子中，我们使用两个 `for` 循环绘制一个矩形表格，每个单元格都有不同的颜色。最终的结果图像看起来像屏幕截图，其实没有令人惊叹的事情发生。我们使用两个变量 i 和 j 为每一个单元格生成唯一的 RGB 颜色，并且只改变红色和绿色的数值。蓝色通道的值是固定不变的。通过修改这些通道，你能生成各种各样的调色板。通过逐步地增加，你能实现类似 Photoshop 的调色板。
```

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

```js
var ctx = document.getElementById("canvas").getContext("2d");
for (var i = 0; i < 6; i++) {
  for (var j = 0; j < 6; j++) {
    ctx.fillStyle =
      "rgb(" +
      Math.floor(255 - 42.5 \* i) +
      "," +
      Math.floor(255 - 42.5 \* j) +
      ",0)";
    ctx.fillRect(j \* 25, i \* 25, 25, 25);
  }
}
```

结果看起来像是这样的：

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

规格描述
----

| Specification |
| --- |
| HTML Standard # dom-context-2d-fillstyle-dev |

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

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

### WebKit/Blink-specific 注解

* 支持 WebKit- 和 Blink-based 的浏览器中，有一个不标准的、被反对的方法 `ctx.setFillColor()` 已经实现。

```js
setFillColor(color, optional alpha);
setFillColor(grayLevel, optional alpha);
setFillColor(r, g, b, a);
setFillColor(c, m, y, k, a);
```

参见
--

* Canvas API
* 接口定义， `CanvasRenderingContext2D`
* 此属性使用的值：
    + `<color>` CSS 数据类型
    + `CanvasGradient` 对象
    + `CanvasPattern` 对象


CanvasRenderingContext2D.translate() - Web API 接口参考

CanvasRenderingContext2D.translate()
====================================

Canvas 2D API 的 **`CanvasRenderingContext2D.translate()`** 方法对当前网格添加平移变换的方法。

语法
--
```

void ctx.translate(x, y);
```

`translate()` 方法，将 canvas 按原始 x 点的水平方向、原始的 y 点垂直方向进行**平移变换**

![](/zh-CN/docs/Web/API/CanvasRenderingContext2D/translate/canvas_grid_translate.png)

### 参数

`x`

水平方向的移动距离。

y

垂直方向的移动距离。

示例
--

### 移动形状

这是一段使用 `translate` 方法的简单的代码片段。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

// Moved square
ctx.translate(110, 30);
ctx.fillStyle = "red";
ctx.fillRect(0, 0, 80, 80);

// Reset current transformation matrix to the identity matrix
ctx.setTransform(1, 0, 0, 1, 0, 0);

// Unmoved square
ctx.fillStyle = "gray";
ctx.fillRect(0, 0, 80, 80);
```

#### 结果

移动后的正方形是红色的，未移动的正方形是灰色的。

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-translate-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`


CanvasRenderingContext2D.closePath() - Web API 接口参考

CanvasRenderingContext2D.closePath()
====================================

**`CanvasRenderingContext2D.closePath()`** 是 Canvas 2D API 将笔点返回到当前子路径起始点的方法。它尝试从当前点到起始点绘制一条直线。如果图形已经是封闭的或者只有一个点，那么此方法不会做任何操作。

语法
--
```

void ctx.closePath();
```

示例
--

### 闭合三角形

这是一段使用 `closePath` 方法的简单的代码片段。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

ctx.beginPath();
ctx.moveTo(20, 140); // Move pen to bottom-left corner
ctx.lineTo(120, 10); // Line to top corner
ctx.lineTo(220, 140); // Line to bottom-right corner
ctx.closePath(); // Line to bottom-left corner
ctx.stroke();
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-closepath-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.beginPath()`


CanvasRenderingContext2D.miterLimit - Web API 接口参考

CanvasRenderingContext2D.miterLimit
===================================

The **`CanvasRenderingContext2D.miterLimit`** 是 Canvas 2D API 设置斜接面限制比例的属性。当获取属性值时，会返回当前的值（默认值是`10.0` ）。当给属性赋值时，0、负数、 `Infinity` 和 `NaN` 都会被忽略；除此之外都会被赋予一个新值。

参见 Canvas Tutorial 中的 Applying styles and color 章节。

语法
--
```

ctx.miterLimit = value;
```

### 选项

`value`

斜接面限制比例的的数字。0、负数、`Infinity` 和 `NaN` 都会被忽略。

简释
--
```

ctx.lineJoin = "miter"  // "miter" >   "round" )   "bevel" ]
```

只有当 lineJoin 显示为 ">" 时，miterLimit 才有效。边角的角度越小，斜接长度就会越大。为了避免斜接长度过长，我们可以使用 miterLimit 属性。如果斜接长度超过 miterLimit 的值，边角会以 lineJoin 的 " ] " 类型来显示

示例
--

### 使用 `miterLimit` 属性

查看 Canvas Tutorial 中的 Applying styles and color 章节，获取更多信息。
```

<canvas id="canvas" width="400" height="200" class="playable-canvas"></canvas>
<div class="playable-buttons">
  <input id="edit" type="button" value="Edit" />
  <input id="reset" type="button" value="Reset" />
</div>
<textarea id="code" class="playable-code">
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineWidth = 15;
ctx.lineTo(100, 100);
ctx.stroke();</textarea
>
```

```
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const textarea = document.getElementById("code");
const reset = document.getElementById("reset");
const edit = document.getElementById("edit");
const code = textarea.value;

function drawCanvas() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  eval(textarea.value);
}

reset.addEventListener("click", () => {
  textarea.value = code;
  drawCanvas();
});

edit.addEventListener("click", () => {
  textarea.focus();
});

textarea.addEventListener("input", drawCanvas);
window.addEventListener("load", drawCanvas);
```

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

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-miterlimit-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.lineCap`
* `CanvasRenderingContext2D.lineJoin`


CanvasRenderingContext2D.shadowOffsetX - Web API 接口参考

CanvasRenderingContext2D.shadowOffsetX
======================================

**`CanvasRenderingContext2D.shadowOffsetX`** 是 Canvas 2D API 描述阴影水平偏移距离的属性。

Syntax
------
```

ctx.shadowOffsetX = offset;
```

`offset`

阴影水平偏移距离的 float 类型的值。默认值是 0。 `Infinity` 或者`NaN`都会被忽略。

示例
--

### 水平移动阴影

这是一段简单的代码片段，使用 `shadowOffsetX` 属性设置阴影的水平偏移量。注意：将 shadowColor 属性设置成不透明，阴影才会被绘制。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

// Shadow
ctx.shadowColor = "red";
ctx.shadowOffsetX = 25;
ctx.shadowBlur = 10;

// Rectangle
ctx.fillStyle = "blue";
ctx.fillRect(20, 20, 150, 100);
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-shadowoffsetx-dev |

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

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

参见
--

* 接口定义，`CanvasRenderingContext2D`.
* `CanvasRenderingContext2D.shadowOffsetY`
* `CanvasRenderingContext2D.shadowColor`
* `CanvasRenderingContext2D.shadowBlur`


CanvasRenderingContext2D.createPattern() - Web API 接口参考

CanvasRenderingContext2D.createPattern()
========================================

**`CanvasRenderingContext2D.createPattern()`** 是 Canvas 2D API 使用指定的图像 (`CanvasImageSource`) 创建模式的方法。它通过 repetition 参数在指定的方向上重复元图像。此方法返回一个`CanvasPattern`对象。

语法
--
```

CanvasPattern ctx.createPattern(image, repetition);
```

### 参数

`image`

作为重复图像源的 `CanvasImageSource` 对象。可以是下列之一：

* `HTMLImageElement` (`<img>`),
* `HTMLVideoElement` (`<video>`),
* `HTMLCanvasElement` (`<canvas>`),
* `CanvasRenderingContext2D`,
* `ImageBitmap`,
* `ImageData`,
* `Blob`.

`repetition`

`DOMString`，指定如何重复图像。允许的值有：

* `"repeat"` (both directions),
* `"repeat-x"` (horizontal only),
* `"repeat-y"` (vertical only),
* `"no-repeat"` (neither).

如果为空字符串 (`''`) 或 `null` (但不是 `undefined`)，repetition 将被当作"repeat"。

### 返回值

`CanvasPattern`

描述模式的不透明对象

示例
--

### 从图像创建图案

这是一段简单的代码片段，使用 createPattern 方法创建一个指定图像和重复的`CanvasPattern` 对象。创建完成后，可以使用`CanvasPattern.setTransform()`方法对图案进行变形。如示例所示，你可以把此模式赋值给当前的`fillStyle`，当你使用`fillRect()` 方法时，会在 canvas 上绘制出效果。

#### HTML

```html
<canvas id="canvas" width="300" height="300"></canvas>
```

#### JavaScript

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

const img = new Image();
img.src = "canvas\_createpattern.png";
img.onload = () => {
  // Only use the image after it's loaded
  const pattern = ctx.createPattern(img, "repeat");
  ctx.fillStyle = pattern;
  ctx.fillRect(0, 0, 300, 300);
};
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-createpattern-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasPattern`


CanvasRenderingContext2D.shadowColor - Web API 接口参考

CanvasRenderingContext2D.shadowColor
====================================

**`CanvasRenderingContext2D.shadowColor`** 是 Canvas 2D API 描述阴影颜色的属性。

语法
--
```

ctx.shadowColor = color;
```

`color`

可以转换成 CSS `<color>` 值的`DOMString` 字符串。默认值是 fully-transparent black.

示例
--

### 为形状添加阴影

这是一段简单的代码片段，使用 `shadowColor` 属性设置阴影的颜色。注意：shadowColor 属性设置成不透明的，并且 `shadowBlur`、 `shadowOffsetX` 或者 `shadowOffsetY` 属性不为 0，阴影才会被绘制。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

// Shadow
ctx.shadowColor = "red";
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;

// Filled rectangle
ctx.fillRect(20, 20, 100, 100);

// Stroked rectangle
ctx.lineWidth = 6;
ctx.strokeRect(170, 20, 100, 100);
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-shadowcolor-dev |

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

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

参见
--

* 接口定义，`CanvasRenderingContext2D`.


CanvasRenderingContext2D.lineWidth - Web API 接口参考

CanvasRenderingContext2D.lineWidth
==================================

The **`CanvasRenderingContext2D.lineWidth`** 是 Canvas 2D API 设置线段厚度的属性（即线段的宽度）。

**备注：** 线可以通过`stroke()`, `strokeRect()`, 和`strokeText()` 方法绘制。

语法
--
```

ctx.lineWidth = value;
```

### 选项

`value`

描述线段宽度的数字。0、负数、 `Infinity` 和 `NaN` 会被忽略。

示例
--

### 改变线宽

此示例使用 15 个单位的线宽绘制直线和矩形。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

ctx.lineWidth = 15;

ctx.beginPath();
ctx.moveTo(20, 20);
ctx.lineTo(130, 130);
ctx.rect(40, 40, 70, 70);
ctx.stroke();
```

#### 结果

### 更多示例

有关此属性的更多示例和说明，请参阅在“画布教程”中的使用样式和颜色。

规范描述
----

| Specification |
| --- |
| HTML Standard # dom-context-2d-linewidth-dev |

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

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

### WebKit/Blink-specific 注解

* 在基于 WebKit- 和 Blink- 的浏览器中，除了此属性外，实现了一个不标准的并且不赞成使用的方法 `ctx.setLineWidth()` 。
### Gecko-specific 注解

* 从 Gecko 2.0 版本开始，设置`lineWidth` 为负数不再抛出异常，所有非正数值都会被忽略。
参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.lineCap`
* `CanvasRenderingContext2D.lineJoin`
* 使用样式和颜色


CanvasRenderingContext2D.shadowBlur - Web API 接口参考

CanvasRenderingContext2D.shadowBlur
===================================

**`CanvasRenderingContext2D.shadowBlur`** 是 Canvas 2D API 描述模糊效果程度的属性；它既不对应像素值也不受当前转换矩阵的影响。默认值是 0。

语法
--
```

ctx.shadowBlur = level;
```

`level`

描述模糊效果程度的，float 类型的值。默认值是 0。负数、 `Infinity` 或者 `NaN` 都会被忽略。

示例
--

### 为形状添加阴影

这是一段简单的代码片段，使用 `shadowblur` 属性设置模糊阴影。注意：只有设置 shadowColor 属性值为不透明，阴影才会被绘制。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

// Shadow
ctx.shadowColor = "red";
ctx.shadowBlur = 15;

// Rectangle
ctx.fillStyle = "blue";
ctx.fillRect(20, 20, 150, 100);
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-shadowblur-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`.


CanvasRenderingContext2D.rotate() - Web API 接口参考

CanvasRenderingContext2D.rotate()
=================================

**`CanvasRenderingContext2D.rotate()`** 是 Canvas 2D API 在变换矩阵中增加旋转的方法。角度变量表示一个顺时针旋转角度并且用弧度表示。

语法
--
```

void ctx.rotate(angle);
```

![](/zh-CN/docs/Web/API/CanvasRenderingContext2D/rotate/canvas_grid_rotate.png)

### 参数

`angle`

顺时针旋转的弧度。如果你想通过角度值计算，可以使用公式： `degree * Math.PI / 180` 。

旋转中心点一直是 canvas 的起始点。如果想改变中心点，我们可以通过 `translate()` 方法移动 canvas。

示例
--

### 旋转形状

这是一段使用 `rotate` 方法的简单的代码片段。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

// Point of transform origin
ctx.arc(0, 0, 5, 0, 2 \* Math.PI);
ctx.fillStyle = "blue";
ctx.fill();

// Non-rotated rectangle
ctx.fillStyle = "gray";
ctx.fillRect(100, 0, 80, 20);

// Rotated rectangle
ctx.rotate((45 \* Math.PI) / 180);
ctx.fillStyle = "red";
ctx.fillRect(100, 0, 80, 20);

// Reset transformation matrix to the identity matrix
ctx.setTransform(1, 0, 0, 1, 0, 0);
```

#### 结果

旋转中心是蓝色的。未旋转的矩形为灰色，而旋转后的矩形为红色。

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-rotate-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`


CanvasRenderingContext2D.imageSmoothingEnabled - Web API 接口参考

CanvasRenderingContext2D.imageSmoothingEnabled
==============================================

**`CanvasRenderingContext2D.imageSmoothingEnabled`** 是 Canvas 2D API 用来设置图片是否平滑的属性，true 表示图片平滑（默认值），false 表示图片不平滑。当我们获取 `imageSmoothingEnabled` 属性值时，它会返回最新设置的值。

以缩放画布为例，这个属性对像素为主的游戏很有用。默认的改变大小的算法会造成图片模糊并且破坏图片原有的像素。如果那样的话，设置属性值为 false。参见 CSS `image-rendering` 属性。

**备注：** 你可以使用`imageSmoothingQuality`属性来调整平滑质量。

语法
--
```

ctx.imageSmoothingEnabled = value;
```

### 选项

`value`

一个`Boolean` 类型的值，表示图片是否平滑。

示例
--

### 禁用图像平滑

本示例比较了三个图像。第一个图像以其自然大小绘制，第二个图像缩放为 3 倍并启用了图像平滑，而第三个图像缩放为 3 倍但禁用了图像平滑。

#### HTML

```html
<canvas id="canvas" width="460" height="210"></canvas>
```

#### JavaScript

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

const ctx = canvas.getContext("2d");
ctx.font = "16px sans-serif";
ctx.textAlign = "center";

const img = new Image();
img.src =
  "https://interactive-examples.mdn.mozilla.net/media/examples/star.png";
img.onload = () => {
  const w = img.width,
    h = img.height;

  ctx.fillText("Source", w \* 0.5, 20);
  ctx.drawImage(img, 0, 24, w, h);

  ctx.fillText("Smoothing = TRUE", w \* 2.5, 20);
  ctx.imageSmoothingEnabled = true;
  ctx.drawImage(img, w, 24, w \* 3, h \* 3);

  ctx.fillText("Smoothing = FALSE", w \* 5.5, 20);
  ctx.imageSmoothingEnabled = false;
  ctx.drawImage(img, w \* 4, 24, w \* 3, h \* 3);
};
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-imagesmoothingenabled-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `image-rendering`


CanvasRenderingContext2D.isPointInPath() - Web API 接口参考

CanvasRenderingContext2D.isPointInPath()
========================================

**`CanvasRenderingContext2D.isPointInPath()`** 是 Canvas 2D API 用于判断在当前路径中是否包含检测点的方法。

语法
--

```js
isPointInPath(x, y)
isPointInPath(x, y, fillRule)
isPointInPath(path, x, y)
isPointInPath(path, x, y, fillRule)
```

### 参数

x

检测点的 X 坐标

y

检测点的 Y 坐标

`fillRule`

 用来决定点在路径内还是在路径外的算法。
 允许的值：

`nonzero`

非零环绕规则，默认的规则。

`evenodd`

奇偶环绕原则。

`path`

`Path2D`应用的路径。

### 返回值

`Boolean`

一个 Boolean 值，当检测点包含在当前或指定的路径内，返回 true；否则返回 false。

示例
--

### 检查当前路径中的点

这是一段简单的代码片段，使用 `isPointInPath` 方法检查某点是否在当前的路径内。

#### HTML

```html
<canvas id="canvas"></canvas>
<p>In path: <code id="result">false</code></p>
```

#### JavaScript

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

ctx.rect(10, 10, 100, 100);
ctx.fill();
result.innerText = ctx.isPointInPath(30, 70);
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-ispointinpath-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`.


CanvasRenderingContext2D.strokeText() - Web API 接口参考

CanvasRenderingContext2D.strokeText()
=====================================

**`CanvasRenderingContext2D.strokeText()`** 是 Canvas 2D API 在给定的 *(x, y)* 位置绘制文本的方法。如果提供了表示最大值的第四个参数，文本将会缩放适应宽度。

参见 `CanvasRenderingContext2D.fillText()` 方法填充文本。

语法
--
```

void ctx.strokeText(text, x, y [, maxWidth]);
```

### 参数

`text`

使用当前 `font`，`textAlign`，`textBaseline`和`direction` 的值对文本进行渲染。

`x`

文本起始点的 x 轴坐标。

`y`

文本起始点的 y 轴坐标。

`maxWidth` 可选

需要绘制的最大宽度。如果指定了值，并且经过计算字符串的宽度比最大宽度还要宽，字体为了适应会使用一个水平缩小的字体（如果通过水平缩放当前的字体，可以进行有效的或者合理可读的处理）或者小号的字体。

示例
--

### 绘制文字轮廓

这是一个使用 `strokeText` 方法的简单的代码片段。

#### HTML

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

#### JavaScript

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

ctx.font = "50px serif";
ctx.strokeText("Hello world", 50, 90);
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-stroketext-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.fillText()`


CanvasRenderingContext2D.setTransform() - Web API 接口参考

CanvasRenderingContext2D.setTransform()
=======================================

**`CanvasRenderingContext2D.setTransform()`** 是 Canvas 2D API 使用单位矩阵重新设置（覆盖）当前的变换并调用变换的方法，此变换由方法的变量进行描述。

参见 `transform()` 方法，这个方法不会覆盖当前的变换矩阵，会多次叠加变换。

语法
--
```

void ctx.setTransform(a, b, c, d, e, f);
```

变换矩阵的描述：

[

a

c

e

b

d

f

0

0

1

]

\left[ \begin{array}{ccc} a & c & e \ b & d & f \ 0 & 0 & 1 \end{array} \right]

### 参数

`a (m11)`

水平缩放。

*`b (m12)`*

垂直倾斜。

`c (m21)`

水平倾斜。

`d (m22)`

垂直缩放。

`e (dx)`

水平移动。

`f (dy)`

垂直移动。

较新的类型由单个参数矩阵组成，该参数表示要设置的 2D 转换矩阵（从技术上讲，是 DOMMatrixInit 对象；任何对象只要包含上述作为属性的组件，就可以执行操作）。

示例
--

### 倾斜形状

这是一段使用 `setTransform` 方法的简单的代码片段。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

ctx.setTransform(1, 0.2, 0.8, 1, 0, 0);
ctx.fillRect(0, 0, 100, 100);
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-settransform-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.transform()`


CanvasRenderingContext2D.beginPath() - Web API 接口参考

CanvasRenderingContext2D.beginPath()
====================================

**`CanvasRenderingContext2D.beginPath()`** 是 Canvas 2D API 通过清空子路径列表开始一个新路径的方法。当你想创建一个新的路径时，调用此方法。

语法
--
```

void ctx.beginPath();
```

示例
--

### 创建不同的路径

这是一段受用 `beginPath` 方法的简单的代码片段。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

// First path
ctx.beginPath();
ctx.strokeStyle = "blue";
ctx.moveTo(20, 20);
ctx.lineTo(200, 20);
ctx.stroke();

// Second path
ctx.beginPath();
ctx.strokeStyle = "green";
ctx.moveTo(20, 20);
ctx.lineTo(120, 120);
ctx.stroke();
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-beginpath-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.closePath()`


CanvasRenderingContext2D.quadraticCurveTo() - Web API 接口参考

CanvasRenderingContext2D.quadraticCurveTo()
===========================================

**`CanvasRenderingContext2D.quadraticCurveTo()`** 是 Canvas 2D API 新增二次贝塞尔曲线路径的方法。它需要 2 个点。第一个点是控制点，第二个点是终点。起始点是当前路径最新的点，当创建二次贝赛尔曲线之前，可以使用 `moveTo()` 方法进行改变。

语法
--
```

void ctx.quadraticCurveTo(cpx, cpy, x, y);
```

### 参数

`cpx`

控制点的 x 轴坐标。

`cpy`

控制点的 y 轴坐标。

`x`

终点的 x 轴坐标。

`y`

终点的 y 轴坐标。

示例
--

### `quadraticCurveTo` 如何工作

这是一段绘制二次贝赛尔曲线的简单的代码片段。控制点是红色，起点和终点是蓝色。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

// Quadratic Bézier curve
ctx.beginPath();
ctx.moveTo(50, 20);
ctx.quadraticCurveTo(230, 30, 50, 100);
ctx.stroke();

// Start and end points
ctx.fillStyle = "blue";
ctx.beginPath();
ctx.arc(50, 20, 5, 0, 2 \* Math.PI); // Start point
ctx.arc(50, 100, 5, 0, 2 \* Math.PI); // End point
ctx.fill();

// Control point
ctx.fillStyle = "red";
ctx.beginPath();
ctx.arc(230, 30, 5, 0, 2 \* Math.PI);
ctx.fill();
```

#### 结果

### 简单的二次曲线

此示例使用`quadraticCurveTo()`绘制了简单的二次 Bézier 曲线。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

曲线从`moveTo()`指定的点开始：(20, 110)。控制点位于 (230, 150)。曲线在 (250, 20) 处结束。

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

ctx.beginPath();
ctx.moveTo(20, 110);
ctx.quadraticCurveTo(230, 150, 250, 20);
ctx.stroke();
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-quadraticcurveto-dev |

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

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

* 接口定义，`CanvasRenderingContext2D`
* WikiPedia article on Bézier curves.


CanvasRenderingContext2D.fillRect() - Web API 接口参考

CanvasRenderingContext2D.fillRect()
===================================

**`CanvasRenderingContext2D.fillRect()`** 是 Canvas 2D API 绘制填充矩形的方法。当前渲染上下文中的`fillStyle` 属性决定了对这个矩形对的填充样式。

这个方法是直接在画布上绘制填充，并不修改当前路径，所以在这个方法后面调用 `fill()` 或者`stroke()`方法并不会对这个方法有什么影响。

语法
--
```

void ctx.fillRect(x, y, width, height);
```

`fillRect()`方法绘制一个填充了内容的矩形，这个矩形的开始点（左上点）在`(x, y)` ，它的宽度和高度分别由`width` 和 `height` 确定，填充样式由当前的`fillStyle` 决定。

### 参数

`x`

矩形起始点的 x 轴坐标。

`y`

矩形起始点的 y 轴坐标。

`width`

矩形的宽度。

`height`

矩形的高度。

示例
--

### 一个填充矩形的例子

这个例子使用`fillRect()`方法绘制了一个用绿色填充的矩形。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

下面绘制的矩形左上顶点在 (20, 10)，宽高分别是 150 和 100 像素。

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(20, 10, 150, 100);
```

#### 结果

### 填充整个画布

下面这个代码片段使用本方法填充了整个画布。这样做通常的目的是在开始绘制其他内容前设置一个背景。为了达到这样的效果，需要让填充的范围和画布的范围相同，需要访问`<canvas>`元素的`width` 和 `height` 属性。

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
ctx.fillRect(0, 0, canvas.width, canvas.height);
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-fillrect-dev |

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

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

参见
--

* 接口定义，`CanvasRenderingContext2D`
* `CanvasRenderingContext2D.fillStyle`
* `CanvasRenderingContext2D.clearRect()`
* `CanvasRenderingContext2D.strokeRect()`


CanvasRenderingContext2D.getLineDash() - Web API 接口参考

CanvasRenderingContext2D.getLineDash()
======================================

**`CanvasRenderingContext2D.getLineDash()`** 是 Canvas 2D API 获取当前线段样式的方法。

语法
--
```

ctx.getLineDash();
```

### 返回值

一个 `Array`数组。一组描述交替绘制线段和间距（坐标空间单位）长度的数字。如果数组元素的数量是奇数，数组元素会被复制并重复。例如，设置线段为 `[5, 15, 25]` 将会得到以下返回值 `[5, 15, 25, 5, 15, 25]`。

示例
--

### 获取当前的划线设置

这是一段使用 `getLineDash` 方法的简单的代码片段。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

ctx.setLineDash([10, 20]);
console.log(ctx.getLineDash()); // [10, 20]

// Draw a dashed line
ctx.beginPath();
ctx.moveTo(0, 50);
ctx.lineTo(300, 50);
ctx.stroke();
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-getlinedash-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.setLineDash()`
* `CanvasRenderingContext2D.lineDashOffset`


CanvasRenderingContext2D.transform() - Web API 接口参考

CanvasRenderingContext2D.transform()
====================================

**`CanvasRenderingContext2D.transform()`** 是 Canvas 2D API 使用矩阵多次叠加当前变换的方法，矩阵由方法的参数进行描述。你可以缩放、旋转、移动和倾斜上下文。

参见 `setTransform()` 方法，这个方法使用单位矩阵重新设置当前的变换并且会调用 `transform()`。

语法
--
```

void ctx.transform(a, b, c, d, e, f);
```

变换矩阵的描述：

[

a

c

e

b

d

f

0

0

1

]

\left[ \begin{array}{ccc} a & c & e \ b & d & f \ 0 & 0 & 1 \end{array} \right]

### 参数

`a (m11)`

水平缩放。

*`b (m12)`*

垂直倾斜。

`c (m21)`

水平倾斜。

`d (m22)`

垂直缩放。

`e (dx)`

水平移动。

`f (dy)`

垂直移动。

示例
--

### 倾斜形状

这是一段使用 `transform` 方法的简单的代码片段。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

ctx.transform(1, 0.2, 0.8, 1, 0, 0);
ctx.fillRect(0, 0, 100, 100);
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-transform-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.setTransform()`


CanvasRenderingContext2D.scrollPathIntoView() - Web API 接口参考

CanvasRenderingContext2D.scrollPathIntoView()
=============================================

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

**`CanvasRenderingContext2D.scrollPathIntoView()`** 是 Canvas 2D API 将当前或给定的路径滚动到窗口的方法。类似于 `Element.scrollIntoView()`。

语法
--
```

void ctx.scrollPathIntoView();
void ctx.scrollPathIntoView(path);
```

### 参数

`path`

使用的`Path2D` 路径。

示例
--

### 使用 scrollPathIntoView 方法

这是一段使用 `scrollPathIntoView` 方法的简单的代码片段。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

ctx.beginPath();
ctx.fillRect(10, 10, 30, 30);
ctx.scrollPathIntoView();
```

#### 可编辑示例

修改下面的代码并在线查看 canvas 的变化：
```

<canvas id="canvas" width="400" height="200" class="playable-canvas">
  <input id="button" type="range" min="1" max="12" />
</canvas>
<div class="playable-buttons">
  <input id="edit" type="button" value="Edit" />
  <input id="reset" type="button" value="Reset" />
</div>
<textarea id="code" class="playable-code">
ctx.beginPath();
ctx.rect(10, 10, 30, 30);
ctx.fill();
if (ctx.scrollPathIntoView) {
  ctx.scrollPathIntoView();
} else {
  ctx.fillText("Your browser does not support 'scrollPathIntoView()'.", 0, 150);
}
</textarea>
```

```
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const textarea = document.getElementById("code");
const reset = document.getElementById("reset");
const edit = document.getElementById("edit");
const code = textarea.value;

function drawCanvas() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  eval(textarea.value);
}

reset.addEventListener("click", () => {
  textarea.value = code;
  drawCanvas();
});

edit.addEventListener("click", () => {
  textarea.focus();
});

textarea.addEventListener("input", drawCanvas);
window.addEventListener("load", drawCanvas);
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-scrollpathintoview-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`.
* `Element.scrollIntoView()`


CanvasRenderingContext2D.lineCap - Web API 接口参考

CanvasRenderingContext2D.lineCap
================================

**`CanvasRenderingContext2D.lineCap`** 是 Canvas 2D API 指定如何绘制每一条线段末端的属性。有 3 个可能的值，分别是：`butt`, `round` and `square`。默认值是 `butt`。

参见 Canvas Tutorial 中的 Applying styles and color 章节。

语法
--
```

ctx.lineCap = "butt";
ctx.lineCap = "round";
ctx.lineCap = "square";
```

### 选项

`butt`

线段末端以方形结束。

`round`

线段末端以圆形结束。

`square`

线段末端以方形结束，但是增加了一个宽度和线段相同，高度是线段厚度一半的矩形区域。

示例
--

### 改变线段末端的形状

这是一段简单的代码片段，使用 `lineCap` 属性绘制以圆形结尾的线段。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

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

ctx.beginPath();
ctx.moveTo(20, 20);
ctx.lineWidth = 15;
ctx.lineCap = "round";
ctx.lineTo(100, 100);
ctx.stroke();
```

#### 结果

### 线条末端对比

在这个例子中绘制了 3 条线段，每条线段都设置了不同的 `lineCap` 属性值。通过 2 条导航线能够精确地看到 3 条已绘制线段之间的不同。每条线段的顶端和末端都能在导航线上准确的反映出来。

左侧的线段使用了默认值 `butt` ，和导航线是完全平齐的。第二条线段使用了 `round` 选项，在线段末端增加了一个半径为线短宽度一半的半圆。右侧的线段使用了 `square` 选项，增加了一个宽度和线段相同，高度是线段厚度一半的矩形区域。
```

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

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

// Draw guides
ctx.strokeStyle = "#09f";
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(140, 10);
ctx.moveTo(10, 140);
ctx.lineTo(140, 140);
ctx.stroke();

// Draw lines
ctx.strokeStyle = "black";
["butt", "round", "square"].forEach((lineCap, i) => {
  ctx.lineWidth = 15;
  ctx.lineCap = lineCap;
  ctx.beginPath();
  ctx.moveTo(25 + i \* 50, 10);
  ctx.lineTo(25 + i \* 50, 140);
  ctx.stroke();
});
```

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

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-linecap-dev |

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

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

参见
--

* 接口定义， `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.lineWidth`
* `CanvasRenderingContext2D.lineJoin`


CanvasRenderingContext2D.getTransform() - Web API 接口参考

CanvasRenderingContext2D.getTransform()
=======================================

**`CanvasRenderingContext2D.getTransform()`** 方法获取当前被应用到上下文的转换矩阵

语法
--
```

let storedTransform = ctx.getTransform();
```

### 参数

无。

### 返回值

一个 `DOMMatrix` 对象

转换矩阵被这样描述：

[

a

c

e

b

d

f

0

0

1

]

\left[ \begin{array}{ccc} a & c & e \ b & d & f \ 0 & 0 & 1 \end{array} \right]

**备注：** 返回的对象不是实时的，所以更新它不会影响当前的转换矩阵，同时更新当前的转换矩阵不会影响已经返回的 `DOMMatrix`.

示例
--

在以下例子，我们有两个 `<canvas>` 元素。我们使用 `CanvasRenderingContext2D.setTransform()` 设置一个转换到第一个画布，并在上面画一个矩形，然后通过 `getTransform()` 获取矩阵。

然后我们将获取到的矩阵作为 `DOMMatrix` 参数传给 `setTransform()` 设置到第二个画布，并在上面画一个圆。

#### HTML

```html
<canvas width="240"></canvas> <canvas width="240"></canvas>
```

#### CSS

```css
canvas {
  border: 1px solid black;
}
```

#### JavaScript

```js
const canvases = document.querySelectorAll("canvas");
const ctx1 = canvases[0].getContext("2d");
const ctx2 = canvases[1].getContext("2d");

ctx1.setTransform(1, 0.2, 0.8, 1, 0, 0);
ctx1.fillRect(25, 25, 50, 50);

let storedTransform = ctx1.getTransform();
console.log(storedTransform);

ctx2.setTransform(storedTransform);
ctx2.beginPath();
ctx2.arc(50, 50, 50, 0, 2 \* Math.PI);
ctx2.fill();
```

#### 结果

规范
--

| Specification |
| --- |
| HTML Standard # dom-context-2d-gettransform-dev |

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

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

参见
--

* The interface defining this method: `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.transform()`