URLSearchParams: URLSearchParams() コンストラクター - Web API

URLSearchParams: URLSearchParams() コンストラクター
===========================================

**`URLSearchParams()`** コンストラクターは、新しい `URLSearchParams` オブジェクトを作成して返します。

**注:** この機能は Web Worker 内で利用可能です

構文
--

```js
new URLSearchParams()
new URLSearchParams(options)
```

### 引数

`options` 省略可

以下のいずれか。

* 文字列。先頭の文字 `'?'` は無視され、`application/x-www-form-urlencoded` 形式としてパースされます。
* 名前を表す文字列と値を表す文字列のペアのリテラル列、もしくはそのような文字列のペアの列を生成するイテレーターを持つ任意のオブジェクト（たとえば `FormData` のオブジェクト）。なお、`File` のエントリーは（`application/x-www-form-urlencoded` 形式で期待される）ファイル名ではなく `[object File]` としてシリアライズされます。
* 文字列のキーと文字列の値からなるレコード。なお、ネストには対応していません。

### 返値

`URLSearchParams` のインスタンスです。

例
-

以下の例では、様々な入力から `URLSearchParams` オブジェクトを生成する方法を示します。

```js
// url.search からパラメーターを取得し、コンストラクターに渡す
const url = new URL("https://example.com?foo=1&bar=2");
const params1 = new URLSearchParams(url.search);

// URL オブジェクトから直接 URLSearchParams オブジェクトを取得する
const params1a = url.searchParams;

// 文字列リテラルを渡す
const params2 = new URLSearchParams("foo=1&bar=2");
const params2a = new URLSearchParams("?foo=1&bar=2");

// ペアの列を渡す
const params3 = new URLSearchParams([
  ["foo", "1"],
  ["bar", "2"],
]);

// レコードを渡す
const params4 = new URLSearchParams({ foo: "1", bar: "2" });
```

この例では、検索パラメーターを持つ既存の URL から、検索パラメーターを表すオブジェクトを用い、新しい URL を構築する方法を示します。

```js
const url = new URL("https://example.com/?a=hello&b=world");

console.log(url.href);
// https://example.com/?a=hello&b=world

console.log(url.origin);
// https://example.com

const add_params = {
  c: "a",
  d: new String(2),
  e: false.toString(),
};

const new_params = new URLSearchParams([
  ...Array.from(url.searchParams.entries()), // [["a","hello"],["b","world"]]
  ...Object.entries(add_params), // [["c","a"],["d","2"],["e","false"]]
]).toString();
console.log(new_params);
// a=hello&b=world&c=a&d=2&e=false

const new_url = new URL(`${url.origin}${url.pathname}?${new\_params}`);

console.log(new_url.href);
// https://example.com/?a=hello&b=world&c=a&d=2&e=false

// (URL, Record<string, string>) を受け取る関数の形式で
const addSearchParams = (url, params = {}) =>
  new URL(
    `${url.origin}${url.pathname}?${new URLSearchParams([
 ...Array.from(url.searchParams.entries()),
 ...Object.entries(params),
 ])}`,
  );
```

仕様書
---

| Specification |
| --- |
| URL Standard # dom-urlsearchparams-urlsearchparams |

ブラウザーの互換性
---------

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


URLSearchParams: delete() メソッド - Web API

URLSearchParams: delete() メソッド
==============================

**`delete()`** は `URLSearchParams` インターフェイスのメソッドで、すべての検索パラメーターのリストから、指定された検索パラメーターとそれに関連するすべての値を削除します。

 パラメーター名とオプションの値は、パラメーターの照合に使用されます。
 パラメーター名のみが指定された場合、その名前に一致するすべての検索パラメーターが、関連する値とともに削除されます。
 パラメーター名と値の両方が指定された場合、パラメーター名と値の両方に一致するすべての検索パラメーターが削除されます。

**注:** この機能は Web Worker 内で利用可能です

構文
--

```js
delete(name)
delete(name, value)
```

### 引数

`name`

削除するパラメーターの名前。

`value` 省略可

パラメーターを削除するために、指定された名前とともにパラメーターが一致しなければならない値。

### 返値

なし (`undefined`)。

例
-

### 指定された名前のすべてのパラメーターを削除

この例では、特定の名前を持つクエリーパラメーター（および値）をすべて削除する方法を示します。
```

<pre id="log"></pre>
```

```
const logElement = document.getElementById("log");
function log(text) {
  logElement.innerText += `${text}\n`;
}
```

```js
const url = new URL("https://example.com?foo=1&bar=2&foo=3");
const params = new URLSearchParams(url.search);
log(`Query string (before):\t ${params}`);
params.delete("foo");
log(`Query string (after):\t ${params}`);
```

以下のログは、`foo` という名前を持つパラメータがすべて削除されていることを示しています。

### 指定した名前と値を持つパラメーターの削除

この例では、特定の名前と値に一致するクエリーパラメーターを削除する方法を示します。
```

<pre id="log"></pre>
```

```
const logElement = document.getElementById("log");
function log(text) {
  logElement.innerText += `${text}\n`;
}
```

```js
const url = new URL("https://example.com?foo=1&bar=2&foo=3&foo=1");
const params = new URLSearchParams(url.search);
log(`Query string (before):\t ${params}`);
params.delete("foo", "1");
log(`Query string (after):\t ${params}`);
```

パラメーターの `name` と `value` の両方が一致するパラメーターがすべて削除されるはずです（上記のように、同じ名前と値を持つパラメーターを 2 つ指定する理由はありません）。

 ブラウザーが `value` オプションに対応している場合、"after" の文字列は `bar=2&foo=3` となります。
 そうでない場合、結果は前の例 (`bar=2`) と同じになります。

仕様書
---

| Specification |
| --- |
| URL Standard # dom-urlsearchparams-delete |

ブラウザーの互換性
---------

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

関連情報
----

* `URLSearchParams` のポリフィル (`core-js`)


URLSearchParams: entries() メソッド - Web API

URLSearchParams: entries() メソッド
===============================

**`entries()`** は `URLSearchParams` インターフェイスのメソッドは、このオブジェクトに含まれるすべてのキー/値のペアを反復処理できる`イテレーター`を返します。それぞれのペアのキーと値は文字列です。

**注:** この機能は Web Worker 内で利用可能です

構文
--

```js
entries()
```

### 引数

なし。

### 返値

`イテレーター`を返します。

例
-

```js
// テスト用の URLSearchParams オブジェクトの作成
const searchParams = new URLSearchParams("key1=value1&key2=value2");

// キー/値のペアの表示
for (const [key, value] of searchParams.entries()) {
  console.log(`${key}, ${value}`);
}
```

結果は次のとおりです。
```

key1, value1
key2, value2
```

仕様書
---

| Specification |
| --- |
| URL Standard # dom-urlsearchparams-urlsearchparams |

ブラウザーの互換性
---------

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

関連情報
----

* `URL` インターフェイス。


URLSearchParams: has() メソッド - Web API

URLSearchParams: has() メソッド
===========================

**`has()`** は `URLSearchParams` インターフェイスのメソッドは、指定された名前のパラメーターが存在するかどうかを示す論理値を返します。

 パラメーター名とオプションの値は、パラメーターの照合に使用されます。
 パラメーター名のみが指定された場合、このメソッドはクエリー文字列内のいずれかのパラメーターがその名前と一致した場合に `true` を返し、それ以外の場合は `false` を返します。
 パラメーター名と値の両方が指定された場合、あるパラメーターの名前と値の両方が一致した場合に `true` を返します。

**注:** この機能は Web Worker 内で利用可能です

構文
--

```js
has(name)
has(name, value)
```

### 引数

`name`

照合するパラメーターの名前です。

`value`

パラメーターの値で、指定された名前と一緒に照合されます。

### 返値

論理値です。

例
-

### 指定された名前のパラメーターをチェック

この例では、クエリー文字列に特定の名前のパラメーターがあるかどうかをチェックする方法を示します。
```

<pre id="log"></pre>
```

```
const logElement = document.getElementById("log");
function log(text) {
  logElement.innerText += `${text}\n`;
}
```

```js
const url = new URL("https://example.com?foo=1&bar=2&foo=3");
const params = new URLSearchParams(url.search);

// has() はそのパラメーターがクエリー文字列にある場合に true を返す
log(`bar?:\t${params.has("bar")}`);
log(`bark?:\t${params.has("bark")}`);
log(`foo?:\t${params.has("foo")}`);
```

以下のログは、パラメーター `bar`、`bark`、`foo` がクエリー文字列内に存在するかどうかを示しています。

### 指定された名前と値を持つパラメーターをチェック

この例では、クエリー文字列に特定の名前と値の両方が一致するパラメーターがあるかどうかをチェックする方法を示します。
```

<pre id="log"></pre>
```

```
const logElement = document.getElementById("log");
function log(text) {
  logElement.innerText += `${text}\n`;
}
```

```js
const url = new URL("https://example.com?foo=1&bar=2&foo=3");
const params = new URLSearchParams(url.search);

// has() は、一致する名前と値を持つパラメーターがクエリー文字列内にある場合に true を返します。
log(`bar=1?:\t${params.has("bar", "1")}`);
log(`bar=2?:\t${params.has("bar", "2")}`);
log(`foo=4?:\t${params.has("foo", "4")}`);
```

パラメーター名が `bar` で値が `2` のもののみが一致するので、上記の 2 番目の値のみが `true` になるはずです。

ブラウザーが `value` オプションに対応していない場合、このメソッドは名前に一致し、結果はすべて `true` になるはずです。

仕様書
---

| Specification |
| --- |
| URL Standard # dom-urlsearchparams-has |

ブラウザーの互換性
---------

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

関連情報
----

* `URLSearchParams` のポリフィル (`core-js`)


URLSearchParams: sort() メソッド - Web API

URLSearchParams: sort() メソッド
============================

**`URLSearchParams.sort()`** メソッドは、このオブジェクトに含まれるすべてのキー/値のペアをその場でソートし、`undefined` を返します。 ソート順は、キーの Unicode コードポイントに従います。 このメソッドは、安定したソートアルゴリズムを使用します（つまり、等しいキーを持つキー/値のペア間の相対的な順序が保持されます）。

**注:** この機能は Web Worker 内で利用可能です

構文
--

```js
sort()
```

### 引数

なし。

### 返値

なし (`undefined`)。

例
-

```js
// テスト用の URLSearchParams オブジェクトの作成
const searchParams = new URLSearchParams("c=4&a=2&b=3&a=1");

// キー/値のペアのソート
searchParams.sort();

// ソートされたクエリー文字列の表示
console.log(searchParams.toString());
```

結果は次のとおりです。
```

a=2&a=1&b=3&c=4
```

仕様書
---

| Specification |
| --- |
| URL Standard # dom-urlsearchparams-sort |

ブラウザーの互換性
---------

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


URLSearchParams: get() メソッド - Web API

URLSearchParams: get() メソッド
===========================

**`get()`** は `URLSearchParams` インターフェースのメソッドで、指定された検索パラメーターに関連付けられた最初の値を返します。

**注:** この機能は Web Worker 内で利用可能です

構文
--

```js
get(name)
```

### 引数

`name`

返すパラメーターの名前。

### 返値

指定された検索パラメーターが見つかった場合は文字列です。それ以外の場合は **`null`** です。

例
-

ページの URL が `https://example.com/?name=Jonathan&age=18` の場合、次のように 'name' および 'age' のパラメーターを解釈できます。

```js
let params = new URLSearchParams(document.location.search);
let name = params.get("name"); // 文字列 "Jonathan" です
let age = parseInt(params.get("age"), 10); // 数値 18 です
```

クエリー文字列に存在しないパラメーターを要求すると、**`null`** が返されます。

```js
let address = params.get("address"); // null
```

仕様書
---

| Specification |
| --- |
| URL Standard # dom-urlsearchparams-get |

ブラウザーの互換性
---------

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


CharacterData: remove() メソッド - Web API

CharacterData: remove() メソッド
============================

**`remove()`** は `CharacterData` インターフェイスのメソッドで、このノードに含まれるテキストを削除します。

構文
--

```js
remove()
```

### 引数

なし。

例
-

### `remove()` の使用

```html
<span>結果: </span>A long string.
```

```js
const span = document.querySelector("span");
const textnode = span.nextSibling;

textnode.remove(); // Removes the text
```

仕様書
---

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

ブラウザーの互換性
---------

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

関連情報
----

* `Element.remove()`
* `CharacterData.deleteData()`


CharacterData: nextElementSibling プロパティ - Web API

CharacterData: nextElementSibling プロパティ
=======================================

**`nextElementSibling`** は `CharacterData` インターフェイスの読み取り専用プロパティで、親の子リストの中で、現在のノードの一つ後の `Element` を返します。指定された要素がリストの最後のものであれば `null` を返します。

値
-

`Element` オブジェクト、または兄弟ノードが見つらなければ `null` です。

例
-

```html
TEXT
<div id="div-01">これは div-01 です</div>
TEXT2
<div id="div-02">これは div-02 です</div>
<pre>こちらは結果領域です</pre>
```

```js
// 最初は、ノードに Text ノード `TEXT` を設定します
let node = document.getElementById("div-01").previousSibling;

let result = "TEXT の次の兄弟要素:\n";

while (node) {
  result += `${node.nodeName}\n`;
  node = node.nextElementSibling; // 最初のノードが CharacterData で、その他は Element オブジェクトです
}

document.querySelector("pre").textContent = result;
```

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-nondocumenttypechildnode-nextelementsibling② |

ブラウザーの互換性
---------

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

関連情報
----

* `CharacterData.previousElementSibling`


CharacterData: appendData() メソッド - Web API

CharacterData: appendData() メソッド
================================

**`appendData()`** は `CharacterData` インターフェイスのメソッドで、指定されたデータをこのノードの現在のデータの末尾に追加します。

構文
--

```js
appendData(data)
```

### 引数

`data`

現在のノードに追加するデータです。

### 返値

なし。

例
-

```html
<span>結果: </span>テキスト
```

```js
const span = document.querySelector("span");
const textnode = span.nextSibling;

textnode.appendData(" - 追加テキスト");
```

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-characterdata-appenddata |

ブラウザーの互換性
---------

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

関連情報
----

* `CharacterData.deleteData()`, `CharacterData.insertData()`, `CharacterData.replaceData()`
* `CharacterData.data`


CharacterData: after() メソッド - Web API

CharacterData: after() メソッド
===========================

**`after()`** は `CharacterData` インターフェイスのメソッドで、一連の `Node` オブジェクトまたは文字列を、このオブジェクトの親ノードの子リスト内の、このオブジェクト自身の直後に挿入します。

文字列は `Text` ノードとして挿入されます。文字列は `Text()` コンストラクターの引数として挿入されます。

構文
--

```js
after(...nodes)
```

### 引数

`nodes`

挿入する一連の `Node` または文字列です。

### 例外

`HierarchyRequestError` `DOMException`

階層内の指定された位置に新しいノードを挿入できない場合，つまり以下の条件のいずれかに該当する場合に発生します。

* 追加されたノードの 1 つを挿入すると循環参照なる場合、つまり、そのノードの 1 つがこの `CharacterData` ノードの祖先である場合です。
* 追加されたノードのいずれかが `DocumentFragment`, `DocumentType`, `Element`, `CharacterData` のいずれでもない場合。
* この `CharacterData` ノードが実際には `Text` ノードであり、その親が `Document` である場合。
* この `CharacterData` ノードの親が `Document` で、挿入するノードの一つが `DocumentFragment` であり、その中に 1 つ以上の `Element` がある場合、または `Text` 子を持つ場合。

例
-

`after()` メソッドを使うと、新しいノードをこの `CharacterData` ノードの後に挿入することができます。

```js
const h1TextNode = document.querySelector("h1").firstChild;
h1TextNode.after(" #h1");

h1TextNode.parentElement.childNodes;
// NodeList [#text "CharacterData.after()", #text " #h1"]

h1TextNode.data;
// "CharacterData.after()"
```

**メモ:** 現在のノードにテキストを追加したい場合は、 `appendData()` メソッドを使用すると現在のノードにデータを追加することができます。

仕様書
---

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

ブラウザーの互換性
---------

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

関連情報
----

* `CharacterData.appendData()`
* `CharacterData.before()`
* `Element.append()`
* `Node.appendChild()`
* `Element.insertAdjacentElement()`


CharacterData: previousElementSibling プロパティ - Web API

CharacterData: previousElementSibling プロパティ
===========================================

**`previousElementSibling`** は `CharacterData` インターフェイスの読み取り専用プロパティで、親の子リストの中で、現在のノードの一つ前の `Element` を返します。存在しなければ `null` を返します。

値
-

`Element` オブジェクト、または兄弟ノードが見つらなければ `null` です。

例
-

```html
<div id="div-01">これは div-01 です</div>
TEXT
<div id="div-02">これは div-02 です</div>
SOME TEXT
<div id="div-03">これは div-03 です</div>
<pre>結果</pre>
```

```js
// 最初に node に Text ノード `SOME TEXT` を設定
let node = document.getElementById("div-02").nextSibling;

let result = "SOME TEXT の前の兄弟要素:\n";

while (node) {
  result += `${node.nodeName}\n`;
  node = node.previousElementSibling;
}

document.querySelector("pre").textContent = result;
```

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-nondocumenttypechildnode-previouselementsibling② |

ブラウザーの互換性
---------

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

関連情報
----

* `CharacterData.nextElementSibling`


CharacterData: deleteData() メソッド - Web API

CharacterData: deleteData() メソッド
================================

**`deleteData()`** は `CharacterData` インターフェイスのメソッドで、この `CharacterData` ノードからすべてまたは一部のデータを削除します。

構文
--

```js
characterData.deleteData(offset, count)
```

### 引数

`offset`

 削除するデータの先頭をバイト数で表す数です。
 `0` は文字列の最初の文字を表します。

`count`

削除するバイト数です。

### 返値

なし。

例外
--

`IndexSizeError` `DOMException`

`offset` が中のデータの長さよりも長い場合に発生します。

例
-

```html
<span>Result: </span>A long string.
```

```js
const span = document.querySelector("span");
const textnode = span.nextSibling;

textnode.deleteData(1, 5);
```

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-characterdata-deletedata |

ブラウザーの互換性
---------

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

関連情報
----

* `CharacterData.appendData()`, `CharacterData.insertData()`, `CharacterData.replaceData()`
* `CharacterData.data`


CharacterData: data プロパティ - Web API

CharacterData: data プロパティ
=========================

**`data`** は `CharacterData` インターフェイスのプロパティで、現在のオブジェクトのデータの値を表します。

値
-

この `CharacterData` ノードに含まれる文字情報による文字列です。

例
-

**メモ:** `CharacterData` は抽象インターフェイスです。
 以下の例はこれを実装した 2 つの具象インターフェイス、 `Text` と `Comment` を使用しています。

### data を使用したコメントの読み取り

```html
<!-- これは HTML のコメントです -->
<output id="result"></output>
```

```js
const comment = document.body.childNodes[1];
const output = document.getElementById("result");

output.value = comment.data;
```

### data を使用してテキストノードの内容を設定

```html
<span>結果: </span>未設定
```

```js
const span = document.querySelector("span");
const textnode = span.nextSibling;

textnode.data = "このテキストは 'textnode.data' を使用して設定されました。";
```

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-characterdata-data |

ブラウザーの互換性
---------

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

関連情報
----

* `CharacterData.length`: この `CharacterData` ノードに含まれるデータの長さを返す


CharacterData: substringData() メソッド - Web API

CharacterData: substringData() メソッド
===================================

**`substringData()`** は `CharacterData` インターフェイスのメソッドで、既存のデータの一部を、指定した位置から始まり、指定した文字数分のデータを返します。

構文
--

```js
  domString = characterData.substringData(offset, count)
```

### 引数

`offset`

 返す部分文字列に含める最初の文字の位置です。
 `0` は文字列の最初の文字を表します。

`count`

返す文字数です。

### 返値

文字列型で部分文字列を返します。

例外
--

`IndexSizeError` `DOMException`

`offset` + `count` が内容のデータの長さよりも大きかった場合に発生します。

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-characterdata-substringdata |

ブラウザーの互換性
---------

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


CharacterData: insertData() メソッド - Web API

CharacterData: insertData() メソッド
================================

**`insertData()`** は `CharacterData` インターフェイスのメソッドで、指定されたデータをこの `CharacterData` ノードの現在のデータの、既存のデータの先頭からのオフセットの位置に挿入します。
 指定されたデータは、既存のデータに継ぎ足されます。

構文
--

```js
characterData.insertData(offset, data)
```

### 引数

`offset`

 提供されたデータを挿入する文字数単位での位置です。
 `0` は文字列の最初の文字を表します。

`data`

挿入するデータです。

### 返値

なし。

例外
--

`IndexSizeError` `DOMException`

offset が負の値であるか、入っているデータの長さよりも大きい場合に発生します。

例
-

```html
<span>結果: </span>A string.
```

```js
const span = document.querySelector("span");
const textnode = span.nextSibling;

textnode.insertData(2, "long ");
```

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-characterdata-insertdata |

ブラウザーの互換性
---------

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

関連情報
----

* `CharacterData.appendData()`, `CharacterData.deleteData()`, `CharacterData.replaceData()`
* `CharacterData.data`


CharacterData: replaceData() メソッド - Web API

CharacterData: replaceData() メソッド
=================================

**`replaceData()`** は `CharacterData` インターフェイスのメソッドで、この `CharacterData` ノードにある既存のテキストの特定の数の文字を取り除き、指定されたテキストの文字で置き換えます。

構文
--

```js
characterData.replaceData(offset, count, data)
```

### 引数

`offset`

 データの先頭から何文字目に挿入するかを指定します。
 `0` は文字列の先頭の文字を表します。

`count`

指定されたデータで置換する文字数。

`data`

挿入するデータです。

### 返値

なし。

例外
--

`IndexSizeError` `DOMException`

`offset` または `count` が負の値であるか、 `offset` が含まれるデータの長さよりも大きい場合に発生します。

例
-

```html
<span>Result: </span>A long string.
```

```js
const span = document.querySelector("span");
const textnode = span.nextSibling;

textnode.replaceData(2, 4, "replaced");
```

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-characterdata-replacedata |

ブラウザーの互換性
---------

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

関連情報
----

* `CharacterData.appendData()`
* `CharacterData.deleteData()`
* `CharacterData.insertData()`
* `CharacterData.data`


CharacterData: before() メソッド - Web API

CharacterData: before() メソッド
============================

**`before()`** は `CharacterData` インターフェイスのメソッドで、一連の `Node` オブジェクトまたは文字列を、この `CharacterData` の親ノードの子リストの中、この `CharacterData` ノードの直前に挿入します。

文字列は `Text` ノードとして挿入されます。文字列は `Text()` コンストラクターの引数として挿入されます。

構文
--

```js
before(...nodes)
```

### 引数

`nodes`

挿入する一連の `Node` または文字列です。

### 例外

`HierarchyRequestError` `DOMException`

階層内の指定された位置に新しいノードを挿入できない場合，つまり以下の条件のいずれかに該当する場合に発生します。

* 追加されたノードの 1 つを挿入すると循環参照なる場合、つまり、そのノードの 1 つがこの `CharacterData` ノードの祖先である場合です。
* 追加されたノードのいずれかが `DocumentFragment`, `DocumentType`, `Element`, `CharacterData` のいずれでもない場合。
* この `CharacterData` ノードが実際には `Text` ノードであり、その親が `Document` である場合。
* この `CharacterData` ノードの親が `Document` で、挿入するノードの一つが `DocumentFragment` であり、その中に 1 つ以上の `Element` がある場合、または `Text` 子を持つ場合。

例
-

`before()` メソッドを使うと、現在のノードのデータを変更せずに、新しいノードをこの `CharacterData` ノードの前に挿入することができます。

```js
const h1TextNode = document.querySelector("h1").firstChild;
h1TextNode.before("h1# ");

h1TextNode.parentElement.childNodes;
// NodeList [#text "h1# ", #text "CharacterData.before()"]

h1TextNode.data;
// "CharacterData.before()"
```

仕様書
---

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

ブラウザーの互換性
---------

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

関連情報
----

* `CharacterData.appendData()`
* `CharacterData.after()`
* `Element.append()`
* `Node.appendChild()`
* `Element.insertAdjacentElement()`


CharacterData: replaceWith() メソッド - Web API

CharacterData: replaceWith() メソッド
=================================

**`replaceWith()`** は `CharacterData` インターフェイスのメソッドで、親ノードの子リスト内にあるこのノードを、一連の `Node` オブジェクトまたは文字列で置き換えます。

文字列は `Text` ノードとして置き換えられます。この文字列は `Text()` コンストラクターに引数として渡されます。

構文
--

```js
replaceWith(nodes)
```

### 引数

`nodes` 省略可

カンマ区切りの `Node` オブジェクトまたは文字列のリストで、現在のノードを置き換えるものです。

**メモ:** 引数が渡されなかった場合、このメソッドはこのノードを DOM ツリーから取り除くだけの動作をします。

### 返値

なし (`undefined`)。

### 例外

`HierarchyRequestError` `DOMException`

ノードが階層内の指定された位置に挿入できない場合に発生します。

例
-

```html
<p id="myText">Some text</p>
```

```js
let text = document.getElementById("myText").firstChild;
let em = document.createElement("em");
em.textContent = "Italic text";

text.replaceWith(em); // `Some text` を `Italic text` で置き換える
```

仕様書
---

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

ブラウザーの互換性
---------

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

関連情報
----

* `CharacterData.replaceData()`


CharacterData: length プロパティ - Web API

CharacterData: length プロパティ
===========================

**`CharacterData.length`** プロパティは読み取り専用で、含まれているデータの文字数を正の整数で返します。

値
-

正の整数で、 `CharacterData.data` 文字列の長さを表します。

例
-

**メモ:** `CharacterData` は抽象インターフェイスです。
 以下の例ではそれを実装した具象インターフェイスの一つである `Text` を使用しています。

```html
<code>Text</code> ノード内の文字列の長さ: <output></output>
```

```js
const output = document.querySelector("output");
const textnode = new Text(
  "このテキストは 'textnode.data' を使用して設定されました。",
);

output.value = textnode.length;
```

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-characterdata-length |

ブラウザーの互換性
---------

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


FileList.length - Web API

FileList.length
===============

`FileList` の読み取り専用プロパティ **`length`** は、`FileList` に含まれるファイルの数を返します。

値
-

リスト中のファイルの数を表す数。

例
-

### 選択されたファイルの数を出力する

この例では、`FileList` の中のアイテム数を知るために `length` を使います。

#### HTML

```html
<input type="file" multiple />
<div class="output"></div>
```

#### JavaScript

```js
const fileInput = document.querySelector("input[type=file]");
const output = document.querySelector(".output");

fileInput.addEventListener("change", () => {
  const fileList = fileInput.files;
  output.textContent = `あなたは ${fileList.length} 個のファイルを選択しました`;
});
```

#### 結果

仕様書
---

| Specification |
| --- |
| File API # dfn-length |

ブラウザーの互換性
---------

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


FileList.item() - Web API

FileList.item()
===============

`FileList` API の **`item()`** メソッドは、ファイルリスト中の指定された位置のファイルを表す `File` オブジェクトを返します。

構文
--

```js
item(index)
```

### 引数

`index`

リストから取得するファイルの、0 始まりの添字です。

### 返値

要求されたファイルを表す `File` オブジェクトを返します。

例
-

### ファイル名を出力する

この例では、`item()` を用いて `FileList` の最初のアイテムを選択します。

#### HTML

```html
<input type="file" />
<div class="output"></div>
```

#### JavaScript

```js
const fileInput = document.querySelector("input[type=file]");
const output = document.querySelector(".output");

fileInput.addEventListener("change", () => {
  const fileList = fileInput.files;
  if (fileList.length > 0) {
    const file = fileList.item(0);
    output.textContent = `${file.name} を選択しました`;
  }
});
```

#### 結果

仕様書
---

| Specification |
| --- |
| File API # dfn-item |

ブラウザーの互換性
---------

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


SerialPort: disconnect イベント - Web API

SerialPort: disconnect イベント
===========================

**安全なコンテキスト用:** この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

**Experimental:** **これは実験的な機能です。**
本番で使用する前にブラウザー互換性一覧表をチェックしてください。

`SerialPort` インターフェイスの **`disconnect`** イベントは、ポートがデバイスから切断された時、発火します。このイベントは、USB で接続されたデバイスなどの取り外し可能なデバイスに関連付いたポートに関してのみ発火します。

このイベントは、このインターフェイスを返した `Serial` のインスタンスに伝搬します。

構文
--

`addEventListener()` のようなメソッドでイベント名を用いるか、イベントハンドラープロパティを設定します。

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

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

型
-

汎用の `Event` です。

バブリング
-----

このイベントは `Serial` に伝搬します。`event.target` プロパティはイベントを発生させた `SerialPort` オブジェクトを指します。

詳しくは、イベントのバブリングとキャプチャリングを参照してください。

例
-

### 特定のポートが切断された時通知する

ここでは、イベントリスナーを特定の `SerialPort` オブジェクトに設定します。

```js
port.addEventListener("disconnect", (event) => {
  // このポートが利用不可能になったことを通知する
});
```

### 利用不可能になった任意のポートを監視する

`disconnect` イベントは `Serial` オブジェクトに伝搬し、ここで利用不可能になった任意のポートを監視することができます。

```js
navigator.serial.addEventListener("disconnect", (event) => {
  // ポートが利用不可能になったら通知する
  // 利用不可能になったポートを参照するには、`event.target` を使う
});
```

仕様書
---

| Specification |
| --- |
| Web Serial API # dfn-disconnect |
| Web Serial API # dom-serialport-ondisconnect |

ブラウザーの互換性
---------

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

関連情報
----

* `connect` イベント


SerialPort.getSignals() - Web API

SerialPort.getSignals()
=======================

**安全なコンテキスト用:** この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

**Experimental:** **これは実験的な機能です。**
本番で使用する前にブラウザー互換性一覧表をチェックしてください。

`SerialPort` インターフェイスの **`SerialPort.getSignals()`** メソッドは、ポートの制御信号の現在の状態が入ったオブジェクトで解決する `Promise` を返します。

構文
--

```js
getSignals()
```

### 引数

なし。

### 返値

以下のメンバーが入ったオブジェクトで解決する `Promise` を返します。

`clearToSend`

シリアル通信の相手がデータの送信を要求しているかを表す `boolean` 値です。

`dataCarrierDetect`

シリアル通信に必要な制御信号があるかを表す `boolean` 値です。

`dataSetReady`

デバイスがデータの送受信が可能な状態にあるかを表す `boolean` 値です。

`ringIndicator`

シリアル通信で呼出信号を受信したかを表す `boolean` 値です。

### 例外

`InvalidStateError` `DOMException`

ポートが開かれていないとき返ります。このエラーが出ないようにするには、`SerialPort.open()` を呼び出してください。

`NetworkError` `DOMException`

デバイスから信号を取得できなかったとき返ります。

仕様書
---

| Specification |
| --- |
| Web Serial API # dom-serialport-getsignals |

ブラウザーの互換性
---------

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


SerialPort.getInfo() - Web API

SerialPort.getInfo()
====================

**安全なコンテキスト用:** この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

**Experimental:** **これは実験的な機能です。**
本番で使用する前にブラウザー互換性一覧表をチェックしてください。

`SerialPort` インターフェイスの **`getInfo()`** メソッドは、デバイスのベンダー ID とプロダクト ID をプロパティとするオブジェクトを返します。

構文
--

```js
getInfo()
```

### 引数

なし。

### 返値

以下の値を持つオブジェクトを返します。

`usbVendorId`

ポートが USB デバイスの一部である場合、USB デバイスの製造元を特定する `unsigned short` の整数です。そうでない場合は `undefined` です。

`usbProductId`

ポートが USB デバイスの一部である場合、USB デバイスを特定する `unsigned short` の整数です。そうでない場合は `undefined` です。

仕様書
---

| Specification |
| --- |
| Web Serial API # dom-serialport-getinfo |

ブラウザーの互換性
---------

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


SerialPort.readable - Web API

SerialPort.readable
===================

**安全なコンテキスト用:** この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

**Experimental:** **これは実験的な機能です。**
本番で使用する前にブラウザー互換性一覧表をチェックしてください。

`SerialPort` の読み取り専用プロパティ **`readable`** は、ポートに接続されたデバイスからデータを受信する用の `ReadableStream` を返します。このストリームから読み出せるチャンクは、`Uint8Array` のインスタンスです。このプロパティは、ポートが開かれており、かつ致命的なエラーが起きていない限り、`null` にはなりません。

値
-

`ReadableStream` です。

例
-

この例は、ポートからデータを受信する方法を示します。外側のループは致命的なエラーが発生して `readable` が `null` になるまで新しい `reader` を生成し続けることで、致命的でないエラーを処理します。

```js
while (port.readable) {
  const reader = port.readable.getReader();
  try {
    while (true) {
      const { value, done } = await reader.read();
      if (done) {
        // |reader| がキャンセルされました。
        break;
      }
      // |value| について何かをする
    }
  } catch (error) {
    // |error| を処理する
  } finally {
    reader.releaseLock();
  }
}
```

仕様書
---

| Specification |
| --- |
| Web Serial API # dom-serialport-readable |

ブラウザーの互換性
---------

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


SerialPort.forget() - Web API

SerialPort.forget()
===================

**安全なコンテキスト用:** この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

**Experimental:** **これは実験的な機能です。**
本番で使用する前にブラウザー互換性一覧表をチェックしてください。

`SerialPort` インターフェイスの **`SerialPort.forget()`** メソッドは、ポートを閉じ、忘れる処理が完了したら解決する `Promise` を返します。

構文
--

```js
forget()
```

### 引数

なし。

### 返値

ポートを閉じ、デバイスを忘れ、許可をリセットする処理が完了したら `undefined` で解決する `Promise` を返します。

仕様書
---

| Specification |
| --- |
| Web Serial API # dom-serialport-forget |

ブラウザーの互換性
---------

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


SerialPort.setSignals() - Web API

SerialPort.setSignals()
=======================

**安全なコンテキスト用:** この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

**Experimental:** **これは実験的な機能です。**
本番で使用する前にブラウザー互換性一覧表をチェックしてください。

`SerialPort` インターフェイスの **`setSignals()`** メソッドは、ポートの制御信号を設定し、完了したら解決する `Promise` を返します。

構文
--

```js
setSignals()
setSignals(options)
```

### 引数

`options` 省略可

以下の値のうち任意のものが入ったオブジェクトです。

`dataTerminalReady`

オペレーティングシステムにシリアルポートの DTR (データ端末レディ) 信号のアサート (`true` の場合) またはデアサート (`false` の場合) を指示することを表す `boolean` 値です。

`requestToSend`

オペレーティングシステムにシリアルポートの RTS (送信要求) 信号のアサート (`true` の場合) またはデアサート (`false` の場合) を指示することを表す `boolean` 値です。

`break`

オペレーティングシステムにシリアルポートのブレーク信号のアサート (`true` の場合) またはデアサート (`false` の場合) を指示することを表す `boolean` 値です。

### 返値

`Promise` を返します。

### 例外

`InvalidStateError` `DOMException`

ポートが開かれていないとき返ります。このエラーが出ないようにするには、`SerialPort.open()` を呼び出してください。

`NetworkError` `DOMException`

デバイスで信号を設定できなかったとき返ります。

仕様書
---

| Specification |
| --- |
| Web Serial API # dom-serialport-setsignals |

ブラウザーの互換性
---------

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


SerialPort.open() - Web API

SerialPort.open()
=================

**安全なコンテキスト用:** この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

**Experimental:** **これは実験的な機能です。**
本番で使用する前にブラウザー互換性一覧表をチェックしてください。

`SerialPort` インターフェイスの **`open()`** メソッドは、ポートを開く処理が完了したら解決する `Promise` を返します。デフォルトでは、ポートは 8 ビットのデータ、1 ビットのストップビット、パリティチェックなしで開かれます。パラメータ `baudRate` は必須です。

構文
--

```js
open(options)
```

### 引数

`options`

以下の値のうち任意のものが入ったオブジェクトです。

`baudRate`

シリアル通信を確立するボーレートを表す正の値です。

`bufferSize` 省略可

確保する送信用と受信用のバッファーのサイズを表す `unsigned long` の整数です。指定されない場合のデフォルト値は 255 です。

`dataBits` 省略可

1 フレームのデータビット数を表す、7 または 8 の整数です。指定されない場合のデフォルト値は 8 です。

`flowControl` 省略可

`"none"` または `"hardware"` のいずれかで、フロー制御の種類を表します。デフォルト値は `"none"` です。

`parity` 省略可

`"none"`, `"even"`, `"odd"` のいずれかで、パリティの種類を表します。デフォルト値は `"none"` です。

`stopBits` 省略可

フレームの最後のストップビットの数を表す、1 または 2の整数です。指定されない場合のデフォルト値は 1 です。

### 返値

`Promise` を返します。

### 例外

`InvalidStateError` `DOMException`

ポートが既に開かれているとき、返されます。

`NetworkError` `DOMException`

ポートを開くのに失敗したとき、返されます。

例
-

シリアルポートで通信を行う前に、ポートを開く必要があります。ポートを開くことで、サイトはデータがどのように送受信されるかを決めるために必要なパラメータを設定できます。開発者は、適切なパラメータを決めるために接続するデバイスのドキュメントを参照するべきです。

```js
await port.open({ baudRate: 9600 /\* ボーレートを決める \*/ });
```

仕様書
---

| Specification |
| --- |
| Web Serial API # dom-serialport-open |

ブラウザーの互換性
---------

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


SerialPort.writable - Web API

SerialPort.writable
===================

**安全なコンテキスト用:** この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

**Experimental:** **これは実験的な機能です。**
本番で使用する前にブラウザー互換性一覧表をチェックしてください。

`SerialPort` の読み取り専用プロパティ **`writable`** は、ポートに接続されたデバイスにデータを送信する用の `WritableStream` を返します。このストリームに書き込むチャンクは、`ArrayBuffer`, `TypedArray`, `DataView` のいずれかのインスタンスでなければなりません。このプロパティは、ポートが開かれており、かつ致命的なエラーが起きていない限り、`null` にはなりません。

値
-

`WritableStream` です。

例
-

この例では、ポートに文字列を送信する方法を示します。送信前に、`TextEncoder` により文字列を `Uint8Array` に変換します。

```js
const encoder = new TextEncoder();
const writer = port.writable.getWriter();
await writer.write(encoder.encode("PING"));
writer.releaseLock();
```

仕様書
---

| Specification |
| --- |
| Web Serial API # dom-serialport-writable |

ブラウザーの互換性
---------

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


SerialPort: connect イベント - Web API

SerialPort: connect イベント
========================

**安全なコンテキスト用:** この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

**Experimental:** **これは実験的な機能です。**
本番で使用する前にブラウザー互換性一覧表をチェックしてください。

`SerialPort` インターフェイスの **`connect`** イベントは、ポートがデバイスに接続された時、発火します。このイベントは、USB で接続されたデバイスなどの取り外し可能なデバイスに関連付いたポートに関してのみ発火します。

このイベントは、このインターフェイスを返した `Serial` のインスタンスに伝搬します。

構文
--

`addEventListener()` のようなメソッドでイベント名を用いるか、イベントハンドラープロパティを設定します。

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

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

型
-

汎用の `Event` です。

バブリング
-----

このイベントは `Serial` に伝搬します。`event.target` プロパティはイベントを発生させた `SerialPort` オブジェクトを指します。

詳しくは、イベントのバブリングとキャプチャリングを参照してください。

例
-

### 特定のポートが接続された時通知する

`Serial.requestPort()` メソッドは、ユーザーが選択した `SerialPort` で解決する `Promise` を返します。

```js
// ユーザーにシリアルポートを選んでもらう
const port = await navigator.serial.requestPort();

port.addEventListener("connect", (event) => {
  // 選択されたポートが接続されたら通知する
});
```

### 新しく接続された任意のポートを監視する

`connect` イベントは `Serial` オブジェクトに伝搬し、ここで新しく接続された任意のポートを監視することができます。

```js
navigator.serial.addEventListener("connect", (event) => {
  // 新しいポートが利用可能になったら通知する
  // 新しいポートを参照するには、`event.target` を使う
});
```

仕様書
---

| Specification |
| --- |
| Web Serial API # dfn-connect |
| Web Serial API # dom-serialport-onconnect |

ブラウザーの互換性
---------

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

関連情報
----

* `disconnect` イベント


SerialPort.close() - Web API

SerialPort.close()
==================

**安全なコンテキスト用:** この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

**Experimental:** **これは実験的な機能です。**
本番で使用する前にブラウザー互換性一覧表をチェックしてください。

`SerialPort` インターフェイスの **`SerialPort.close()`** メソッドは、ポートを閉じる処理が完了したら解決する `Promise` を返します。

構文
--

```js
close()
```

### 引数

なし。

### 返値

`Promise` を返します。

仕様書
---

| Specification |
| --- |
| Web Serial API # dom-serialport-close |

ブラウザーの互換性
---------

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


SensorErrorEvent: SensorErrorEvent() コンストラクター - Web API

SensorErrorEvent: SensorErrorEvent() コンストラクター
=============================================

**`SensorErrorEvent`** コンストラクターは、`Sensor` をベースとする各インターフェイスから投げられたエラーに関する情報を提供する新しい `SensorErrorEvent` オブジェクトを生成します。

構文
--

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

### 引数

`type`

 イベントの名前を表す文字列です。
 大文字と小文字は区別され、ブラウザーは常に `error` に設定します。

`options`

*`Event()` で定義されているプロパティに加え*、以下のプロパティを持ちうるオブジェクトです。

`error`

エラーの内容を表す `DOMException` オブジェクトです。

### 返値

新しい `SensorErrorEvent` オブジェクトです。

仕様書
---

| Specification |
| --- |
| Generic Sensor API # dom-sensorerrorevent-sensorerrorevent |

ブラウザーの互換性
---------

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


SensorErrorEvent: error プロパティ - Web API

SensorErrorEvent: error プロパティ
=============================

`SensorErrorEvent` インターフェイスの読み取り専用プロパティ **`error`** は、イベントのコンストラクターに渡された `DOMException` オブジェクトを返します。

値
-

`DOMException` です。

仕様書
---

| Specification |
| --- |
| Generic Sensor API # dom-sensorerrorevent-error |

ブラウザーの互換性
---------

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


Canvas チュートリアル - Web API

Canvas チュートリアル
==============

このチュートリアルは、 **`<canvas>`** 要素を使用して二次元のグラフィックを描画する方法を、基本から説明します。ここでの例は、キャンバスで何ができるかを明確に示すものであり、独自のコンテンツを作成するためのコードスニペットも提供しています。

`<canvas>` は HTML の要素であり、スクリプト（ふつうは JavaScript）を使ってグラフィックを描くことができます。これは例えば、グラフを描いたり、写真を合成する、または簡単なアニメーションを（あまり簡単ではないものも）作成したりすることができます。このページにある画像は、このチュートリアルで作成する **`<canvas>`** の実装の例を示しています。

`<canvas>` は Apple が macOS Dashboard のために WebKit に初めて導入した後、ブラウザーに実装されました。現在は、あらゆる主要ブラウザーが対応しています。

始める前に
-----

`<canvas>` を使うのはそれほど難しくはありませんが、 HTML と JavaScript の基本的な理解が必要です。一部の古いブラウザーは `<canvas>` 要素に対応していませんが、最近のバージョンの主要ブラウザーはすべて対応しています。キャンバスの既定の大きさは、 300 ピクセル × 150 ピクセル（幅 × 高さ）です。しかし、 HTML の `height` および `width` プロパティを使用して、独自の大きさを定義することができます。キャンバスにグラフィックを描画するためには、JavaScript のコンテキストオブジェクトを使用します。このオブジェクトは、グラフィックをその場で生成します。

チュートリアル
-------

1. 基本的な使い方
2. 図形の描画
3. スタイルと色の適用
4. 文字の描画
5. 画像の使用
6. 座標変換
7. 合成とクリッピング
8. 基本的なアニメーション
9. 高度なアニメーション
10. ピクセル操作
11. キャンバスの最適化
12. おわりに
関連情報
----

* Canvas トピックのページ
* HTML5CanvasTutorials
貢献者へのメモ
-------

2013 年 6 月 17 日の週に発生した不運な技術的エラーにより、すべての過去の貢献者の属性を含む、このチュートリアルの履歴情報が失われました。この問題についておわびするとともに、この不運な事故を容赦願います。

* 次のページ »


基本的なアニメーション - Web API

基本的なアニメーション
===========

* « 前のページ
* 次のページ »

私たちが `<canvas>` 要素の操作に JavaScript を使うのは、とても簡単にインタラクティブなアニメーションを作成できるからです。本章では、いくつかの基本的なアニメーションで、その概要をつかんでいきます。

おそらく最大の制約は、キャンバスに図形を一度描画すると、その状態が維持されることです。アニメーションさせる場合にも、移動する部分と以前に描いた部分をすべて再描画する必要があります。複雑なフレームの再描画には時間がかかり、パフォーマンスは、実行しているコンピューターの速度に大きく依存します。

基本的なアニメーションの手順
--------------

フレームを描画させる手順は、このようになります。

1. **キャンバスをクリアする**
 描画する図形が（たとえば、背景画像のように）キャンバス全体を埋めない限り、以前に描画した図形をすべてクリアする必要があります。最も簡単な方法は、`clearRect()` メソッドを使うことです。
2. **キャンバスの状態を保存する**
 キャンバスの状態に影響を与える設定（スタイル、変形など）を変更していて、フレームを描画するたびに元の状態を使用したい場合は、その状態を保存する必要があります。
3. **アニメ―ションさせる図形を描画する**
 実際に、フレームの描画を行います。
4. **キャンバスの状態を復元する**
 状態を保存した場合は、新しいフレームを描画する前に状態を復元します。
アニメーションの制御
----------

図形は、キャンバスのメソッドを直接使用するか、カスタム関数を呼び出すことによって描画されます。通常は、スクリプトの実行が終了したときにのみ、これらの結果がキャンバスに表示されます。たとえば、`for` ループ内からアニメーションを実行することはできません。

つまり、一定の期間ごとに描画関数を実行する方法が必要です。このようなアニメーションを制御するには、 2 つの方法があります。

### スケジュールの更新

まず、`setInterval()`、`setTimeout()` があります。それから、`window.requestAnimationFrame()` 関数があります。これらは、特定の関数を一定時間で呼び出すために使用できます。

`setInterval()`

`function` で指定した関数を `delay` ミリ秒ごとに繰り返し実行します。

`setTimeout()`

`function` で指定した関数を `delay` ミリ秒後に実行します。

`requestAnimationFrame(callback)`

アニメーションを実行することをブラウザーに通知し、次の再描画の前にアニメーションを更新するため、ブラウザーが指定の関数を呼び出すように要求します。

ユーザーの操作が必要ない場合は、提供されたコードを繰り返し実行する `setInterval()` 関数が利用できます。ゲームを作成したい場合、キーボードまたはマウスのイベントを使用したアニメーションを制御するためには `setTimeout()` が利用できます。イベントリスナー (`EventListener`) を設定することで、ユーザーの操作を取得し、アニメーション関数を実行します。

**メモ:** 以下の例では、`window.requestAnimationFrame()` メソッドを使用してアニメーションを制御します。`requestAnimationFrame` メソッドは、フレームを描画する準備ができた時にシステムがアニメーションフレームを呼び出すことで、よりスムーズで効率的な方法でアニメーションを提供します。通常、コールバック回数は 1 秒あたり 60 回となり、バックグラウンドタブで実行している場合は、レートが低くなることがあります。特にゲームのアニメーションループの詳細については、ゲーム開発のビデオゲームの解剖学を参照してください。

アニメーションする太陽系
------------

この例は、太陽系の小さなモデルをアニメーションさせます。

### HTML

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

### JavaScript

```js
var sun = new Image();
var moon = new Image();
var earth = new Image();
function init() {
  sun.src = "canvas\_sun.png";
  moon.src = "canvas\_moon.png";
  earth.src = "canvas\_earth.png";
  window.requestAnimationFrame(draw);
}

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

  ctx.globalCompositeOperation = "destination-over";
  ctx.clearRect(0, 0, 300, 300); // clear canvas

  ctx.fillStyle = "rgba(0, 0, 0, 0.4)";
  ctx.strokeStyle = "rgba(0, 153, 255, 0.4)";
  ctx.save();
  ctx.translate(150, 150);

  // 地球
  var time = new Date();
  ctx.rotate(
    ((2 \* Math.PI) / 60) \* time.getSeconds() +
      ((2 \* Math.PI) / 60000) \* time.getMilliseconds(),
  );
  ctx.translate(105, 0);
  ctx.fillRect(0, -12, 40, 24); // 影
  ctx.drawImage(earth, -12, -12);

  // 月
  ctx.save();
  ctx.rotate(
    ((2 \* Math.PI) / 6) \* time.getSeconds() +
      ((2 \* Math.PI) / 6000) \* time.getMilliseconds(),
  );
  ctx.translate(0, 28.5);
  ctx.drawImage(moon, -3.5, -3.5);
  ctx.restore();

  ctx.restore();

  ctx.beginPath();
  ctx.arc(150, 150, 105, 0, Math.PI \* 2, false); // 地球の軌道
  ctx.stroke();

  ctx.drawImage(sun, 0, 0, 300, 300);

  window.requestAnimationFrame(draw);
}

init();
```

### 結果

アニメ―ションする時計
-----------

この例は、アニメーションする時計で現在時間を表示します。

### HTML

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

### JavaScript

```js
function clock() {
  var now = new Date();
  var ctx = document.getElementById("canvas").getContext("2d");
  ctx.save();
  ctx.clearRect(0, 0, 150, 150);
  ctx.translate(75, 75);
  ctx.scale(0.4, 0.4);
  ctx.rotate(-Math.PI / 2);
  ctx.strokeStyle = "black";
  ctx.fillStyle = "white";
  ctx.lineWidth = 8;
  ctx.lineCap = "round";

  // 文字盤の時
  ctx.save();
  for (var i = 0; i < 12; i++) {
    ctx.beginPath();
    ctx.rotate(Math.PI / 6);
    ctx.moveTo(100, 0);
    ctx.lineTo(120, 0);
    ctx.stroke();
  }
  ctx.restore();

  // 文字盤の分
  ctx.save();
  ctx.lineWidth = 5;
  for (i = 0; i < 60; i++) {
    if (i % 5 != 0) {
      ctx.beginPath();
      ctx.moveTo(117, 0);
      ctx.lineTo(120, 0);
      ctx.stroke();
    }
    ctx.rotate(Math.PI / 30);
  }
  ctx.restore();

  var sec = now.getSeconds();
  var min = now.getMinutes();
  var hr = now.getHours();
  hr = hr >= 12 ? hr - 12 : hr;

  ctx.fillStyle = "black";

  // 時針
  ctx.save();
  ctx.rotate(
    hr \* (Math.PI / 6) + (Math.PI / 360) \* min + (Math.PI / 21600) \* sec,
  );
  ctx.lineWidth = 14;
  ctx.beginPath();
  ctx.moveTo(-20, 0);
  ctx.lineTo(80, 0);
  ctx.stroke();
  ctx.restore();

  // 分針
  ctx.save();
  ctx.rotate((Math.PI / 30) \* min + (Math.PI / 1800) \* sec);
  ctx.lineWidth = 10;
  ctx.beginPath();
  ctx.moveTo(-28, 0);
  ctx.lineTo(112, 0);
  ctx.stroke();
  ctx.restore();

  // 秒針
  ctx.save();
  ctx.rotate((sec \* Math.PI) / 30);
  ctx.strokeStyle = "#D40000";
  ctx.fillStyle = "#D40000";
  ctx.lineWidth = 6;
  ctx.beginPath();
  ctx.moveTo(-30, 0);
  ctx.lineTo(83, 0);
  ctx.stroke();
  ctx.beginPath();
  ctx.arc(0, 0, 10, 0, Math.PI \* 2, true);
  ctx.fill();
  ctx.beginPath();
  ctx.arc(95, 0, 10, 0, Math.PI \* 2, true);
  ctx.stroke();
  ctx.fillStyle = "rgba(0, 0, 0, 0)";
  ctx.arc(0, 0, 3, 0, Math.PI \* 2, true);
  ctx.fill();
  ctx.restore();

  ctx.beginPath();
  ctx.lineWidth = 14;
  ctx.strokeStyle = "#325FA2";
  ctx.arc(0, 0, 142, 0, Math.PI \* 2, true);
  ctx.stroke();

  ctx.restore();

  window.requestAnimationFrame(clock);
}

window.requestAnimationFrame(clock);
```

### 結果

ループする風景
-------

この例は、左から右へ風景写真をスクロールさせます。Wikipedia からヨセミテ国立公園の画像を使いましたが、キャンバスよりも大きな任意の画像を使用できます。

### HTML

この HTML には、画像がスクロール表示される `<canvas>` が含まれます。ここで指定する幅と高さは、 JavaScript のコードにある変数 `CanvasXZSize` と `CanvasYSize` の値と一致する必要があることに注意してください。

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

### JavaScript

```js
var img = new Image();

// ユーザー変数。これらをカスタマイズすると、スクロールする画像、方向、速度を
// 変更することができます。

img.src = "capitan\_meadows\_yosemite\_national\_park.jpg";
var CanvasXSize = 800;
var CanvasYSize = 200;
var speed = 30; // 小さくすると速くなる
var scale = 1.05;
var y = -4.5; // 垂直オフセット

// メインプログラム

var dx = 0.75;
var imgW;
var imgH;
var x = 0;
var clearX;
var clearY;
var ctx;

img.onload = function () {
  imgW = img.width \* scale;
  imgH = img.height \* scale;

  if (imgW > CanvasXSize) {
    // image larger than canvas
    x = CanvasXSize - imgW;
  }
  if (imgW > CanvasXSize) {
    // image width larger than canvas
    clearX = imgW;
  } else {
    clearX = CanvasXSize;
  }
  if (imgH > CanvasYSize) {
    // image height larger than canvas
    clearY = imgH;
  } else {
    clearY = CanvasYSize;
  }

  // get canvas context
  ctx = document.getElementById("canvas").getContext("2d");

  // set refresh rate
  return setInterval(draw, speed);
};

function draw() {
  ctx.clearRect(0, 0, clearX, clearY); // clear the canvas

  // if image is <= Canvas Size
  if (imgW <= CanvasXSize) {
    // reset, start from beginning
    if (x > CanvasXSize) {
      x = -imgW + x;
    }
    // draw additional image1
    if (x > 0) {
      ctx.drawImage(img, -imgW + x, y, imgW, imgH);
    }
    // draw additional image2
    if (x - imgW > 0) {
      ctx.drawImage(img, -imgW \* 2 + x, y, imgW, imgH);
    }
  }

  // image is > Canvas Size
  else {
    // reset, start from beginning
    if (x > CanvasXSize) {
      x = CanvasXSize - imgW;
    }
    // draw additional image
    if (x > CanvasXSize - imgW) {
      ctx.drawImage(img, x - imgW + 1, y, imgW, imgH);
    }
  }
  // 画像を描画
  ctx.drawImage(img, x, y, imgW, imgH);
  // 移動量
  x += dx;
}
```

### 結果

マウス追跡アニメーション
------------

### HTML

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

### CSS

```css
#cw {
  position: fixed;
  z-index: -1;
}

body {
  margin: 0;
  padding: 0;
  background-color: rgba(0, 0, 0, 0.05);
}
```

### JavaScript

```js
const canvas = document.getElementById("cw");
const context = canvas.getContext("2d");
context.globalAlpha = 0.5;

const cursor = {
  x: innerWidth / 2,
  y: innerHeight / 2,
};

let particlesArray = [];

generateParticles(101);
setSize();
anim();

addEventListener("mousemove", (e) => {
  cursor.x = e.clientX;
  cursor.y = e.clientY;
});

addEventListener(
  "touchmove",
  (e) => {
    e.preventDefault();
    cursor.x = e.touches[0].clientX;
    cursor.y = e.touches[0].clientY;
  },
  { passive: false },
);

addEventListener("resize", () => setSize());

function generateParticles(amount) {
  for (let i = 0; i < amount; i++) {
    particlesArray[i] = new Particle(
      innerWidth / 2,
      innerHeight / 2,
      4,
      generateColor(),
      0.02,
    );
  }
}

function generateColor() {
  let hexSet = "0123456789ABCDEF";
  let finalHexString = "#";
  for (let i = 0; i < 6; i++) {
    finalHexString += hexSet[Math.ceil(Math.random() \* 15)];
  }
  return finalHexString;
}

function setSize() {
  canvas.height = innerHeight;
  canvas.width = innerWidth;
}

function Particle(x, y, particleTrailWidth, strokeColor, rotateSpeed) {
  this.x = x;
  this.y = y;
  this.particleTrailWidth = particleTrailWidth;
  this.strokeColor = strokeColor;
  this.theta = Math.random() \* Math.PI \* 2;
  this.rotateSpeed = rotateSpeed;
  this.t = Math.random() \* 150;

  this.rotate = () => {
    const ls = {
      x: this.x,
      y: this.y,
    };
    this.theta += this.rotateSpeed;
    this.x = cursor.x + Math.cos(this.theta) \* this.t;
    this.y = cursor.y + Math.sin(this.theta) \* this.t;
    context.beginPath();
    context.lineWidth = this.particleTrailWidth;
    context.strokeStyle = this.strokeColor;
    context.moveTo(ls.x, ls.y);
    context.lineTo(this.x, this.y);
    context.stroke();
  };
}

function anim() {
  requestAnimationFrame(anim);

  context.fillStyle = "rgba(0,0,0,0.05)";
  context.fillRect(0, 0, canvas.width, canvas.height);

  particlesArray.forEach((particle) => particle.rotate());
}
```

### 結果

その他の例
-----

基本的なレイキャスター

キーボードを使ってアニメーションをどのように制御するか説明した良いサンプルです。

高度なアニメーション

高度なアニメーション技術と物の動きについて見ていきます。

* « 前のページ
* 次のページ »


キャンバスとピクセル操作 - Web API

キャンバスとピクセル操作
============

* « 前のページ
* 次のページ »

これまで、キャンバスの実際のピクセルは見てきませんでした。 `ImageData` オブジェクトを使用して、ピクセルデータを操作するためにデータ配列へ直接読み取りや書き込みを行うことが可能です。また、画像のスムージング（アンチエイリアシング）の制御方法やキャンバスの画像を保存する方法も見ていきます。

ImageData オブジェクト
----------------

`ImageData` オブジェクトは、キャンバスオブジェクトの領域にあるピクセルデータを表します。これには以下の読み取り専用プロパティがあります。

`width`

画像の幅をピクセル数で表します。

`height`

画像の高さをピクセル数で表します。

`data`

`0` から `255` の間の (両端の値を含む) 整数データを RGBA の順で収めた一次元配列を表す `Uint8ClampedArray` です。

`data` プロパティは、生のピクセルデータを参照するためにアクセス可能な `Uint8ClampedArray` を返します。それぞれのピクセルは 4 つの 1 バイト値（赤、緑、青、アルファの順、すなわち "RGBA" 形式）で表されます。また、それぞれの色成分は 0 から 255 の間の整数で表します。さらに、それぞれの成分は配列内で連続した添字が割り当てられており、左上のピクセルの赤色成分が配列の添字 0 になります。配列の中でピクセルは左から右へ進み、さらに下へと進んでいきます。

`Uint8ClampedArray` は `height` × `width` × 4 バイトのデータがあり、添字の範囲は 0 から (`height`×`width`×4)-1 になります。

例えば画像の 50 行目の 200 列目にあるピクセルから青色成分の値を読み取るには、以下のようにします。

```js
blueComponent = imageData.data[50 \* (imageData.width \* 4) + 200 \* 4 + 2];
```

座標（X と Y）が与えられると、次のようなことをすることになるかもしれません。

```js
var xCoord = 50;
var yCoord = 100;
var canvasWidth = 1024;

function getColorIndicesForCoord(x, y, width) {
  var red = y \* (width \* 4) + x \* 4;
  return [red, red + 1, red + 2, red + 3];
}

var colorIndices = getColorIndicesForCoord(xCoord, yCoord, canvasWidth);

var redIndex = colorIndices[0];
var greenIndex = colorIndices[1];
var blueIndex = colorIndices[2];
var alphaIndex = colorIndices[3];

var redForCoord = imageData.data[redIndex];
var greenForCoord = imageData.data[greenIndex];
var blueForCoord = imageData.data[blueIndex];
var alphaForCoord = imageData.data[alphaIndex];
```

または ES2015 では次のようになります。

```js
const xCoord = 50;
const yCoord = 100;
const canvasWidth = 1024;

const getColorIndicesForCoord = (x, y, width) => {
  const red = y \* (width \* 4) + x \* 4;
  return [red, red + 1, red + 2, red + 3];
};

const colorIndices = getColorIndicesForCoord(xCoord, yCoord, canvasWidth);

const [redIndex, greenIndex, blueIndex, alphaIndex] = colorIndices;
```

`Uint8ClampedArray.length` 属性を読み取ると、ピクセル配列のサイズをバイト数で知ることができます。

```js
var numBytes = imageData.data.length;
```

ImageData オブジェクトの作成
-------------------

新たに空の `ImageData` オブジェクトを作成するには、`createImageData()` メソッドを使用します。`createImageData()` メソッドは 2 種類の形式があります。

```js
var myImageData = ctx.createImageData(width, height);
```

これは、特定の寸法の新たな `ImageData` オブジェクトを作成します。すべてのピクセルは透明な黒色（すべてがゼロ、すなわち rgba(0,0,0,0)）に設定されます。

新たな `ImageData` オブジェクトを、　`anotherImageData` で指定したオブジェクトと同じ寸法で作成することもできます。新しいオブジェクトのピクセルは、すべて透明な黒色に設定されます。**画像データはコピーされません!**

```js
var myImageData = ctx.createImageData(anotherImageData);
```

コンテキストのピクセルデータの取得
-----------------

キャンバスのコンテキストのピクセルデータの複製を持つ `ImageData` オブジェクトを取得するには、`getImageData()` メソッドを使用します。

```js
var myImageData = ctx.getImageData(left, top, width, height);
```

このメソッドは (`left`,`top`)、(`left+width`, `top`)、(`left`, `top+height`)、(`left+width`, `top+height`) の点で四隅を表したキャンバスの領域のピクセルデータを表す `ImageData` オブジェクトを返します。点の座標は、キャンバスの座標空間の単位で指定します。

**メモ:** 返される `ImageData` オブジェクトで、キャンバスの外部にあるピクセルはすべて透明な黒色になります。

このメソッドは、キャンバスを使用した動画の操作 (en-US)の記事でも説明しています。

### カラーピッカー

この例では、マウスカーソルの下にある色を表示するために getImageData() メソッドを使用しています。ここでは現在のマウスカーソルの位置を `layerX` と `layerY` で求めて、getImageData() が提供するピクセル配列で該当位置のピクセルデータを探します。最後に、色を表示するための `<div>` で背景色とテキストを設定するために、配列データを使用します。

```js
var img = new Image();
img.crossOrigin = "anonymous";
img.src = "./assets/rhino.jpg";
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
img.onload = function () {
  ctx.drawImage(img, 0, 0);
  img.style.display = "none";
};
var hoveredColor = document.getElementById("hovered-color");
var selectedColor = document.getElementById("selected-color");

function pick(event, destination) {
  var x = event.layerX;
  var y = event.layerY;
  var pixel = ctx.getImageData(x, y, 1, 1);
  var data = pixel.data;

  const rgba = `rgba(${data[0]}, ${data[1]}, ${data[2]}, ${data[3] / 255})`;
  destination.style.background = rgba;
  destination.textContent = rgba;

  return rgba;
}

canvas.addEventListener("mousemove", function (event) {
  pick(event, hoveredColor);
});
canvas.addEventListener("click", function (event) {
  pick(event, selectedColor);
});
```

このコードの使い方は、次のライブ例で紹介します。

ソースコードもご覧ください。 HTML, JavaScript です。

コンテキストへのピクセルデータの描画
------------------

`putImageData()` メソッドを使用して、コンテキストにピクセルデータを描くことができます。

```js
ctx.putImageData(myImageData, dx, dy);
```

引数 `dx` と `dy` は、描画したいピクセルデータの左上の隅を描く位置を、コンテキストのデバイス座標で示します。

例えば `myImageData` が表す画像全体をコンテキストの左上の隅から描くには、単純に以下のようにします。

```js
ctx.putImageData(myImageData, 0, 0);
```

### 色のグレースケール化と反転

この例では、すべてのピクセルに対して繰り返し処理を行い、値を変更したピクセル配列を `putImageData()` を使ってキャンバスに戻しています。反転機能は、最大値 255 から各色を減算します。グレースケール関数は、赤、緑、青の平均値を使用します。また、例えば `x = 0.299r + 0.587g + 0.114b` という式で与えられる加重平均を使用することもできます。詳しくは Wikipedia のグレースケールをご覧ください。

```js
var img = new Image();
img.crossOrigin = "anonymous";
img.src = "./assets/rhino.jpg";

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

img.onload = function () {
  ctx.drawImage(img, 0, 0);
};

var original = function () {
  ctx.drawImage(img, 0, 0);
};

var invert = function () {
  ctx.drawImage(img, 0, 0);
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const data = imageData.data;
  for (var i = 0; i < data.length; i += 4) {
    data[i] = 255 - data[i]; // red
    data[i + 1] = 255 - data[i + 1]; // green
    data[i + 2] = 255 - data[i + 2]; // blue
  }
  ctx.putImageData(imageData, 0, 0);
};

var grayscale = function () {
  ctx.drawImage(img, 0, 0);
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const data = imageData.data;
  for (var i = 0; i < data.length; i += 4) {
    var avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
    data[i] = avg; // red
    data[i + 1] = avg; // green
    data[i + 2] = avg; // blue
  }
  ctx.putImageData(imageData, 0, 0);
};

const inputs = document.querySelectorAll("[name=color]");
for (const input of inputs) {
  input.addEventListener("change", function (evt) {
    switch (evt.target.value) {
      case "inverted":
        return invert();
      case "grayscale":
        return grayscale();
      default:
        return original();
    }
  });
}
```

このコードの使い方は、次のライブ例で紹介します。

ソースコードも利用できます。 — HTML, JavaScript

ズームとアンチエイリアシング
--------------

`drawImage()` メソッド、第 2 の canvas、`imageSmoothingEnabled` プロパティの力を借りて、画像をズームアップして詳しく見ることができます。また、`imageSmoothingEnabled` のない 3 番目のキャンバスも描画し、左右に並べて比較できるようにします。

マウスカーソルの位置を取得して、そこから上下左右に 5 ピクセルの範囲の画像を切り取ります。そして切り取った画像を別のキャンバスにコピーして、望むサイズにリサイズします。ズーム用のキャンバスでは、元のキャンバスから切り取った 10×10 ピクセルの画像を 200×200 ピクセルにリサイズしています。

```js
zoomctx.drawImage(
  canvas,
  Math.min(Math.max(0, x - 5), img.width - 10),
  Math.min(Math.max(0, y - 5), img.height - 10),
  10,
  10,
  0,
  0,
  200,
  200,
);
```

ズームの例です。

```js
var img = new Image();
img.crossOrigin = "anonymous";
img.src = "./assets/rhino.jpg";
img.onload = function () {
  draw(this);
};

function draw(img) {
  var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0);

  var smoothedZoomCtx = document
    .getElementById("smoothed-zoom")
    .getContext("2d");
  smoothedZoomCtx.imageSmoothingEnabled = true;
  smoothedZoomCtx.mozImageSmoothingEnabled = true;
  smoothedZoomCtx.webkitImageSmoothingEnabled = true;
  smoothedZoomCtx.msImageSmoothingEnabled = true;

  var pixelatedZoomCtx = document
    .getElementById("pixelated-zoom")
    .getContext("2d");
  pixelatedZoomCtx.imageSmoothingEnabled = false;
  pixelatedZoomCtx.mozImageSmoothingEnabled = false;
  pixelatedZoomCtx.webkitImageSmoothingEnabled = false;
  pixelatedZoomCtx.msImageSmoothingEnabled = false;

  var zoom = function (ctx, x, y) {
    ctx.drawImage(
      canvas,
      Math.min(Math.max(0, x - 5), img.width - 10),
      Math.min(Math.max(0, y - 5), img.height - 10),
      10,
      10,
      0,
      0,
      200,
      200,
    );
  };

  canvas.addEventListener("mousemove", function (event) {
    const x = event.layerX;
    const y = event.layerY;
    zoom(smoothedZoomCtx, x, y);
    zoom(pixelatedZoomCtx, x, y);
  });
}
```

このコードの使い方は、次のライブ例で紹介します。

ソースコードも見ることができます。 — HTML, JavaScript

画像の保存
-----

`HTMLCanvasElement` は、画像を保存する際に役に立つ `toDataURL()` メソッドを提供します。これは、 data URI (en-US) として引数 `type` で指定した形式（既定値は PNG）で表した画像を返します。返される画像の解像度は 96 dpi です。

**メモ:** CORS を使用せずに他の origin から取得したピクセルがキャンバスに含まれている場合、キャンバスは**汚染**され、その内容を読み取ったり保存したりできなくなることに注意してください。
 セキュリティと汚染されたキャンバスを参照してください。

`canvas.toDataURL('image/png')`

既定の設定。PNG 画像を作成します。

`canvas.toDataURL('image/jpeg', quality)`

JPG 画像を作成します。オプションで、品質を 0 から 1 の範囲で指定できます。1 は最高品質、0 はほとんど見分けがつかなくなりますがファイルサイズを小さくできます。

キャンバスから生成した data URI は、例えば任意の `<image>` のソースとして使用したり、ディスクに保存するために download 属性を持つハイパーリンクに投入することができます。

また、キャンバスから `Blob` を生成することもできます。

`canvas.toBlob(_callback_, _type_, _encoderOptions_)`

キャンバスに含まれる画像を表す `Blob` オブジェクトを作成します。

関連情報
----

* `ImageData`
* キャンバスを使用した動画の操作 (en-US)
* Canvas, images and pixels – by Christian Heilmann
* « 前のページ
* 次のページ »


テキストの描画 - Web API

テキストの描画
=======

* « 前のページ
* 次のページ »

前の章でスタイルや色を適用する方法を見た後は、キャンバスにテキストを描画する方法を見ていきます。

テキストの描画
-------

キャンバスの描画コンテキストでは、 2 種類のテキスト描画方法を提供しています。

`fillText(text, x, y [, maxWidth])`

(x,y) で指定した位置にテキストを塗りつぶして描画します。任意で最大描画幅を指定できます。

`strokeText(text, x, y [, maxWidth])`

(x,y) で指定した位置にテキストの輪郭を描画します。任意で最大描画幅を指定できます。

### `fillText` の例

現在の `fillStyle` を使用して、テキストを塗りつぶして描画します。

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  ctx.font = "48px serif";
  ctx.fillText("Hello world", 10, 50);
}
```

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

```
draw();
```

### `strokeText` の例

現在の `strokeStyle` を使用して、テキストの輪郭を描画します。

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  ctx.font = "48px serif";
  ctx.strokeText("Hello world", 10, 50);
}
```

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

```
draw();
```

テキストのスタイル付け
-----------

上記の例では、テキストを既定のサイズより若干大きくするため、すでに `font` プロパティを使用していました。キャンバスにテキストを表示する形式を調整できるプロパティは、さらにいくつかあります。

`font = value`

テキストを描画する際に使用するテキストのスタイルです。 CSS の `font` プロパティと同じ構文に則った文字列です。既定のフォントは 10px sans-serif です。

`textAlign = value`

テキストの配置を設定します。使用できる値は `start`、`end`、`left`、`right`、`center` です。既定値は `start` です。

`textBaseline = value`

ベースラインの位置ぞろえを設定します。使用できる値は `top`、`hanging`、`middle`、`alphabetic`、`ideographic`、`bottom` です。既定値は `alphabetic` です。

`direction = value`

書字方向を設定します。使用できる値は `ltr`、`rtl`、`inherit` です。既定値は `inherit` です。

以前に CSS を扱ったことがあれば、これらのプロパティも見慣れているでしょう。

以下は WHATWG 提供の、`textBaseline` 属性によってサポートされている様々なベースラインを示した図です。
 ![em 矩形の上端はフォントのグリフの上端にほぼ一致し、 hanging baseline は 906 のようないくつかのグリフが固定されているところ、 middle は em 矩形の上端と下端の中間、alphabetic baseline は Á, ÿ, f, Ω などの文字が固定されているところ、ideographic baseline は私や達などのグリフが固定され、em 矩形の底はフォント中のグリフの底にほぼ一致しているところです。グリフが em 矩形の外まで伸びているため、バウンディングボックスの上端と下端はこれらのベースラインから遠く離れていることがあります。](/ja/docs/Web/API/Canvas_API/Tutorial/Drawing_text/baselines.png)

### textBaseline の例

以下のコードを編集すると、canvas の変更個所をその場で確認できます。
```

<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.font = "48px serif";
ctx.textBaseline = "hanging";
ctx.strokeText("Hello world", 0, 100);</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);
```

高度なテキスト測定
---------

テキストのより詳細な情報を得る必要がある場合は、以下のメソッドで測定することができます。

`measureText()`

指定したテキストを現在のテキストスタイルで描画したときの幅をピクセル単位で表した情報を持つ、`TextMetrics` (en-US) オブジェクトを返します。

以下のコードスニペットは、テキストを測定して幅を得る方法を示しています。

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  var text = ctx.measureText("foo"); // TextMetrics object
  text.width; // 16;
}
```

Gecko 固有の注意事項
-------------

Gecko (Firefox、Firefox OS および他の Mozilla ベースアプリケーション) では一部の接頭辞付き API で、早期バージョンのテキスト描画法を実装しています。これらは非推奨になり削除されており、動作が保証されていません。

* « 前のページ
* 次のページ »


おわりに - Web API

おわりに
====

* « 前のページ

おめでとうございます。キャンバスのチュートリアルは終了です。この知識は、ウェブ上で素晴らしい二次元グラフィックを作るのに役立ちます。

他の例とチュートリアル
-----------

ここでは様々なデモや、更なるキャンバスについての例を紹介します。

Codepen.io

ブラウザー上のフロントエンド開発者向けのプレイグラウンドとコードエディターです。

HTML5 Canvas Tutorials

キャンバス API の例です。

Game development

ゲームは最も人気な活動の一つです。標準に準拠したウェブブラウザーで実行できる、より良くより強力なゲームを開発するための新しい技術が定期的に登場しています。

その他の Web API
------------

これらの API は、キャンバスやグラフィックをさらに扱う際に役立つかもしれません。

WebGL

複雑なグラフィックや三次元を含んだレンダリングのための高度な API です。

SVG

Scalable Vector Graphics は、画像をベクター（線）と図形の集合で表現することで、描画サイズに関わらず滑らかに拡大縮小できるようにしたものです。

Web Audio

Web Audio API は、ウェブ上の音声を制御するための強力で多用途なシステムを提供し、開発者は音声ソースの選択、音声へのエフェクトの追加、音声視覚化の作成、空間効果（パンニングなど）の適用などを行うことができるようになります。

質問
--

Stack Overflow

"html5-canvas" とタグ付けされた質問です。

Comments about this tutorial – the MDN documentation community

このチュートリアルについて何かコメントや感謝の言葉がありましたら、お気軽にご連絡ください。

* « 前のページ


高度なアニメーション - Web API

高度なアニメーション
==========

* « 前のページ
* 次のページ »

前の章では、いくつかの基本的なアニメーションを作成して、物の動かし方を学びました。このパートでは、 運動そのものをより詳細に見て、 アニメーションをより高度にするための物理を追加していきましょう。

ボールの描画
------

アニメーションの勉強のために、ボールを使おうと思うので、最初にボールをキャンバス上に描きましょう。以下のコードで設定します。

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

普通通り、まず描画コンテキストが必要になります。ボールを描くため、 `ball` オブジェクトを作成して、プロパティと、キャンバスにボールを描くための `draw()` メソッドを持つようにします。

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

var ball = {
  x: 100,
  y: 100,
  radius: 25,
  color: "blue",
  draw: function () {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI \* 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  },
};

ball.draw();
```

ここでは特別なことはなく、ボールは本当に単純な円で、`arc()` メソッドの助けを借りて描かれています。

速度の追加
-----

ボールができたので、このチュートリアルの前の章で学んだような、基本的なアニメーションを追加する準備ができたことになります。ここでも `window.requestAnimationFrame()` がアニメーションを制御するのに役立っています。ボールは、位置に速度ベクトルを追加することで移動します。また、フレームごとに clear キャンバスに以前のフレームから古い円を削除しています。

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

var ball = {
  x: 100,
  y: 100,
  vx: 5,
  vy: 2,
  radius: 25,
  color: "blue",
  draw: function () {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI \* 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  },
};

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ball.draw();
  ball.x += ball.vx;
  ball.y += ball.vy;
  raf = window.requestAnimationFrame(draw);
}

canvas.addEventListener("mouseover", function (e) {
  raf = window.requestAnimationFrame(draw);
});

canvas.addEventListener("mouseout", function (e) {
  window.cancelAnimationFrame(raf);
});

ball.draw();
```

境界
--

境界で衝突テストを行わないと、ボールはすぐにキャンバスから飛び出してしまいます。ボールの `x` と `y` の位置がキャンバスの寸法から外れているかどうかをチェックし、速度ベクトルの向きを反転させる必要があります。そのために、`draw` メソッドに次のようなチェックを追加します。

```js
if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
  ball.vy = -ball.vy;
}
if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
  ball.vx = -ball.vx;
}
```

### 最初のデモ

ここまでで実際にどのように見えるか見てみましょう。

#### HTML

```html
<canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas>
```

#### JavaScript

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

var ball = {
  x: 100,
  y: 100,
  vx: 5,
  vy: 2,
  radius: 25,
  color: "blue",
  draw: function () {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI \* 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  },
};

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ball.draw();
  ball.x += ball.vx;
  ball.y += ball.vy;

  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
    ball.vy = -ball.vy;
  }
  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
    ball.vx = -ball.vx;
  }

  raf = window.requestAnimationFrame(draw);
}

canvas.addEventListener("mouseover", function (e) {
  raf = window.requestAnimationFrame(draw);
});

canvas.addEventListener("mouseout", function (e) {
  window.cancelAnimationFrame(raf);
});

ball.draw();
```

#### 結果

キャンバスにマウスを移動するとアニメーションを開始します。

加速
--

動きをよりリアルにするために、例えばこんな風に移動量を変化させることができます。

```js
ball.vy \*= 0.99;
ball.vy += 0.25;
```

これにより、フレームごとに垂直方向の速度が遅くなり、最終的にボールは床の上でバウンドするだけになります。

### 第 2 のデモ

#### HTML

```html
<canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas>
```

#### JavaScript

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

var ball = {
  x: 100,
  y: 100,
  vx: 5,
  vy: 2,
  radius: 25,
  color: "blue",
  draw: function () {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI \* 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  },
};

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ball.draw();
  ball.x += ball.vx;
  ball.y += ball.vy;
  ball.vy \*= 0.99;
  ball.vy += 0.25;

  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
    ball.vy = -ball.vy;
  }
  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
    ball.vx = -ball.vx;
  }

  raf = window.requestAnimationFrame(draw);
}

canvas.addEventListener("mouseover", function (e) {
  raf = window.requestAnimationFrame(draw);
});

canvas.addEventListener("mouseout", function (e) {
  window.cancelAnimationFrame(raf);
});

ball.draw();
```

#### 結果

後引き効果
-----

これまで、前のフレームをクリアするときは `clearRect` メソッドを使用していました。このメソッドを半透明の `fillRect` に置き換えると、簡単に後引き効果を作ることができます。

```js
ctx.fillStyle = "rgba(255, 255, 255, 0.3)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
```

### 第 3 のデモ

#### HTML

```html
<canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas>
```

#### JavaScript

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

var ball = {
  x: 100,
  y: 100,
  vx: 5,
  vy: 2,
  radius: 25,
  color: "blue",
  draw: function () {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI \* 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  },
};

function draw() {
  ctx.fillStyle = "rgba(255, 255, 255, 0.3)";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ball.draw();
  ball.x += ball.vx;
  ball.y += ball.vy;
  ball.vy \*= 0.99;
  ball.vy += 0.25;

  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
    ball.vy = -ball.vy;
  }
  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
    ball.vx = -ball.vx;
  }

  raf = window.requestAnimationFrame(draw);
}

canvas.addEventListener("mouseover", function (e) {
  raf = window.requestAnimationFrame(draw);
});

canvas.addEventListener("mouseout", function (e) {
  window.cancelAnimationFrame(raf);
});

ball.draw();
```

#### 結果

マウス制御の追加
--------

ボールに対してちょっとした制御をするために、たとえば `mousemove` イベントを使用してボールにマウスを追いかけさせるようなことができます。`click` イベントでボールを解放して、またバウンドさせることもできます。

### 第 4 のデモ

#### HTML

```html
<canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas>
```

#### JavaScript

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

var ball = {
  x: 100,
  y: 100,
  vx: 5,
  vy: 1,
  radius: 25,
  color: "blue",
  draw: function () {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI \* 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  },
};

function clear() {
  ctx.fillStyle = "rgba(255, 255, 255, 0.3)";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
}

function draw() {
  clear();
  ball.draw();
  ball.x += ball.vx;
  ball.y += ball.vy;

  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
    ball.vy = -ball.vy;
  }
  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
    ball.vx = -ball.vx;
  }

  raf = window.requestAnimationFrame(draw);
}

canvas.addEventListener("mousemove", function (e) {
  if (!running) {
    clear();
    ball.x = e.clientX;
    ball.y = e.clientY;
    ball.draw();
  }
});

canvas.addEventListener("click", function (e) {
  if (!running) {
    raf = window.requestAnimationFrame(draw);
    running = true;
  }
});

canvas.addEventListener("mouseout", function (e) {
  window.cancelAnimationFrame(raf);
  running = false;
});

ball.draw();
```

#### 結果

マウスでボールを動かし、クリックでボールを放します。

ブロック崩し
------

この短い章では、より高度なアニメーションを作成するためのテクニックをいくつか説明するだけです。他にもたくさんあります。パドルやレンガを追加して、このデモを Breakout ゲームにするのはどうでしょうか？ゲーム開発エリアでは、ゲーム関連の記事を多数掲載しています。

関連情報
----

* `window.requestAnimationFrame()`
* ウェブゲームのための効率的なアニメーション (en-US)
* « 前のページ
* 次のページ »


キャンバスの基本的な使い方 - Web API

キャンバスの基本的な使い方
=============

* « 前のページ
* 次のページ »

このチュートリアルを、 `<canvas>` という HTML の要素を見てみることから始めましょう。このページの最後では、ブラウザーでキャンバス 2D コンテキストの設定し、最初の例を描画する方法を学びます。

`<canvas>` 要素
-------------

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

一見すると、 `<canvas>` は `<img>` 要素と似ていますが、 `src` 属性と `alt` 属性がない点が明確に異なります。一方、 `<canvas>` には `width` と `height` の 2 つの属性のみがあります。これらはどちらもオプションで、 DOM プロパティを用いて設定することもできます。を利用できます。 `width` 属性と `height` 属性が指定されていない場合、キャンバスは幅 **300 ピクセル**、高さ **150 ピクセル**で初期化されます。要素の大きさは CSS で変更できますが、画像を描画される際にはそのレイアウト上の大きさに合わせて拡縮されます。 CSS での大きさは初期のキャンバスの比率を考慮しないため、歪んで表示されることになります。

**メモ:** 画像が歪んでいると感じた時は、 CSS を使用するのではなく、 `width` および `height` 属性を `<canvas>` の属性に明示的に指定してください。

`id` は `<canvas>` 要素に固有の属性ではありませんが、HTML のグローバル属性の一つで、（`class` のように）すべての HTML 要素に適用することができます。常に `id` を設定するようにすると、スクリプトから要素を特定しやすくなります。

`<canvas>` 要素は通常の画像と同じようにスタイル付けすることができます（`margin`、`border`、`background` など）。しかし、これらのルールは、実際にキャンバス上に描画されるものには影響しません。これをどう扱うかについては、このチュートリアルの専用の章で紹介します。スタイルのルールが何も適用されていない場合、キャンバスは完全に透明なものとして描画されます。

### 代替コンテンツ

`<canvas>` 要素は `<img>` タグとは異なり、 `<video>`、`<audio>`、`<picture>` 要素のように、未対応の古いブラウザー（Internet Explorer 9 以前など）やテキストのブラウザーで表示される代替コンテンツを設定するのは簡単です。これらのブラウザーで表示される代替コンテンツを常に設定してください。

代替コンテンツを提供する方法はとても直観的です。代替コンテンツを `<canvas>` の中に入れるだけです。 `<canvas>` に対応していないブラウザーはこのコンテナーを無視し、内部の代替コンテンツを表示します。 `<canvas>` に対応しているブラウザーは、ふつうコンテナー内のコンテンツを無視し、通常通りキャンバスを描画します。

例えば、キャンバスの内容を説明するテキストを提供したり、動的に描画されるコンテンツの静的な画像を提供したりすることができます。次のようになります。

```html
<canvas id="stockGraph" width="150" height="150">
  現在の株価: $3.15 + 0.15
</canvas>

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

キャンバスに対応した別なブラウザーを使用するようにユーザーに指示することは、例えばキャンバスを見ることができないユーザーにとって助けになりません。有用な代替テキストやサブ DOM を提供することは、キャンバスのアクセシビリティを向上させます。

### `</canvas>` タグが必要

代替コンテンツを内部に持つ関係上、 `<img>` 要素と異なって `<canvas>` 要素は閉じタグ (`</canvas>`) が**必須**です。タグを閉じなかった場合は、残りのページ全てが代替コンテンツと見なされ、結果として表示されなくなります。

代替コンテンツが必要でない場合は、単に `<canvas id="foo" ...></canvas>` とすれば対応するブラウザーですべて利用することができます。

描画コンテキスト
--------

`<canvas>` は固定された大きさの描画可能領域を作成できます。この領域は、1 つ以上の**描画コンテキスト**として表現され、そのコンテキストを通じて描画領域を操作します。このチュートリアルでは、二次元グラフィックスを描画するためのコンテキストについてのみ解説しますが、これ以外の描画コンテキストも存在します。例えば WebGL は OpenGL ES に基づいて、三次元グラフィックを扱います。

初期状態ではキャンバスは空です。何かを表示するには、まずスクリプトで描画コンテキストを取得する必要があります。 `<canvas>` 要素には `getContext()` というメソッドがあり、描画コンテキストを取得したり描画機能を呼び出したりするのに使います。 `getContext()` には 1 つの引数があり、コンテキストの種類を指定します。このチュートリアルで扱っているような二次元のグラフィックでは、 `"2d"` を指定すると `CanvasRenderingContext2D` を取得することができます。

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

スクリプトの最初の行では、 DOM 内から `<canvas>` 要素を表すノードを取得するために `document.getElementById()` メソッドを呼び出しています。要素のノードを取得したら、 `getContext()` メソッドを使用して描画コンテキストにアクセスすることができます。

対応しているかどうかの確認
-------------

`<canvas>` 要素に対応していないブラウザーでは、代替コンテンツが表示されます。スクリプトからは、 `getContext()` メソッドの有無を調べることで、ブラウザーが対応しているかどうかを確認することができます。確認するためのコードは以下のようになります。

```js
var canvas = document.getElementById("tutorial");

if (canvas.getContext) {
  var ctx = canvas.getContext("2d");
  // 描画するコードをここに
} else {
  // キャンバスに未対応の場合のコードをここに
}
```

スケルトンテンプレート
-----------

ここでは、この後の例で開始点として使用する、最小限のテンプレートを紹介します。

**メモ:** スクリプトを HTML に埋め込むのは、よいやり方ではありません。この例では分かりやすさのために、仕方なく埋め込んでいます。

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

スクリプトには `draw()` という関数が含まれており、ページの読み込みが完了したときに一度実行されます。これは文書で `load` イベントを待ち受けすることで実現できます。この関数、または同様の関数は、`setTimeout()`、`setInterval()`、その他のイベントハンドラーを使用した場合でも、ページが最初に読み込まれたときに限り、呼び出すことができます。

ここでは、テンプレートが実際にどのように見えるかを説明します。このように、最初は白紙の状態です。

単純な描画
-----

まず始めに、交差する 2 つの矩形を描き、そのうちの 1 つにアルファ透過をさせる簡単な例を見てみましょう。これがどのように機能するかは、後の例でさらに詳しく見ていきましょう。

```html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <script type="application/javascript">
 function draw() {
 var canvas = document.getElementById("canvas");
 if (canvas.getContext) {
 var ctx = canvas.getContext("2d");

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

 ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
 ctx.fillRect(30, 30, 50, 50);
 }
 }
 </script>
  </head>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

この例は次のように動作します。

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

* « 前のページ
* 次のページ »


合成とクリッピング - Web API

合成とクリッピング
=========

* « 前のページ
* 次のページ »

これまでの例ではすべて、図形は、常に 1 つずつ重ねて描かれていました。これはほとんどの状況において十分すぎるほど適切ですが、複合図形の構築順序が制限されます。しかし、 `globalCompositeOperation` プロパティを設定することで、この動作を変更することができます。さらに、 `clip` プロパティによって、シェイプの不要な部分を隠すことができます。

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

既存の図形の背後に新しい図形を描画できるだけでなく、特定の領域をマスクしたり、キャンバスの一部を消去したり（`clearRect()` メソッドのように矩形に限定しない）、その他にも使用することが可能です。

`globalCompositeOperation = type`

これは、新しい図形を描くときに適用する合成処理の種類を設定します。 type は、 12 種類の合成処理から使用するものを特定する文字列です。

以下の例のコードについては、合成の例をご覧ください。

クリッピングパス
--------

クリッピングパスは通常のキャンバスの図形に似ていますが、図形の不要な部分を隠すマスクとして作用します。これを以下の画像で視覚化しました。赤い星型の図形は、クリッピングパスです。このパスの外側にあるものはすべて、キャンバスで描画されません。

![](/ja/docs/Web/API/Canvas_API/Tutorial/Compositing/canvas_clipping_path.png)

クリッピングパスと先ほどの `globalCompositeOperation` プロパティを比較すると、おおむね同じ効果をもたらす合成モードとして `source-in` と `source-atop` の 2 つがあることがわかります。これら 2 つとのもっとも重要な違いは、クリッピングパスは実際にキャンバスに描かれるものではないことと、クリッピングパスは新しい図形による影響を受けないことです。これは制限された領域に複数の図形を描くという、クリッピングパスの目標を表しています。

図形の描画の章では `stroke()` および `fill()` メソッドのみに言及しましたが、パスを扱う第 3 のメソッドとして `clip()` があります。

`clip()` (en-US)

現在構築しているパスを、現在のクリッピングパスに変換します。

`closePath()` の代わりに `clip()` を使用すると、パスの輪郭を描いたり塗りつぶすのではなく、パスを閉じてクリッピングパスに変換します。

既定で `<canvas>` 要素には、キャンバス自体とまったく同じ大きさのクリッピングパスが存在します。言い換えると、クリッピングは行われません。

### `clip` の例

この例では、ランダムな星の集団の描画先を特定の領域に制限するために、円形のクリッピングパスを使用しています。

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

  // 円形のクリッピングパスを作成
  ctx.beginPath();
  ctx.arc(0, 0, 60, 0, Math.PI \* 2, true);
  ctx.clip();

  // 背景を描く
  var lingrad = ctx.createLinearGradient(0, -75, 0, 75);
  lingrad.addColorStop(0, "#232256");
  lingrad.addColorStop(1, "#143778");

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

  // 星を描く
  for (var j = 1; j < 50; j++) {
    ctx.save();
    ctx.fillStyle = "#fff";
    ctx.translate(
      75 - Math.floor(Math.random() \* 150),
      75 - Math.floor(Math.random() \* 150),
    );
    drawStar(ctx, Math.floor(Math.random() \* 4) + 2);
    ctx.restore();
  }
}

function drawStar(ctx, r) {
  ctx.save();
  ctx.beginPath();
  ctx.moveTo(r, 0);
  for (var i = 0; i < 9; i++) {
    ctx.rotate(Math.PI / 5);
    if (i % 2 === 0) {
      ctx.lineTo((r / 0.525731) \* 0.200811, 0);
    } else {
      ctx.lineTo(r, 0);
    }
  }
  ctx.closePath();
  ctx.fill();
  ctx.restore();
}
```

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

```
draw();
```

コードの始めの数行で、背景としてキャンバスと同サイズの黒い背景を描いて、原点を中央に移動します。次に、円弧を描いて `clip()` を呼び出すことで、円形のクリッピングパスを作成します。クリッピングパスは、キャンバスの状態として保存されるもののひとつでもあります。元のクリッピングパスを維持したい場合は、新しいクリッピングパスを作成する前に保存したキャンバスの状態があるとよいでしょう。

クリッピングパスを作成した後に描いたものはすべて、パスの内部にあるものだけが見える状態になります。これは、次に描いている線形グラデーションで明らかです。この後に独自の `drawStar()` 関数を使用して、位置や大きさがランダムな星を 50 個描きます。星もまた、クリッピングパスの内部で定義されたものしか見えません。

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

* « 前のページ
* 次のページ »


画像の使用 - Web API

画像の使用
=====

* « 前のページ
* 次のページ »

これまで、図形を作成してスタイルを適用する方法を見てきました。 `<canvas>` のより面白い機能のひとつが、画像を扱えることです。これは動的な画像合成を行う、グラフの背景として使用する、ゲームのスプライトとして使用するなどといったことが可能です。 PNG、GIF、JPEG といった、ブラウザーが対応しているどの形式でも外部画像が使用できます。同じページ上の別のキャンバス要素によって生成された画像も、ソースとして使用できます。

基本的には 2 段階の手続きによって、画像をキャンバスにインポートします。

1. `HTMLImageElement` オブジェクトまたは別の canvas 要素への参照を、ソースとして取得します。URL を与えることでも、画像を使用できます。
2. `drawImage()` 関数を使用して、画像をキャンバスに描きます。

これを行う方法を見ていきましょう。

描く画像の取得
-------

キャンバス API は、以下のデータ形式を画像ソースとして使用できます。

`HTMLImageElement`

`<img>` 要素だけでなく、 `Image()` コンストラクターを使用して作成した画像も含みます。

`SVGImageElement` (en-US)

`<image>` 要素を使用して埋め込まれた画像です。

`HTMLVideoElement`

HTML の `<video>` 要素を画像ソースとして使用すると、現在のフレームを動画から取得して、画像として使用します。

`HTMLCanvasElement`

別の `<canvas>` 要素を画像ソースとして使用できます。

これらのソースは集約的に、`CanvasImageSource` (en-US) 型から参照されています。

キャンバスで使用する画像を取得する方法がいくつかあります。

### 同一ページ上の画像の使用

キャンバスと同じページにある画像への参照は、次のいずれかを使って取得することができます。

* `document.images` コレクション
* `document.getElementsByTagName()` メソッド
* 使用したい特定の画像の ID がわかる場合は、特定の画像を取得するために `document.getElementById()` を使用できます。
### ほかのドメインにある画像の使用

`crossorigin` 属性を`<img>` 要素に使用すると（`HTMLImageElement.crossOrigin` プロパティを反映）、`drawImage()` を呼び出してほかのドメインから画像を読み込む許可を求めることができます。ホスティングしているドメインが画像のドメイン間のアクセスを許可している場合は、キャンバスを汚染せずに画像を使用できます。そうでない場合は、画像を使用するとキャンバスを汚染します。

### ほかの canvas 要素の使用

通常の画像と同様に、`document.getElementsByTagName()` または `document.getElementById()` メソッドを使用してほかの canvas 要素にアクセスできます。対象のキャンバスを使用する前に、そのキャンバスで描画を終えるようにしてください。

より実用的な使い方としては、 2 つ目の canvas 要素を、他の大きなキャンバスのサムネイル表示として使用することでしょう。

### 最初から画像を作成

もうひとつの方法は、スクリプト内で新たな `HTMLImageElement` オブジェクトを作成することです。そのために、便利な `Image()` コンストラクターを使用することができます。

```js
var img = new Image(); // 新たな img 要素を作成
img.src = "myImage.png"; // ソースのパスを設定
```

このスクリプトを実行すると、画像の読み込みが始まります。

画像の読み込みが完了する前に `drawImage()` を呼び出しても、何も行いません（あるいは、古いブラウザーでは例外が発生するかもしれません）。よって画像を読み込む前に描画しないようにするために、load イベントを使用する必要があります。

```js
var img = new Image(); // 新たな img 要素を作成
img.addEventListener(
  "load",
  function () {
    // drawImage を実行する文をここに置く
  },
  false,
);
img.src = "myImage.png"; // ソースのパスを設定
```

外部画像を 1 つだけ使用するのであれば、これは良い方法ですが、 2 つ以上を追跡する必要がある場合は、もっと賢い方法に頼る必要があります。画像の先読み方法については、このチュートリアルの範囲外ですが、覚えておくとよいでしょう。

### data: URL で画像を埋め込む

画像を埋め込む別の方法が、data: URL です。 data URL によって、画像を Base64 でエンコードした文字列として、コード内で完全に定義できます。

```js
var img = new Image(); // 新たな img 要素を作成
img.src =
  "data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==";
```

data URL の利点のひとつが、別にサーバとの通信を行うことなく即座に結果の画像を使用できることです。ほかに潜在的な利点として CSS、JavaScript、HTML、画像をひとつのファイルにカプセル化することもでき、ほかの場所へ持ち運びやすくなります。

この方法の欠点は画像がキャッシュされないことと、大きな画像をエンコードした URL がとても長くなることです。

### 動画のフレームの使用

`<video>` 要素が提供する動画のフレームも（動画が非表示であっても）使用できます。例えば ID が "myvideo" である `<video>` 要素があるとき、以下のようなことができます。

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

    return document.getElementById("myvideo");
  }
}
```

これは動画の `HTMLVideoElement` オブジェクトを返します。このオブジェクトは先に述べたとおり、`CanvasImageSource` として使用できるオブジェクトのひとつです。

画像の描画
-----

ソース画像オブジェクトへの参照を取得したら、 `drawImage()` メソッドを使用して画像をキャンバスに描画できます。後ほど見るように、 `drawImage()` メソッドをオーバーロードした派生形がいくつかあります。もっとも基本的な形式は以下のようなものです。

`drawImage(image, x, y)`

引数 `image` で指定した `CanvasImageSource` を、座標 (`x`, `y`) に描画します。

**メモ:** SVG 画像は、ルート <svg> 要素で幅と高さを指定しなければなりません。

### 例: シンプルな折れ線グラフ

以下の例は、小さな折れ線グラフの背景として外部の画像を使用しています。背景画像を使用すると背景を生成するコードが不要になりますので、スクリプトをかなり小さくすることができます。この例では画像を 1 つしか使用しませんので、描画する文を実行するために画像オブジェクトの `load` イベントハンドラを使用しています。`drawImage()` メソッドは背景画像を座標 (0, 0) に配置します。これはキャンバスの左上の隅です。
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="180" height="150"></canvas>
  </body>
</html>
```

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  var img = new Image();
  img.onload = function () {
    ctx.drawImage(img, 0, 0);
    ctx.beginPath();
    ctx.moveTo(30, 96);
    ctx.lineTo(70, 66);
    ctx.lineTo(103, 76);
    ctx.lineTo(170, 15);
    ctx.stroke();
  };
  img.src = "backdrop.png";
}
```

結果のグラフは以下のようになります。

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

拡大縮小
----

`drawImage()` メソッドの第 2 の形式は引数が 2 つ追加されており、キャンバスに拡大・縮小した画像を配置することができます。

`drawImage(image, x, y, width, height)`

これは引数 `width` および `height` を追加しており、画像をキャンバスに描画する際のサイズを示します。

### 例: 画像をタイル配置

以下の例は画像を壁紙として使用して、キャンバス上で数回繰り返して貼り付けています。ループ処理によって、さまざまな場所に縮小した画像を貼り付けました。以下のコードでは、最初の `for` ループで行の繰り返し処理を行います。2 番目の `for` ループで列の繰り返し処理を行います。画像は元のサイズの 3 分の 1 である、 50x38 ピクセルに縮小しています。

**メモ:** 画像を拡大しすぎると不鮮明に、あるいは縮小しすぎると荒くなります。読みやすくしておかなければならない文字列が画像内にある場合は、サイズを変更しないほうがよいでしょう。
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  var img = new Image();
  img.onload = function () {
    for (var i = 0; i < 4; i++) {
      for (var j = 0; j < 3; j++) {
        ctx.drawImage(img, j \* 50, i \* 38, 50, 38);
      }
    }
  };
  img.src = "rhino.jpg";
}
```

キャンバスの結果は以下のようになります。

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

切り抜き
----

`drawImage()` メソッドの第 3 かつ最後の形式は、画像ソースについて 8 個の引数が追加されています。これはソース画像の一部を切り抜いて、サイズ変更およびキャンバスへの描画を行います。

`drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)`

この関数は、`image` から左上の隅が (`sx`, `sy`)、幅と高さが `sWidth` および `sHeight` である矩形で指定されるソース画像の領域を取得して、キャンバスの (`dx`, `dy`) で示した位置に配置して、`dWidth` および `dHeight` で指定したサイズに拡大縮小します。

何を行っているかを正しく理解するために、この画像を見ると役に立つかもしれません。

![](/ja/docs/Web/API/Canvas_API/Tutorial/Using_images/canvas_drawimage.jpg)

始めの 4 つの引数は、ソース画像を切り抜く場所とサイズを定義します。最後の 4 つの引数は、描画先キャンバスで画像を描画する矩形を定義します。

切り抜きは、画像を合成する際に役に立つでしょう。ひとつの画像ファイルにすべての要素を置いておき、このメソッドを使用して完成形の描画結果に合成します。例えばグラフを作成したいときに、すべての必要なテキストをひとつのファイルに収めた PNG 画像を用意して、データに応じてグラフの目盛りをとても簡単に変更できるでしょう。ほかの利点として、すべての画像を個別に読み込む必要がありませんので、読み込みパフォーマンスが向上するでしょう。

### 例: 画像をフレームに収める

以下の例では前の例と同じサイの画像を使用していますが、頭の部分を切り抜いて額縁の中に合成しています。額縁の画像は、ドロップシャドウを含む 24 ビット PNG 画像です。GIF や 8 ビット PNG 画像と異なり、24 ビット PNG 画像は 8 ビットのアルファチャンネルが含まれていますので、マットカラーに悩まされることなく背景に重ねることができます。

```html
<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
    <div style="display:none;">
      <img id="source" src="rhino.jpg" width="300" height="227" />
      <img id="frame" src="canvas\_picture\_frame.png" width="132" height="150" />
    </div>
  </body>
</html>
```

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

  // スライス画像を描く
  ctx.drawImage(
    document.getElementById("source"),
    33,
    71,
    104,
    124,
    21,
    20,
    87,
    104,
  );

  // フレームを描く
  ctx.drawImage(document.getElementById("frame"), 0, 0);
}
```

この例では、画像の読み込みに別の方法を使用しています。新しい `HTMLImageElement` オブジェクトを作成して画像を読み込む代わりに、画像を HTML ソース内の `<img>` タグとして直接含めておき、そこから画像を取り込んでいます。この画像は、CSS の `display` プロパティを none に設定して隠しています。

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

スクリプト自体はとてもシンプルです。それぞれの `<img>` に ID 属性を割り当てており、`document.getElementById()` を使用して簡単に選択できます。最初の画像からサイを切り抜いて canvas 上でサイズを調整するため単純に `drawImage()` を使用して、その後に第 2 の `drawImage()` を呼び出して枠を描きます。

アートギャラリーの例
----------

この章の最後の例では、小さなアートギャラリーを作ります。いくつかの画像を持つテーブルで、ギャラリーを構成します。ページを読み込むとそれぞれの画像のために `<canvas>` 要素を挿入して、そこに画像と額縁を描画します。

この場合、すべてのイメージの幅と高さは固定で、その周りに描かれるフレームも固定です。このスクリプトを改良して、画像の幅と高さを利用して、額縁が画像の周りにぴったりと収まるようにすることができます。

以下のコードは自明でしょう。`document.images` コンテナーに対するループ処理を行って、適宜新たな canvas 要素を追加します。おそらく、 DOM についてあまり詳しくない場合に注意したほうがよいことは、`Node.insertBefore` メソッドを使用していることです。`insertBefore()` は、ある要素 (image) の前に新たな要素 (canvas 要素) を挿入したいときに使用する、親ノード (テーブルのセル) のメソッドです。

```html
<html>
  <body onload="draw();">
    <table>
      <tr>
        <td><img src="gallery\_1.jpg" /></td>
        <td><img src="gallery\_2.jpg" /></td>
        <td><img src="gallery\_3.jpg" /></td>
        <td><img src="gallery\_4.jpg" /></td>
      </tr>
      <tr>
        <td><img src="gallery\_5.jpg" /></td>
        <td><img src="gallery\_6.jpg" /></td>
        <td><img src="gallery\_7.jpg" /></td>
        <td><img src="gallery\_8.jpg" /></td>
      </tr>
    </table>
    <img id="frame" src="canvas\_picture\_frame.png" width="132" height="150" />
  </body>
</html>
```

こちらが、見栄えをよくするための CSS です:

```css
body {
  background: 0 -100px repeat-x url(bg\_gallery.png) #4f191a;
  margin: 10px;
}

img {
  display: none;
}

table {
  margin: 0 auto;
}

td {
  padding: 15px;
}
```

額縁付き画像を描く JavaScript が、すべてを結びつけます。

```js
function draw() {
  // すべての画像に対するループ処理
  for (var i = 0; i < document.images.length; i++) {
    // 額縁の画像用の canvas は追加しない
    if (document.images[i].getAttribute("id") != "frame") {
      // canvas 要素を作成
      canvas = document.createElement("canvas");
      canvas.setAttribute("width", 132);
      canvas.setAttribute("height", 150);

      // 画像の前に挿入
      document.images[i].parentNode.insertBefore(canvas, document.images[i]);

      ctx = canvas.getContext("2d");

      // canvas に画像を描く
      ctx.drawImage(document.images[i], 15, 20);

      // 額縁を追加
      ctx.drawImage(document.getElementById("frame"), 0, 0);
    }
  }
}
```

画像のサイズ変更の動作の制御
--------------

先に述べたとおり、サイズを変更した画像は変更処理の影響で、不鮮明またはブロック状のアーティファクトが発生します。描画コンテキスト内で画像のサイズを変更する際に使用する画像スムージングアルゴリズムを制御するために、描画コンテキストの `imageSmoothingEnabled` プロパティを使用できます。既定ではこれが `true` であり、画像のサイズを変更する際にスムージングを行います。以下のように、この機能は無効化できます。

```js
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
```

* « 前のページ
* 次のページ »