recursal/MDN huggingface dataset:
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
====================

只读属性 **`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
=====================

`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()
====================

**`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
=================

`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()
=============

**`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()
======================================

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()
================================

**`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
=====================================

**`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()
============================================

**`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.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()
===============================================

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()
==================================

**`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()
=================================

**`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
==================================

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

**`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()
==================================

**`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()
==========================================

**`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 像素控制