スタイルと色の適用 - Web API

スタイルと色の適用
=========

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

図形の描画についての章では、既定の線と塗りつぶしのスタイルのみを使用しました。ここでは、私たちの絵を少しでも魅力的にするために、自由に使えるキャンバスのオプションについて探っていきます。色、線のスタイル、グラデーション、パターン、影を追加する方法を学びます。

色
-

今までは、描画コンテキストのメソッドだけを見てきました。もし、図形に色をつけたいのであれば、 2 つの重要なプロパティを使用することができます。 `fillStyle` と `strokeStyle` です。

`fillStyle = color`

図形を塗りつぶす際に使用するスタイルを設定します。

`strokeStyle = color`

図形の輪郭のスタイルを設定します。

`color` は文字列で、 CSS の `<color>` やグラデーションオブジェクト、パターンオブジェクトを表します。グラデーションオブジェクトとパターンオブジェクトについては後で見ます。既定では、輪郭線と塗りつぶしの色は黒に設定されています（CSS 色では`#000000`）。

**メモ:** `strokeStyle` および `fillStyle` プロパティを設定すると、その設定した値が既定となって、それ以降に描かれる図形の線や塗りつぶしはその色で行なわれるようになります。それぞれの図形をそれぞれ別の色で描きたい場合は、図形を描くごとに `fillStyle` や `strokeStyle` プロパティを設定する必要があります。

入力できる有効な文字列は、 CSS の `<color>` 値である必要があります。 下記の例では同じ色について説明しています。

```js
// これらは全て fillStyle にオレンジ色を設定します

ctx.fillStyle = "orange";
ctx.fillStyle = "#FFA500";
ctx.fillStyle = "rgb(255, 165, 0)";
ctx.fillStyle = "rgba(255, 165, 0, 1)";
```

### `fillStyle` の例

この例では、再び 2 つの `for` ループを使って、それぞれ異なる色の矩形を格子状に描画しています。出来上がった画像はスクリーンショットのようなものになるはずです。ここでは、あまり派手なことはしていません。 2 つの変数 `i` と `j` を使ってそれぞれの正方形に固有の RGB カラーを生成し、赤と緑の値だけを変更します。青チャンネルは固定値です。チャンネルを変更することで、あらゆる種類のパレットを生成することができます。ステップを増やせば、 Photoshop が使っているカラーパレットに近いものを実現することも可能です。

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

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

```
draw();
```

結果は次のようになります。

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

### `strokeStyle` の例

この例は上の例と似ていますが、 `strokeStyle` プロパティを使って、図形の輪郭の色を変えています。また、 `arc()` メソッドを使って、四角形の代わりに円を描いています。

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  for (var i = 0; i < 6; i++) {
    for (var j = 0; j < 6; j++) {
      ctx.strokeStyle =
        "rgb(0, " +
        Math.floor(255 - 42.5 \* i) +
        ", " +
        Math.floor(255 - 42.5 \* j) +
        ")";
      ctx.beginPath();
      ctx.arc(12.5 + j \* 25, 12.5 + i \* 25, 10, 0, Math.PI \* 2, true);
      ctx.stroke();
    }
  }
}
```

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

```
draw();
```

結果は次のようになります。

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

透明度
---

キャンバスには不透明な図形を描くだけではなく、半透明の図形を描くこともできます。これは、 `globalAlpha` プロパティを設定するか、輪郭や塗りつぶしのスタイルに半透明の色を割り当てることで実現します。

`globalAlpha = transparencyValue`

代入された透明度の値を、代入後にキャンバスに描画されるすべての図形に適用します。値は 0.0 （完全に透明）から 1.0 （完全に不透明）の間でなければなりません。既定では 1.0 （完全に不透明）が設定されています。

`globalAlpha` プロパティは、同様の透明度でキャンバスにいくつもの図形を描画する場合に役に立ちますが、それ以外の場合は、色を設定するときにそれぞれの図形に透明度を設定する方が一般的に便利です。

`strokeStyle` プロパティと `fillStyle` プロパティは CSS の rgba 表現を利用できるため、次のような表記を使用して透明な色を割り当てることもできます。

```js
// 輪郭線と塗りつぶしの色に透明色を割り当てる

ctx.strokeStyle = "rgba(255, 0, 0, 0.5)";
ctx.fillStyle = "rgba(255, 0, 0, 0.5)";
```

`rgba()` 関数は `rgb()` 関数によく似ていますが、 1 つ引数が増えます。最後の引数には、この色の透明度の値を設定します。有効な値の範囲は、 0.0 （完全に透明）から 1.0 （完全に不透明）です。

### `globalAlpha` の例

この例では、 4 つの異なる色の正方形で背景を描きます。その上に、一連の半透明の円を描きます。このとき、 `globalAlpha` プロパティは `0.2` に設定され、これ以降すべての図形に使用されます。 `for` ループのそれぞれのステップでは、半径の大きな円を描画します。最終的な結果は放射状のグラデーションになります。より多くの円を重ねることで、すでに描かれている円の透明度を効果的に下げています。ステップ数を増やし、より多くの円を描くと、画像の中心から背景が完全に消えます。

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  // draw background
  ctx.fillStyle = "#FD0";
  ctx.fillRect(0, 0, 75, 75);
  ctx.fillStyle = "#6C0";
  ctx.fillRect(75, 0, 75, 75);
  ctx.fillStyle = "#09F";
  ctx.fillRect(0, 75, 75, 75);
  ctx.fillStyle = "#F30";
  ctx.fillRect(75, 75, 75, 75);
  ctx.fillStyle = "#FFF";

  // set transparency value
  ctx.globalAlpha = 0.2;

  // Draw semi transparent circles
  for (var i = 0; i < 7; i++) {
    ctx.beginPath();
    ctx.arc(75, 75, 10 + 10 \* i, 0, Math.PI \* 2, true);
    ctx.fill();
  }
}
```

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

```
draw();
```

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

### `rgba()` の使用例

この 2 つ目の例では、上の例と似たようなことをしていますが、円を重ねて描くのではなく、小さな長方形を不透明度を上げながら描いています。 `rgba()` を使うと、塗りつぶしと輪郭線のスタイルを個別に設定できるので、もう少し制御と柔軟性が増します。

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

  // Draw background
  ctx.fillStyle = "rgb(255, 221, 0)";
  ctx.fillRect(0, 0, 150, 37.5);
  ctx.fillStyle = "rgb(102, 204, 0)";
  ctx.fillRect(0, 37.5, 150, 37.5);
  ctx.fillStyle = "rgb(0, 153, 255)";
  ctx.fillRect(0, 75, 150, 37.5);
  ctx.fillStyle = "rgb(255, 51, 0)";
  ctx.fillRect(0, 112.5, 150, 37.5);

  // Draw semi transparent rectangles
  for (var i = 0; i < 10; i++) {
    ctx.fillStyle = "rgba(255, 255, 255, " + (i + 1) / 10 + ")";
    for (var j = 0; j < 4; j++) {
      ctx.fillRect(5 + i \* 14, 5 + j \* 37.5, 14, 27.5);
    }
  }
}
```

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

```
draw();
```

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

線のスタイル
------

線のスタイル付けを可能にするプロパティがいくつかあります。

`lineWidth = value` (en-US)

これから描かれる線の幅を設定します。

`lineCap = type`

線の末端の外観を設定します。

`lineJoin = type` (en-US)

線と線が交わる「角」の外観を設定します。

`miterLimit = value` (en-US)

2 本の線が鋭角に接合する際のマイターを制限し、接合部の太さを制御することができます。

`getLineDash()` (en-US)

非負の偶数個を含む現在の線ダッシュのパターンの配列を返します。

`setLineDash(segments)`

現在の線ダッシュパターンを設定します。

`lineDashOffset = value` (en-US)

ダッシュ配列の行頭位置を指定します。

以下の例をご覧いただくと、これらが何をするものなのか、より理解していただけると思います。

### `lineWidth` の例

このプロパティは、現在の線の太さを設定します。値は正の数でなければなりません。既定では、この値は 1.0 単位に設定されています。

線の幅は、与えられたパスを中心としたストロークの太さです。言い換えれば、描画される領域はパスの両側で線幅の半分まで広がります。キャンバスの座標はピクセルを直接参照するわけではないので、水平・垂直方向の線が鮮明になるように特別な注意を払う必要があります。

下の例では、 10 本の直線を線幅を大きくして描いています。一番左の線の幅は 1.0 単位です。しかし、一番左の線とその他の奇数幅の太い線は、パスの位置の関係で鮮明に表示されません。

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  for (var i = 0; i < 10; i++) {
    ctx.lineWidth = 1 + i;
    ctx.beginPath();
    ctx.moveTo(5 + i \* 14, 5);
    ctx.lineTo(5 + i \* 14, 140);
    ctx.stroke();
  }
}
```

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

```
draw();
```

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

鮮明な線を得るには、パスがどのように描かれるかを理解する必要があります。下の画像で、グリッドはキャンバスの座標グリッドを表しています。グリッド線とグリッド線の間の矩形は、画面上の実際のピクセルです。下の最初のグリッド画像では、 (2,1) から (5,5) までの矩形が塗りつぶされています。その間の領域（薄赤色）はすべてピクセルの境界線に当たるので、塗りつぶされた矩形は鮮明なエッジを持つことになります。

![](/ja/docs/Web/API/Canvas_API/Tutorial/Applying_styles_and_colors/canvas-grid.png)

(3,1) から (3,5) までのパスを線の太さを `1.0` にして考えてみると、 2 番目の画像のような状況になります。実際に塗りつぶされる領域（濃い青色）は、パスの両側のピクセルの半分までしか届きません。この近似値をレンダリングしなければならないので、これらのピクセルは部分的にしかシェーディングされず、その結果、領域全体（水色と濃紺）が実際のストローク色の半分の濃さでしか塗りつぶされないことになります。これは、前の例のコードで `1.0` の幅の行で起こることです。

これを解決するには、パスの作成を非常に正確に行う必要があります。 `1.0` の幅の線はパスの両側へ半単位伸びることを知っていて、パスを (3.5,1) から (3.5,5) まで作成すると、 3 番目の画像のような状況になります。 `1.0` の線幅は完全に、正確に 1 ピクセルの縦線を埋めることになります。

**メモ:** 縦線の例では、 Y 位置はまだ整数のグリッド線位置を参照していることに注意してください。もしそうでなければ、端点で半分しかカバーしていないピクセルが見えるでしょう（ただし、この動作は、既定値が `butt` である現在の `lineCap` スタイルに依存していることにも注意してください。奇数幅の線に対して半ピクセル座標で一貫したストロークを計算するには、 `lineCap` スタイルを `square` にして、端点周りのストロークの外枠が自動的にピクセル全体を正確に覆うまで拡張します）。

また、パスの始点と終点のみが影響を受けることに注意してください。パスが `closePath()` で閉じられると、始点と終点がなくなります。その代わりに、パスのすべての端点は、現在の `lineJoin` スタイルの設定（既定値は `miter`）を使用して、接続された区間の外側の境界線をそれらの交点まで自動的に拡張する効果があり、レンダリングストロークは、接続された区間が水平または垂直である場合にそれぞれの端点を中心としたピクセル全体を正確に覆うようになります。これらの追加ラインスタイルのデモについては、次の 2 つのセクションを参照してください。

偶数幅の線は、それぞれの半分が整数のピクセルになるので、ピクセルの真ん中ではなく、ピクセルとピクセルの間（つまり (3,1) から (3,5)）にパスを設定する必要があります。

拡大縮小可能な二次元グラフィックを扱う最初のうちは少し面倒ですが、ピクセルグリッドとパスの位置に注意することで、拡大状況やその他の座標変換に関係なく、描画を正しく表示することができます。正しい位置に描かれた幅 1.0 の縦線は、 2 倍に拡大すると 2 ピクセルの鮮明な線となり、正しい位置に表示されます。

### `lineCap` の例

`lineCap` プロパティは、すべての線の端点がどのように描かれるかを決定します。このプロパティには3つの値があり、それらは `butt`, `round`, `quare` です。既定では、このプロパティは `butt` に設定されています。

`butt`

線の両端は、末尾の点で四角く切り落とされます。

`round`

線の両端は丸められます。

`square`

線の両端は、線の太さと同じ幅と半分の高さのボックスを追加して四角くされます。

この例では、 3 本の線を描きます。それぞれの線は `lineCap` プロパティの値が異なっています。また、 3 つの正確な違いを見るために、 2 つのガイドを追加しました。それぞれの線は、これらのガイドの上で正確に始まり、終わります。

左側の線は、既定の `butt` オプションを使用しています。ガイドと完全に同じ高さに描かれているのがわかると思います。 2 番目の線は `round` オプションを使うように設定されています。これは線の幅の半分の半径を持つ半円を端に追加します。右の線は `square` オプションを使用しています。これは線の太さと同じ幅と半分の高さのボックスを追加します。

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  var lineCap = ["butt", "round", "square"];

  // ガイドを描画
  ctx.strokeStyle = "#09f";
  ctx.beginPath();
  ctx.moveTo(10, 10);
  ctx.lineTo(140, 10);
  ctx.moveTo(10, 140);
  ctx.lineTo(140, 140);
  ctx.stroke();

  // 線を描画
  ctx.strokeStyle = "black";
  for (var i = 0; i < lineCap.length; i++) {
    ctx.lineWidth = 15;
    ctx.lineCap = lineCap[i];
    ctx.beginPath();
    ctx.moveTo(25 + i \* 50, 10);
    ctx.lineTo(25 + i \* 50, 140);
    ctx.stroke();
  }
}
```

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

```
draw();
```

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

### `lineJoin` の例

`lineJoin` プロパティは、形状内の長さがゼロでない 2 つの接続された区間（直線、円弧、曲線）をどのように結合するかを決定します（長さがゼロで、指定した端点と制御点が正確に同じ位置にある区間はスキップされます）。

このプロパティには、 3 つの値があります。このプロパティには、 `round`, `bevel`, `miter` の 3 つの値があります。既定では、このプロパティは `miter` に設定されています。なお、`lineJoin` の設定は、接続された 2 つの区間の方向が同じである場合には、接合領域が追加されないため、何の効果もありません。

`round`

接続された区間の共通の端点を中心とする円盤の追加セクターを埋めることによって、形状の角を丸くします。この丸められた角の半径は、線幅の半分に等しくなります。

`bevel`

接続された区間の共通の端点と、各区間にある個別の外側の長方形の角との間の三角形の領域を追加で埋めます。

`miter`

接続された区間は、外側のエッジを延長して 1 点で接続され、追加のロゼンジ形状の領域を埋める効果があります。この設定は、以下に説明する `miterLimit` プロパティによって影響されます。

以下の例では、これら3つの `lineJoin` プロパティ設定をそれぞれ実演しながら、 3 つの異なるパスを描画しています。

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  var lineJoin = ["round", "bevel", "miter"];
  ctx.lineWidth = 10;
  for (var i = 0; i < lineJoin.length; i++) {
    ctx.lineJoin = lineJoin[i];
    ctx.beginPath();
    ctx.moveTo(-5, 5 + i \* 40);
    ctx.lineTo(35, 45 + i \* 40);
    ctx.lineTo(75, 5 + i \* 40);
    ctx.lineTo(115, 45 + i \* 40);
    ctx.lineTo(155, 5 + i \* 40);
    ctx.stroke();
  }
}
```

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

```
draw();
```

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

### `miterLimit` プロパティのデモ

前の例で見たように、 `miter` オプションを使って 2 本の線をつなぐと、2 本の線の外側の端は、それらが出会う点まで延長されます。互いに大きな角度を持つ線の場合、この点は内側の接続点からそう遠くないところにあります。しかし、各ライン間の角度が小さくなるにつれて、これらのポイント間の距離（マイター長）は指数関数的に増加します。

`miterLimit` プロパティは、内側の接続点から外側の接続点をどれだけ遠くに配置できるかを決定します。もし、 2 本の線がこの値を超えた場合、代わりにベベルジョイントが描かれます。最大マイター長は、現在の座標系で測定された線の幅と、この `miterLimit` プロパティの値（既定値は HTML の `<canvas>` の 10.0）の積であることに注意してください。したがって `miterLimit` は現在の表示スケールやパスのアフィン変換とは独立して設定できます。それは、線の端の効果的なレンダリングの形状にのみ影響するものです。

より正確には、マイター制限とは、線幅の半分に対する延長長さ（HTML キャンバスでは、線の接続端の外側の角と、パスで指定した接続セグメントの共通の端点の間で測ります）の最大許容比率のことです。これは同様に、線幅全体に対する、辺の接合部の内側と外側の点間の距離の最大許容比率と定義することもできます。これは、接続セグメントの最小内角の半分の正接に等しく、それ以下ではマイター結合は描画されず、ベベル結合のみが描画されます。

* `miterLimit` = **max** `miterLength` / `lineWidth` = 1 / **sin** ( **min** *θ* / 2 )
* 既定のマイター制限 10.0 は、約 11 度以下の鋭角のマイターをすべて解除します。
* マイター制限を √2 ≈ 1.4142136（切り上げ）とすると、すべての鋭角に対してマイターを剥がし、鈍角または直角に対してのみマイター結合を維持することができます。
* マイター制限を 1.0 に設定すると有効ですが、すべてのマイターが無効になります。
* 1.0 以下の値はマイター制限では無効です。

ここでは、 `miterLimit` を動的に設定し、それがキャンバス上の図形にどのように影響するかを見るための小さなデモを紹介します。青い線は、ジグザグ模様の各線の始点と終点を示しています。

もし `miterLimit` の値を 4 以下で指定した場合。 10 以上の `miterLimit` を指定すると、このデモのほとんどのコーナーは青い線から遠く離れたところでマイターで結合し、左から右へ角度を大きくして接続するため、コーナーの高さが減少するはずです。中間の値では、左側のコーナーは青い線の近くでベベルで結合し、右側のコーナーはマイターを延長（これも高さが減少する）するだけです。

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

  // キャンバスを消去
  ctx.clearRect(0, 0, 150, 150);

  // ガイドを描画
  ctx.strokeStyle = "#09f";
  ctx.lineWidth = 2;
  ctx.strokeRect(-5, 50, 160, 50);

  // 線のスタイルを設定
  ctx.strokeStyle = "#000";
  ctx.lineWidth = 10;

  // 入力をチェック
  if (document.getElementById("miterLimit").value.match(/\d+(\.\d+)?/)) {
    ctx.miterLimit = parseFloat(document.getElementById("miterLimit").value);
  } else {
    alert("Value must be a positive number");
  }

  // 線を描画
  ctx.beginPath();
  ctx.moveTo(0, 100);
  for (i = 0; i < 24; i++) {
    var dy = i % 2 == 0 ? 25 : -25;
    ctx.lineTo(Math.pow(i, 1.5) \* 2, 75 + dy);
  }
  ctx.stroke();
  return false;
}
```

```
<table>
  <tr>
    <td><canvas id="canvas" width="150" height="150"></canvas></td>
    <td>
      <code>miterLimit</code>
      を変更するには、下に新しい値を入力し、再描画ボタンをクリックしてください。<br /><br />
      <form onsubmit="return draw();">
        <label>マイター制限</label>
        <input type="number" size="3" id="miterLimit" />
        <input type="submit" value="Redraw" />
      </form>
    </td>
  </tr>
</table>
```

```
document.getElementById("miterLimit").value = document
  .getElementById("canvas")
  .getContext("2d").miterLimit;
draw();
```

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

### 線ダッシュの使用

`setLineDash` メソッドと `lineDashOffset` プロパティは直線のダッシュパターンを指定します。`setLineDash` メソッドは、線と隙間を交互に描く距離を指定する数値のリストを受け取り、`lineDashOffset` プロパティはパターンを開始するオフセットを設定します。

この例では、蟻の行進のような効果を作成しています。これは、コンピュータグラフィックスプログラムの選択ツールでよく見られるアニメーション技術です。境界線をアニメーション化することで、ユーザーが画像の背景と選択範囲の境界線を区別するのに役立ちます。このチュートリアルの後半では、この方法とその他の基本的なアニメーションを行う方法を学習することができます。
```

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

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

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.setLineDash([4, 2]);
  ctx.lineDashOffset = -offset;
  ctx.strokeRect(10, 10, 100, 100);
}

function march() {
  offset++;
  if (offset > 16) {
    offset = 0;
  }
  draw();
  setTimeout(march, 20);
}

march();
```

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

グラデーション
-------

通常の描画プログラムと同様に、線形、放射、扇形グラデーションを用いて図形を塗りつぶしたり描画したりすることができます。以下のメソッドのいずれかを使用して `CanvasGradient` オブジェクトを作成します。そして、このオブジェクトを `fillStyle` または `strokeStyle` プロパティに代入することができます。

`createLinearGradient(x1, y1, x2, y2)` (en-US)

線形グラデーションオブジェクトを、 (`x1`, `y1`) の点から始まり (`x2`, `y2`) の点から終える位置に生成します。

`createRadialGradient(x1, y1, r1, x2, y2, r2)` (en-US)

放射グラデーションを生成します。引数は 2 つの円を表します。一つは (`x1`, `y1`) が中心で `r1` が半径、もう一つは (`x2`, `y2`) が中心で `r2` が半径です。

`createConicGradient(angle, x, y)` (en-US)

扇形グラデーションオブジェクトを、ラジアンの開始角 `angle`、位置を (`x`, `y`) で生成します。

例を示します。

```js
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100);
```

`CanvasGradient` オブジェクトを作成したら、 `addColorStop()` メソッドを使って色を割り当てることができます。

`gradient.addColorStop(position, color)` (en-US)

`gradient` オブジェクトに新しい色経由点を作成します。また、 `color` 引数は CSS の `<color>` を表す文字列である必要があり、グラデーションがそのオフセットで到達すべき色を表します。

グラデーションには、必要なだけ色経由点を追加することができます。以下は、白から黒へ非常にシンプルな線形グラデーションです。

```js
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
lineargradient.addColorStop(0, "white");
lineargradient.addColorStop(1, "black");
```

### `createLinearGradient` の例

この例では、 2 つの異なるグラデーションを作成します。ここでわかるように、 `strokeStyle` と `fillStyle` の両プロパティは `canvasGradient` オブジェクトを有効な入力として受け入れることができます。

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

  // グラデーションを生成
  var lingrad = ctx.createLinearGradient(0, 0, 0, 150);
  lingrad.addColorStop(0, "#00ABEB");
  lingrad.addColorStop(0.5, "#fff");
  lingrad.addColorStop(0.5, "#26C000");
  lingrad.addColorStop(1, "#fff");

  var lingrad2 = ctx.createLinearGradient(0, 50, 0, 95);
  lingrad2.addColorStop(0.5, "#000");
  lingrad2.addColorStop(1, "rgba(0, 0, 0, 0)");

  // グラデーションに塗りつぶしと輪郭のスタイルを割り当てる
  ctx.fillStyle = lingrad;
  ctx.strokeStyle = lingrad2;

  // 図形を描画
  ctx.fillRect(10, 10, 130, 130);
  ctx.strokeRect(50, 50, 50, 50);
}
```

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

```
draw();
```

1 つ目は、背景のグラデーションです。ご覧のように、同じ位置に 2 つの色を割り当てています。これは、非常にシャープな色の遷移を行うためで、この場合は白から緑への遷移です。通常は、色経由点をどのような順番で定義しても問題ありませんが、この特殊なケースでは、それが大きな意味を持ちます。表示させたい順番に割り当てておけば、問題にはなりません。

2 つ目のグラデーションでは、開始色（位置 0.0）を割り当てませんでした。なぜなら、次の色経由点の色を自動的に仮定するため、厳密には必要ないからです。したがって、位置 0.5 に黒を割り当てると、グラデーションの開始からこの停止位置までが自動的に黒になります。

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

### `createRadialGradient` の例

この例では、 4 つの異なる放射状グラデーションを定義します。グラデーションの開始点と終了点を制御できるので、 Photoshop などで見られる「古典的な」放射グラデーション（つまり、グラデーションが円形に広がる 1 つの中心点を持つグラデーション）よりも複雑な効果を得ることができます。

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

  // グラデーションを作成
  var radgrad = ctx.createRadialGradient(45, 45, 10, 52, 50, 30);
  radgrad.addColorStop(0, "#A7D30C");
  radgrad.addColorStop(0.9, "#019F62");
  radgrad.addColorStop(1, "rgba(1, 159, 98, 0)");

  var radgrad2 = ctx.createRadialGradient(105, 105, 20, 112, 120, 50);
  radgrad2.addColorStop(0, "#FF5F98");
  radgrad2.addColorStop(0.75, "#FF0188");
  radgrad2.addColorStop(1, "rgba(255, 1, 136, 0)");

  var radgrad3 = ctx.createRadialGradient(95, 15, 15, 102, 20, 40);
  radgrad3.addColorStop(0, "#00C9FF");
  radgrad3.addColorStop(0.8, "#00B5E2");
  radgrad3.addColorStop(1, "rgba(0, 201, 255, 0)");

  var radgrad4 = ctx.createRadialGradient(0, 150, 50, 0, 140, 90);
  radgrad4.addColorStop(0, "#F4F201");
  radgrad4.addColorStop(0.8, "#E4C700");
  radgrad4.addColorStop(1, "rgba(228, 199, 0, 0)");

  // 図形を描画
  ctx.fillStyle = radgrad4;
  ctx.fillRect(0, 0, 150, 150);
  ctx.fillStyle = radgrad3;
  ctx.fillRect(0, 0, 150, 150);
  ctx.fillStyle = radgrad2;
  ctx.fillRect(0, 0, 150, 150);
  ctx.fillStyle = radgrad;
  ctx.fillRect(0, 0, 150, 150);
}
```

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

```
draw();
```

この場合、始点と終点を少しずらして、球状の三次元効果を出しています。内円と外円が重ならないようにすると、予測しにくい不思議な効果が得られます。

4 つのグラデーションの最後の色経由点は、完全に透明な色を使っています。この色から前の色への移行を美しくしたい場合は、両方の色を同じにする必要があります。このコードでは、 2 つの異なる CSS カラーメソッドをデモンストレーションとして使用しているので、これはあまり明らかではありませんが、最初のグラデーションでは `#019F62 = rgba(1,159,98,1)` です。

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

### `createConicGradient` 例

この例では、 2 つの異なる扇形グラデーションを定義します。扇形グラデーションは放射グラデーションとは異なり、円を描くのではなく、点の周りを一周します。

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

  // グラデーションの作成
  var conicGrad1 = ctx.createConicGradient(2, 62, 75);
  conicGrad1.addColorStop(0, "#A7D30C");
  conicGrad1.addColorStop(1, "#fff");

  var conicGrad2 = ctx.createConicGradient(0, 187, 75);
  // we multiple our values by Math.PI/180 to convert degrees to radians
  conicGrad2.addColorStop(0, "black");
  conicGrad2.addColorStop(0.25, "black");
  conicGrad2.addColorStop(0.25, "white");
  conicGrad2.addColorStop(0.5, "white");
  conicGrad2.addColorStop(0.5, "black");
  conicGrad2.addColorStop(0.75, "black");
  conicGrad2.addColorStop(0.75, "white");
  conicGrad2.addColorStop(1, "white");

  // 図形を描画
  ctx.fillStyle = conicGrad1;
  ctx.fillRect(12, 25, 100, 100);
  ctx.fillStyle = conicGrad2;
  ctx.fillRect(137, 25, 100, 100);
}
```

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

```
draw();
```

最初のグラデーションは、最初の矩形の中央に配置され、開始時に緑の色経由点を移動し、終了時に白の色経由点を移動します。角度は 2 ラジアンから始まり、始まりと終わりの線が南東を指しているため、顕著に現れています。

2 つ目のグラデーションも、 2 つ目の矩形の中心に配置されています。こちらは複数の色経由点があり、回転の 1/4 ごとに黒から白に交互に変化します。これにより、市松模様のような効果が得られます。

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

パターン
----

前ページの例では、一連のループを使って画像のパターンを作成しました。しかし、もっと簡単な方法があります。 `createPattern()` メソッドです。

`createPattern(image, type)` (en-US)

新しいキャンバスパターンオブジェクトを作成し、返します。 `image` は `CanvasImageSource` (en-US) です（つまり、`HTMLImageElement`、他のキャンバス、 `<video>` 要素などです）。`type` は、画像の利用方法を示す文字列です。

type は、パターンを作成するための画像の使用方法を指定し、以下の文字列値のいずれかでなければなりません。

`repeat`

垂直・水平方向に画像を並べます。

`repeat-x`

画像を水平方向に並べますが、垂直方向には並べません。

`repeat-y`

画像を垂直方向に並べますが、水平方向には並べません。

`no-repeat`

画像をタイル配置しません。一度だけ使用されます。

このメソッドを使って `CanvasPattern` オブジェクトを作成します。これは上で見たグラデーションのメソッドと非常によく似ています。パターンを作成したら、それを `fillStyle` または `strokeStyle` プロパティに代入します。例えば次のようにします。

```js
var img = new Image();
img.src = "someimage.png";
var ptrn = ctx.createPattern(img, "repeat");
```

**メモ:** `drawImage()` メソッドと同様に、このメソッドを呼び出す前に使用する画像が読み込まれていることを確認する必要があります。そうしないと、パターンが正しく描画されない可能性があります。

### `createPattern` の例

この最後の例では、 `fillStyle` プロパティに割り当てるパターンを作成します。唯一の注目すべき点は、画像の `onload` ハンドラーを使用していることです。これは、パターンに割り当てる前に画像が読み込まていれることを保証するためです。

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

  // 新しい画像オブジェクトを生成して、パターンとして使用する
  var img = new Image();
  img.src = "canvas\_createpattern.png";
  img.onload = function () {
    // パターンを作成
    var ptrn = ctx.createPattern(img, "repeat");
    ctx.fillStyle = ptrn;
    ctx.fillRect(0, 0, 150, 150);
  };
}
```

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

```
draw();
```

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

影
-

影を使うには、ちょうど 4 つのプロパティが必要です。

`shadowOffsetX = float`

影がオブジェクトから伸びるべき水平距離を示します。この値は、変換行列の影響を受けません。既定値は 0 です。

`shadowOffsetY = float`

影がオブジェクトから伸びるべき垂直距離を示します。この値は、変換行列の影響を受けません。既定値は 0 です。

`shadowBlur = float`

ぼかし効果の大きさを示します。この値はピクセル数には対応せず、現在の変換行列の影響を受けません。既定値は 0 です。

`shadowColor = color`

影の効果の色を示す CSS 標準の色の値です。は、既定では完全透過の黒です。

プロパティ `shadowOffsetX` と `shadowOffsetY` は、影がオブジェクトから X と Y 方向にどれだけ伸びるかを示します。これらの値は、現在の変換行列には影響されません。影を上または左に伸ばすには負の値を使用し、影を下または右に伸ばすには正の値を使用します。既定値はどちらも 0 です。

`shadowBlur` プロパティはぼかし効果の大きさを示します。この値はピクセル数には対応せず、現在の変換行列の影響を受けません。既定値は 0 です。

`shadowColor` プロパティは影の効果の色を示す CSS 標準の色の値です。は、既定では完全透過の黒です。

**メモ:** 影は `source-over` 合成操作でのみ描画されます。

### 影付きテキストの例

この例では、文字列を影付きで描画しています。

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

  ctx.shadowOffsetX = 2;
  ctx.shadowOffsetY = 2;
  ctx.shadowBlur = 2;
  ctx.shadowColor = "rgba(0, 0, 0, 0.5)";

  ctx.font = "20px Times New Roman";
  ctx.fillStyle = "Black";
  ctx.fillText("Sample String", 5, 30);
}
```

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

```
draw();
```

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

`font` プロパティと `fillText` メソッドについては、次の章の テキストの描画で見ていくことにしましょう。

キャンバスの塗りつぶしルール
--------------

`fill` （または `clip` (en-US) と `isPointInPath` (en-US)）を使う場合、オプションとして、ある点がパスの内側か外側か、したがってそれが埋められたかどうかを判断する充填規則のアルゴリズムを指定することが出来ます。これは、パスがそれ自身と交差していたり、入れ子になっていたりする場合に便利です。

2 つの値が可能です。

`nonzero`

非ゼロワインディングルールです。こちらが既定のルールです。

`evenodd`

偶奇ワインディングルールです。

この例では `evenodd` ルールを使用しています。

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  ctx.beginPath();
  ctx.arc(50, 50, 30, 0, Math.PI \* 2, true);
  ctx.arc(50, 50, 15, 0, Math.PI \* 2, true);
  ctx.fill("evenodd");
}
```

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

```
draw();
```

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

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


座標変換 - Web API

座標変換
====

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

これまでのチュートリアルで、キャンバスのグリッドや**座標空間**について学びました。今までは既定のグリッドしか使用しておらず、また必要に応じてキャンバス全体のサイズを変更していました。座標変換 (transformations) には、原点を別の場所に移したり、回転したり、拡大縮小したりといった、より強力な手段があります。

状態の保存と復元
--------

座標変換のメソッドを見ていく前に、より複雑な描画を始めたときに不可欠になメソッドを 2 つ見ておきましょう。

`save()`

キャンバス全体の状態を保存します。

`restore()` (en-US)

直近に保存したキャンバスの状態を復元します。

キャンバスの状態は、スタックに保存されます。 `save()` メソッドを呼び出すたびに、現在の描画状態をスタックにプッシュします。描画状態は以下の情報で構成されます。

* 適用された座標変換操作 (すなわち、後述する `translate`、`rotate`、`scale`)。
* `strokeStyle`、`fillStyle`、`globalAlpha`、`lineWidth` (en-US)、`lineCap`、`lineJoin` (en-US)、`miterLimit` (en-US)、`lineDashOffset` (en-US)、`shadowOffsetX`、`shadowOffsetY`、`shadowBlur`、`shadowColor`、`globalCompositeOperation`、`font`、`textAlign`、`textBaseline`、`direction`、`imageSmoothingEnabled` 属性の現在の値。
* 現在のクリッピングパス。これは次の章で説明します。

`save()` メソッドは、何回でも呼び出すことができます。`restore()` メソッドを呼び出すたびに、最後に保存された状態をスタックからポップして、すべての保存済み設定を復元します。

### `save` および `restore` の例

この例は、連続した一連の矩形を描画するときに、描画状態のスタックがどのように機能するかを示します。

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

  ctx.fillRect(0, 0, 150, 150); // 既定の設定で矩形を描画
  ctx.save(); // 既定の状態を保存

  ctx.fillStyle = "#09F"; // 設定変更
  ctx.fillRect(15, 15, 120, 120); // 新たな設定で矩形を描画

  ctx.save(); // 現在の状態を保存
  ctx.fillStyle = "#FFF"; // 設定変更
  ctx.globalAlpha = 0.5;
  ctx.fillRect(30, 30, 90, 90); // 新たな設定で矩形を描画

  ctx.restore(); // 以前の状態を復元
  ctx.fillRect(45, 45, 60, 60); // 復元した設定で矩形を描画

  ctx.restore(); // 以前の状態を復元
  ctx.fillRect(60, 60, 30, 30); // 復元した設定で矩形を描画
}
```

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

```
draw();
```

最初のステップで、大きな矩形を既定の設定で描きます。次にこの状態を保存して、塗りつぶし色を変更します。そして、 2 番目のやや小さい青色の矩形を描いて、状態を保存します。もう一度描画設定を変更して、 3 番目の半透明な白色の矩形を描きます。

ここまでは、これまでの章で行ってきたことによく似ています。しかし最初に `restore()` 文を呼び出したとき、スタックの先頭の描画状態が削除されて、その設定が復元されます。`save()` を使用して状態を保存しなければ、前の状態に戻すために塗りつぶし色や透過性を手動で変更しなければなりません。ここではプロパティが 2 つであり容易ですが、プロパティが多ければコードが一気にとても長くなります。

2 番目の `restore()` 文を呼び出すと、元の状態（1 番目の `save` を呼び出す前に設定した状態）を復元して、最後の矩形を再び黒色で描きます。

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

移動
--

最初の座標変換メソッドとして、`translate()` を見ていきましょう。このメソッドは、キャンバスおよびその原点をグリッド内の別の場所に移動するために使用されます。

`translate(x, y)` (en-US)

キャンバスやその原点をグリッド上で移動します。`x` は水平方向の移動距離、`y` はグリッドを垂直方向の移動距離を示します。

![](/ja/docs/Web/API/Canvas_API/Tutorial/Transformations/canvas_grid_translate.png)

座標変換を行う前にキャンバスの状態を保存しておくことは、よいアイデアです。ほとんどの場合、元の状態に戻すためには逆の座標変換を行うよりも `restore` メソッドを呼び出すほうが簡単です。また、ループ内で座標変換を行っているときにキャンバスの状態の保存や復元を行わなければ、キャンバスの端の外側に描画することになり、描いたものの一部を失ってしまうかもしれません。

### `translate` の例

この例は、キャンバスの原点を移動する利点をいくつか示しています。 `translate()` メソッドを使用しなければ、すべての矩形が同じ位置 (0,0) に描かれます。また `translate()` によって、 `fillRect()` 関数で座標を手動で調整する必要なく、どこにでも自由に矩形を置くことができます。これにより若干理解しやすく、また使いやすくなります。

`draw()` 関数で、`for` ループを使用して `fillRect()` 関数を 9 回呼び出しています。それぞれのループで canvas を移動して矩形を描き、その後に元の状態を復元します。描画位置を調節する `translate()` を頼って、`fillRect()` は毎回同じ座標を使用していることに注目してください。

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  for (var i = 0; i < 3; i++) {
    for (var j = 0; j < 3; j++) {
      ctx.save();
      ctx.fillStyle = "rgb(" + 51 \* i + ", " + (255 - 51 \* i) + ", 255)";
      ctx.translate(10 + j \* 50, 10 + i \* 50);
      ctx.fillRect(0, 0, 25, 25);
      ctx.restore();
    }
  }
}
```

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

```
draw();
```

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

回転
--

2 番目の座標変換メソッドは `rotate()` です。現在の原点を中心にしてキャンバスを回転させるために使用します。

`rotate(angle)` (en-US)

現在の原点を中心にしてラジアンで示した `angle` の分、キャンバスを時計回りに回転します。

![](/ja/docs/Web/API/Canvas_API/Tutorial/Transformations/canvas_grid_rotate.png)

回転の中心は、常にキャンバスの原点です。中心を変更するには、`translate()` メソッドを使用してキャンバスを移動しなければなりません。

### `rotate` の例

この例は、まずはキャンバスの原点で矩形を回転するために `rotate()` メソッドを使用して、次に矩形自身の中心で回転するために `translate()` の助けを借りています。

**メモ:** 角度はラジアン (radians) で表しており、度数 (degrees) ではありません。これは `radians = (Math.PI/180)*degrees` のようにすると変換できます。

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

  // 左の矩形を canvas の原点で回転する
  ctx.save();
  // 青い矩形
  ctx.fillStyle = "#0095DD";
  ctx.fillRect(30, 30, 100, 100);
  ctx.rotate((Math.PI / 180) \* 25);
  // 灰色の矩形
  ctx.fillStyle = "#4D4E53";
  ctx.fillRect(30, 30, 100, 100);
  ctx.restore();

  // 右の矩形を矩形の中心で回転する
  // draw blue rect
  ctx.fillStyle = "#0095DD";
  ctx.fillRect(150, 30, 100, 100);

  ctx.translate(200, 80); // 矩形の中心に移動する
  // x = x + 0.5 \* 幅
  // y = y + 0.5 \* 高さ
  ctx.rotate((Math.PI / 180) \* 25); // 回転する
  ctx.translate(-200, -80); // 元の位置に移動する

  // 灰色の矩形を描く
  ctx.fillStyle = "#4D4E53";
  ctx.fillRect(150, 30, 100, 100);
}
```

矩形を中心で回転するために、キャンバスを矩形の中心へ移動した後にキャンバスを回転しています。そして canvas を 0,0 へ移動した後に矩形を描きます。
```

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

```
draw();
```

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

拡大縮小
----

次の座標変換メソッドは拡大縮小です。キャンバスのグリッドの単位を増減するために使用します。これは、図形やビットマップを縮小または拡大して描くために使用できます。

`scale(x, y)`

キャンバスの単位を x （水平方向）または y （垂直方向）で指定した分拡大縮小します。どちらの引数も実数です。1.0 より小さい値は単位あたりのサイズが減少、1.0 より大きい値は単位あたりのサイズが増加します。1.0 では単位あたりのサイズが変わりません。

負数を使用すると軸を反転できます（例えば `translate(0,canvas.height); scale(1,-1);` で、原点が左下の隅にある有名なデカルト座標系になります）。

既定では、キャンバスの 1 単位は 1 ピクセルとまったく同じです。例えば、拡大率に 0.5 を適用すると 1 単位が 0.5 ピクセルになり、図形が半分のサイズで描かれます。同様に拡大率を 2.0 に設定すると単位あたりのサイズが増えて、1 単位あたり 2 ピクセルになります。この結果、図形は 2 倍の大きさで描かれます。

### `scale` の例

この例は、図形をさまざまな拡大率で描きます。

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

  // シンプルな図形を描いて、拡大する
  ctx.save();
  ctx.scale(10, 3);
  ctx.fillRect(1, 10, 10, 10);
  ctx.restore();

  // 水平方向に反転する
  ctx.scale(-1, 1);
  ctx.font = "48px serif";
  ctx.fillText("MDN", -135, 120);
}
```

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

```
draw();
```

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

座標変換
----

最後に、以下の座標変換メソッドでは、変換行列によって直接変更を行うことができます。

* `transform(a, b, c, d, e, f)` (en-US)
    + : 引数で表した行列と、現在の変換行列で乗算を行います。変換行列は以下のとおりです。

    [

    a

    c

    e

    b

    d

    f

    0

    0

    1

    ]

    \left[ \begin{array}{ccc} a & c & e \ b & d & f \ 0 & 0 & 1 \end{array} \right]
    + : いずれかの引数が `Infinity` になる場合は、メソッドで例外を発生させないように行列を infinite としてマークしなければなりません。

この関数の引数は以下のとおりです。

`a (m11)`

水平方向の拡大。

*`b (m12)`*

水平方向の歪み。

`c (m21)`

垂直方向の歪み。

`d (m22)`

垂直方向の拡大。

`e (dx)`

水平方向の移動。

`f (dy)`

垂直方向の移動。

`setTransform(a, b, c, d, e, f)` (en-US)

現在の座標変換を単位行列にリセットして、同じ引数で `transform()` メソッドを呼び出します。これは基本的に、現在の座標変換をアンドゥしてから指定した座標変換を行う操作を一度に行うものです。

`resetTransform()` (en-US)

現在の座標変換を単位行列にリセットします。これは `ctx.setTransform(1, 0, 0, 1, 0, 0);` を呼び出すことと同じです。

### `transform` と `setTransform` の例

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

  var sin = Math.sin(Math.PI / 6);
  var cos = Math.cos(Math.PI / 6);
  ctx.translate(100, 100);
  var c = 0;
  for (var i = 0; i <= 12; i++) {
    c = Math.floor((255 / 12) \* i);
    ctx.fillStyle = "rgb(" + c + ", " + c + ", " + c + ")";
    ctx.fillRect(0, 0, 100, 10);
    ctx.transform(cos, sin, -sin, cos, 0, 0);
  }

  ctx.setTransform(-1, 0, 0, 1, 100, 100);
  ctx.fillStyle = "rgba(255, 128, 255, 0.5)";
  ctx.fillRect(0, 50, 100, 100);
}
```

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

```
draw();
```

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

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


キャンバスでの図形の描画 - Web API

キャンバスでの図形の描画
============

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

キャンバスの環境をセットアップしましたので、キャンバスに描画する方法の詳細に入ることができます。この記事の終わりまでに、矩形、三角形、直線、円弧、曲線を描く方法を学び、基本的な図形について理解できます。キャンバスにオブジェクトを描く際はパスを扱うことが不可欠ですので、その方法を見ていきます。

グリッド
----

描画を始める前に、キャンバスのグリッド、もしくは**座標空間**について話す必要があります。前のページの HTML スケルトンは、幅 150 ピクセル、高さ 150 ピクセルの canvas 要素を持っていました。

![](/ja/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes/canvas_default_grid.png)

普通、グリッド上の 1 単位はキャンバス上の 1 ピクセルに相当します。このグリッドの原点は、*左上*の角に (0,0) の座標が配置されています。すべての要素がこの原点から相対的に配置されます。よって青い正方形の左上の場所は左から x ピクセル、上から y ピクセルの、 (x,y) の位置になります。このチュートリアルの後半では、原点を別の位置に移動したり、グリッドを回転させたり、拡大縮小したりする方法を紹介しますが、今は既定のままにしておきましょう。

矩形の描画
-----

SVG とは異なり、 `<canvas>` は 2 つの基本的な図形、矩形とパス（直線で結んだ点のリスト）のみに対応しています。他の全ての図形は 1 つ以上のパスの組み合わせで作らなくてはなりません。幸いなことに、パスを描く一連の関数があり、とても複雑な図形を作ることができます。

最初に矩形を見ていきましょう。キャンバスに矩形を描く関数が 3 つあります。

`fillRect(x, y, width, height)`

塗りつぶされた矩形を描きます。

`strokeRect(x, y, width, height)`

矩形の輪郭を描きます。

`clearRect(x, y, width, height)`

指定された領域を消去し、完全な透明にします。

3 つの関数は同じ引数を取ります。 `x` と `y` はキャンバスにおける矩形の左上の角の位置（原点からの相対位置）を指定します。 `width` と `height` は矩形の大きさを指定します。

以下のものは前ページの `draw()` 関数ですが、ここではこれら 3 つの関数を使用しています。

### 矩形の例
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

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

    ctx.fillRect(25, 25, 100, 100);
    ctx.clearRect(45, 45, 60, 60);
    ctx.strokeRect(50, 50, 50, 50);
  }
}
```

結果は以下のように見えるはずです。

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

`fillRect()` 関数は 100 ピクセル各の大きな黒い正方形を描きます。 `clearRect()` 関数は中心から 60x60 ピクセルの正方形を取り除き、最後に `strokeRect()` が消去された正方形の中に 50x50 ピクセルの矩形の輪郭を描きます。

後のページでは、 `clearRect()` に代わる 2 つのメソッドを紹介し、描画された図形の色と輪郭のスタイルを変更する方法について説明します。

次の節で見るパス関数とは異なり、 3 つの矩形関数はすべてキャンバスに即座に描画されます。

パスを描く
-----

ここで、パスについて見てみましょう。パスは点のリストであり、さまざまな形、曲線、幅、色の線分によって結ばれています。パスは、サブパスのように閉じることができます。パスを使って図形を作るには、いくつかの特別な手順を踏みます。

1. 始めに、パスを作成します。
2. 次に、パスへ描画するために描画コマンドを使用します。
3. パスを作成したら、パスを輪郭または塗りつぶしで描くことができます。

これらのステップで使用する関数を以下に示します。

`beginPath()`

新しいパスを作成します。パスを作成すると以降の描画コマンドは、そのパスを構築するために直接作用します。

パスのメソッド

オブジェクトのためにさまざまなパスを設定するメソッド群です。

`closePath()`

直線をパスに追加し、現在のサブパスの開始地点につなぎます。

`stroke()`

輪郭をなぞる方式で、図形を描きます。

`fill()` (en-US)

パスの内部領域を塗りつぶして、単色の図形を描きます。

パスを作る最初の作業は `beginPath()` メソッドを呼び出すことです。内部では、パスは図形を一緒に作るサブパス（線、円弧など）のリストとして保存されます。このメソッドが呼び出される毎に、リストはリセットされ新しい図形を始めることができます。

**メモ:** `beginPath()` を呼び出した直後やキャンバスを新規作成した直後など、現在のパスが空であるときに最初にパスを構築するコマンドは、実際は何であるかにかかわらず常に `moveTo()` として扱われます。このためパスをリセットした後はほぼ必ず、開始位置を明示することが必要になるでしょう。

2 番目の作業は描かれる実際のパスを定義するメソッドを呼び出すことです。まもなくみることになります。

3 番目は任意の作業ですが、 `closePath()` メソッドを呼び出すことです。このメソッドは現在の点から始点に向けて直線を描くことで図形を閉じようとします。もし図形がすでに閉じられているかリストに点がひとつしかない場合はこの関数は何もしません。

**メモ:** `fill()` が呼び出されたとき、開いている図形は自動的に閉じられるので、`closePath()` を呼び出す必要はありません。これは、`stroke()` を呼び出したときは**あてはまりません**。

### 三角形の描画

例えば、三角形を描くコードは次のようになります。
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="100" height="100"></canvas>
  </body>
</html>
```

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

    ctx.beginPath();
    ctx.moveTo(75, 50);
    ctx.lineTo(100, 75);
    ctx.lineTo(100, 25);
    ctx.fill();
  }
}
```

表示結果は以下のようになります。

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

### ペンの移動

非常に便利な関数のひとつに、 `moveTo()` 関数があります。これは実際には何も描画しませんが、上記のパスのリストの一部となります。これは、ペンや鉛筆を紙の上のある場所から持ち上げて、次の場所に置くようなものだと思えばよいでしょう。

`moveTo(x, y)`

`x` と `y` で指定した座標に、ペンを移動します。

キャンバスが初期化されるか `beginPath()` メソッドが呼び出されたとき、ふつうは `moveTo()` メソッドを使って始点を他の場所に配置します。 `moveTo()` メソッドを使って繋がっていないパスを描くこともできます。下のスマイリーを見てください。

これをあなた自身で試すには、以下のコードを使うことができます。さきほど見た `draw()` 関数に貼り付けるだけです。
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

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

    ctx.beginPath();
    ctx.arc(75, 75, 50, 0, Math.PI \* 2, true); // 外の円
    ctx.moveTo(110, 75);
    ctx.arc(75, 75, 35, 0, Math.PI, false); // 口 (時計回り)
    ctx.moveTo(65, 65);
    ctx.arc(60, 65, 5, 0, Math.PI \* 2, true); // 左目
    ctx.moveTo(95, 65);
    ctx.arc(90, 65, 5, 0, Math.PI \* 2, true); // 右目
    ctx.stroke();
  }
}
```

表示結果は以下のようになります。

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

もし、連続した線を見たい場合は、`moveTo()`を呼び出す行を削除してください。

**メモ:** `arc()` 関数とそのパラメータの解説は円弧の節をご覧下さい。

### 直線

直線を描くには `lineTo()` メソッドを使います。

`lineTo(x, y)`

現在の描画位置から `x` と `y` で指定した位置に、線を描きます。

このメソッドは、線の終点の座標である `x` と `y` の 2 つの引数をとります。始点は以前に描かれたパスに依存し、前のパスの終点が次のパスの始点となる、といった具合です。始点は、 `moveTo()` メソッドを用いて変更することもできます。

次の例では 2 つの三角形が描かれています。 1 つは塗りつぶされ、もう 1 つは輪郭線が描かれます。
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

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

    // 塗りつぶした三角形
    ctx.beginPath();
    ctx.moveTo(25, 25);
    ctx.lineTo(105, 25);
    ctx.lineTo(25, 105);
    ctx.fill();

    // 輪郭の三角形
    ctx.beginPath();
    ctx.moveTo(125, 125);
    ctx.lineTo(125, 45);
    ctx.lineTo(45, 125);
    ctx.closePath();
    ctx.stroke();
  }
}
```

最初に新しい図形のパスを始めるために `beginPath()` メソッドが呼ばれています。次に 始点を望む位置に移動するために `moveTo()` メソッドが呼ばれています。三角形の両側の辺を作る 2 つの線が描かれています。

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

塗りつぶされた三角形と輪郭線の三角形の違いに気づくでしょう。これは前述したように、図形はパスが塗りつぶされたときには自動的に閉じられますが、輪郭線のときには閉じられないからです。もし、描画された三角形の `closePath()` を省いたら、完全な三角形ではなく、 2 本の線だけが描画されることになります。

### 円弧

円弧や円を描くために `arc()` または `arcTo()` メソッドを使います。

`arc(x, y, radius, startAngle, endAngle, counterclockwise)`

*(x, y)* を中心の位置、 *radius* を半径、 *startAngle* を開始角度、 *endAngle* を終了角度、 *counterclockwise* を方向（既定では時計回り）とする円弧を描きます。

`arcTo(x1, y1, x2, y2, radius)`

指定した制御点と半径によって円弧を描き、その前の描画位置と直線で接続します。

もっと詳しく `arc` メソッドを見てみましょう。このメソッドは 6 つの引数を取ります。 `x` と `y` は円弧を描画する円の中心の座標です。 `x` と `y` は円弧を描画する円の中心の座標で、 `radius` はその名の通り半径です。 `startAngle` および `endAngle` 引数は、円のカーブに沿った円弧の始点と終点をラジアン単位で指定します。これらは x 軸から測定されます。 `counterclockwise` 引数は論理値で、 `true` の場合は反時計回りに、それ以外の場合は時計回りに円弧が描かれます。

**メモ:** `arc` 関数の角度は度ではなく、ラジアンで計算されます。度からラジアンに変換するには、 JavaScript の式では `radians = (Math.PI/180)*degrees` を使うことができます。

次の例は、上で見たものよりも少し複雑です。これは 12 種類の円弧を、それぞれ異なる角度と塗りつぶしで描画します。

2 つの `for` ループは円弧の行と列のループです。すべての円弧毎に `beginPath()` を使って新しいパスを始めます。コードでは、わかりやすくするために円弧の各引数を変数にしていますが、実生活では必ずしもそうする必要はないでしょう。

`x` と `y` の座標は十分に明確であるはずです。 `radius` と `startAngle` は固定です。 `endAngle` は最初の列で 180 度（半円）から始まり、90 度ずつ増加し、最後の列で完全な円になります。

`clockwise` 引数の文は最初と 3 番目の列では時計回りの円弧として 2 番目と 4 番目の列では反時計回りの円弧という結果になります。最後に、 `if` 文は上半分は輪郭を描画された円弧を、下半分は塗られた円弧を作ります。

**メモ:** この例では、ほかの例より若干大きなサイズである 150 x 200 ピクセルのキャンバスが必要です。
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="200"></canvas>
  </body>
</html>
```

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

    for (var i = 0; i < 4; i++) {
      for (var j = 0; j < 3; j++) {
        ctx.beginPath();
        var x = 25 + j \* 50; // x 座標
        var y = 25 + i \* 50; // y 座標
        var radius = 20; // 円弧の半径
        var startAngle = 0; // 円孤の始点
        var endAngle = Math.PI + (Math.PI \* j) / 2; // 円孤の終点
        var counterclockwise = i % 2 !== 0; // 時計回りまたは反時計回り

        ctx.arc(x, y, radius, startAngle, endAngle, counterclockwise);

        if (i > 1) {
          ctx.fill();
        } else {
          ctx.stroke();
        }
      }
    }
  }
}
```

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

### ベジェと二次曲線

次に見ていく種類のパスはベジェ曲線です。三次関数と二次関数が利用可能です。一般に、複雑な自然の図形を描くのに使われます。

`quadraticCurveTo(cp1x, cp1y, x, y)` (en-US)

現在のペンの位置から `x` および `y` で指定した終端へ、 `cp1x` および `cp1y` で指定した制御点を使用して二次ベジェ曲線を描きます。

`bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)` (en-US)

現在のペンの位置から `x` および `y` で指定した終端へ、(`cp1x`, `cp1y`) および (`cp2x`, `cp2y`) で指定した制御点を使用して三次ベジェ曲線を描きます。

 これらの違いは右の画像を使うことで説明することができます。二次ベジェ曲線は始点と終点（青い点）と 1 つの**制御点**（赤い点で示したもの） を持つのに対して、三次ベジェ曲線は 2 つの制御点を持ちます。

 ![](/ja/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes/canvas_curves.png)

それらのメソッドの両方の `x` と `y` パラメータは終点の座標です。`cp1x` と `cp1y` は最初の制御点、`cp2x` と `cp2y` は 2 番目の制御点の座標です。

二次・三次ベジェ曲線は、 Adobe Illustrator のようなベクトル描画ソフトとは異なり、何をしているのかが直接視覚的にわからないため、かなり難易度が高いです。そのため、複雑な形状を描くのはかなり難しいです。次の例では、単純な有機的な形状をいくつか描きますが、時間と忍耐力があれば、もっと複雑な形状を作成することが可能です。

これらの例で非常に難しいものは何もありません。 どちらの場合も、最終的に描かれた一連の曲線が完全な図形となるのを見ることになります。

#### 二次ベジェ曲線

この例では、吹き出しをレンダリングするために複数の二次ベジェ曲線を使用しています。
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

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

    // 二次曲線の例
    ctx.beginPath();
    ctx.moveTo(75, 25);
    ctx.quadraticCurveTo(25, 25, 25, 62.5);
    ctx.quadraticCurveTo(25, 100, 50, 100);
    ctx.quadraticCurveTo(50, 120, 30, 125);
    ctx.quadraticCurveTo(60, 120, 65, 100);
    ctx.quadraticCurveTo(125, 100, 125, 62.5);
    ctx.quadraticCurveTo(125, 25, 75, 25);
    ctx.stroke();
  }
}
```

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

#### 三次ベジェ曲線

この例では、三次ベジェ曲線を使ってハートを描画します。
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

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

    // 三次ベジェ曲線の例
    ctx.beginPath();
    ctx.moveTo(75, 40);
    ctx.bezierCurveTo(75, 37, 70, 25, 50, 25);
    ctx.bezierCurveTo(20, 25, 20, 62.5, 20, 62.5);
    ctx.bezierCurveTo(20, 80, 40, 102, 75, 120);
    ctx.bezierCurveTo(110, 102, 130, 80, 130, 62.5);
    ctx.bezierCurveTo(130, 62.5, 130, 25, 100, 25);
    ctx.bezierCurveTo(85, 25, 75, 37, 75, 40);
    ctx.fill();
  }
}
```

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

### 矩形

矩形の描画で見た、キャンバスに直接矩形を描く 3つ のメソッドに加え、現在開いているパスに矩形のパスを追加する `rect()` メソッドも用意されています。

`rect(x, y, width, height)`

(`x`, `y`) で指定した位置を左上の角にして、 `width` および `height` で指定した幅および高さの矩形を描きます。

このメソッドが実行される前に、引数に (x,y) を持った `moveTo()` メソッドが自動的に呼ばれます。すなわち、始点が標準の位置に置かれます。

### 組み合わせ

このページのすべての例で図形につき一種類のパス関数のみを使ってきました。しかし、図形を作るのに使用できるパスの種類の制限は一切ありません。そこで、この最後の例では非常に有名なゲームのキャラクターを作るために、全てのパス関数を組み合わせてみましょう。
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

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

    roundedRect(ctx, 12, 12, 150, 150, 15);
    roundedRect(ctx, 19, 19, 150, 150, 9);
    roundedRect(ctx, 53, 53, 49, 33, 10);
    roundedRect(ctx, 53, 119, 49, 16, 6);
    roundedRect(ctx, 135, 53, 49, 33, 10);
    roundedRect(ctx, 135, 119, 25, 49, 10);

    ctx.beginPath();
    ctx.arc(37, 37, 13, Math.PI / 7, -Math.PI / 7, false);
    ctx.lineTo(31, 37);
    ctx.fill();

    for (var i = 0; i < 8; i++) {
      ctx.fillRect(51 + i \* 16, 35, 4, 4);
    }

    for (i = 0; i < 6; i++) {
      ctx.fillRect(115, 51 + i \* 16, 4, 4);
    }

    for (i = 0; i < 8; i++) {
      ctx.fillRect(51 + i \* 16, 99, 4, 4);
    }

    ctx.beginPath();
    ctx.moveTo(83, 116);
    ctx.lineTo(83, 102);
    ctx.bezierCurveTo(83, 94, 89, 88, 97, 88);
    ctx.bezierCurveTo(105, 88, 111, 94, 111, 102);
    ctx.lineTo(111, 116);
    ctx.lineTo(106.333, 111.333);
    ctx.lineTo(101.666, 116);
    ctx.lineTo(97, 111.333);
    ctx.lineTo(92.333, 116);
    ctx.lineTo(87.666, 111.333);
    ctx.lineTo(83, 116);
    ctx.fill();

    ctx.fillStyle = "white";
    ctx.beginPath();
    ctx.moveTo(91, 96);
    ctx.bezierCurveTo(88, 96, 87, 99, 87, 101);
    ctx.bezierCurveTo(87, 103, 88, 106, 91, 106);
    ctx.bezierCurveTo(94, 106, 95, 103, 95, 101);
    ctx.bezierCurveTo(95, 99, 94, 96, 91, 96);
    ctx.moveTo(103, 96);
    ctx.bezierCurveTo(100, 96, 99, 99, 99, 101);
    ctx.bezierCurveTo(99, 103, 100, 106, 103, 106);
    ctx.bezierCurveTo(106, 106, 107, 103, 107, 101);
    ctx.bezierCurveTo(107, 99, 106, 96, 103, 96);
    ctx.fill();

    ctx.fillStyle = "black";
    ctx.beginPath();
    ctx.arc(101, 102, 2, 0, Math.PI \* 2, true);
    ctx.fill();

    ctx.beginPath();
    ctx.arc(89, 102, 2, 0, Math.PI \* 2, true);
    ctx.fill();
  }
}

// 角丸の四角形を描画するためのユーティリティ関数

function roundedRect(ctx, x, y, width, height, radius) {
  ctx.beginPath();
  ctx.moveTo(x, y + radius);
  ctx.arcTo(x, y + height, x + radius, y + height, radius);
  ctx.arcTo(x + width, y + height, x + width, y + height - radius, radius);
  ctx.arcTo(x + width, y, x + width - radius, y, radius);
  ctx.arcTo(x, y, x, y + radius, radius);
  ctx.stroke();
}
```

以下の様な表示結果となります。

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

実際には驚くほど簡単なので、ここでは詳しく説明しません。最も重要なことは、描画コンテキストで `fillStyle` プロパティを使用することと、ユーティリティ関数（この場合は `roundedRect()`）を使用することです。ユーティリティ関数を使用すると、必要なコードの量や複雑さを減らすことができ、とても便利です。

このチュートリアルの後半で、 `fillStyle` について、より詳しく見ていきます。ここでは、パスの塗りつぶし色を既定の黒から白に変更し、また元に戻すために使用しているだけです。

Path2D オブジェクト
-------------

最後の例で見たように、オブジェクトを描くための一連のパスや描画コマンドをキャンバスに置くことができます。コードをシンプルにしてパフォーマンスを向上させるために最近の版のブラウザーで使用できる `Path2D` (en-US) オブジェクトは、描画コマンドをキャッシュあるいは記録することを可能にしています。これにより、パスをすばやく再実行できます。 `Path2D` オブジェクトの構築方法を見ていきましょう。

`Path2D()`

**`Path2D()`** コンストラクターは、新たにインスタンス化した `Path2D` オブジェクトを返します。任意で引数として別のパス、あるいは SVG パスデータを構成する文字列を指定できます（コピーを作成）。

```js
new Path2D(); // 空のパスオブジェクトを作成する
new Path2D(path); // 別の Path2D オブジェクトを複製する
new Path2D(d); // SVG パスデータからパスを作成する
```

これまで見てきたすべてのパスメソッド、`moveTo`、`rect`、`arc`、`quadraticCurveTo` などを、 `Path2D` オブジェクトで使用することができます。

また `Path2D` API には、パスを結合するための `addPath` メソッドが追加されています。これは、複数の部品を組み合わせてオブジェクトを構築したい場合などに役立ちます。

`Path2D.addPath(path [, transform])`

現在のパスに、変換行列（任意指定）とともに、パスを追加します。

### Path2D の例

この例では、矩形と円を作成します。どちらも `Path2D` オブジェクトとして保存しており、後で使用することができます。新たな `Path2D` API に合わせて、いくつかのメソッドが現在のパスに代わり任意で `Path2D` を受け入れられるように更新されました。ここでは、キャンバスに両方のオブジェクトを描くため、 1 つの path 引数を `stroke` および `fill` で使用しています。
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="130" height="100"></canvas>
  </body>
</html>
```

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

    var rectangle = new Path2D();
    rectangle.rect(10, 10, 50, 50);

    var circle = new Path2D();
    circle.arc(100, 35, 25, 0, 2 \* Math.PI);

    ctx.stroke(rectangle);
    ctx.fill(circle);
  }
}
```

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

### SVG パスの使用

キャンバスの新たな `Path2D` API の、もうひとつの強力な機能が、 SVG パスデータを使用してキャンバスのパスを初期化ができることです。これにより、パスデータを SVG キャンバスの両方で使い回すことができるようになります。

このパスはある点に移動して (`M10 10`) 、そこから右へ水平に 80 ポイント移動 (`h 80`)、下へ 80 ポイント移動 (`v 80`) 、 80 ポイント 左へ移動 (`h -80`) 、そして始点へ戻ります (`z`)。この例は `Path2D` コンストラクターのページで確認できます。

```js
var p = new Path2D("M10 10 h 80 v 80 h -80 Z");
```

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


キャンバスの最適化 - Web API

キャンバスの最適化
=========

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

`<canvas>` 要素は、ウェブで二次元グラフィックを描画するためにもっとも広く使用されているツールのひとつです。しかし、ウェブサイトやアプリがキャンバス API の限界付近まで使用するようになって、パフォーマンスが悪化するようになりました。この記事では、キャンバス要素の使用を最適化して、グラフィックを確実に改善するための提案を行います。

パフォーマンスに関する TIPS
----------------

キャンバスのパフォーマンスを向上させるための TIPS 集を以下に掲載します。

### 同様のプリミティブや繰り返し使用するオブジェクトをオフスクリーンキャンバスで事前にレンダリングする

アニメーションフレーム毎に同じ描画操作を繰り返していることに気づいたら、あらかじめオフスクリーンキャンバスに描画しておくことを検討しましょう。そして、必要な時に本来のキャンバスにオフスクリーン画像を、最初の場所で生成したときのステップなしで描画することができます。

```js
myCanvas.offscreenCanvas = document.createElement("canvas");
myCanvas.offscreenCanvas.width = myCanvas.width;
myCanvas.offscreenCanvas.height = myCanvas.height;

myCanvas.getContext("2d").drawImage(myCanvas.offScreenCanvas, 0, 0);
```

### 浮動小数点数値の座標を避けて整数を使用

キャンバスで整数以外の値を使用してオブジェクトを描画すると、サブピクセルレンダリングを実行します。

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

これはアンチエイリアス効果を生成するために、ブラウザーに追加の計算処理を強制します。これを避けるために、たとえば `drawImage()` を呼び出す際に `Math.floor()` を使用して、すべての座標で端数処理を行ってください。

### `drawImage` で画像の拡大縮小を行わない

`drawImage()` でいつも画像の拡大縮小処理を行うのではなく、さまざまなサイズの画像をオフスクリーンキャンバスでキャッシュしてください。

### 複雑なシーンでは複数レイヤーのキャンバスを使用する

アプリケーションでは、一部のオブジェクトは頻繁に動かしたり変更したりする必要があるのに対し、他のものは比較的静止していることが分かるかもしれません。この場合に可能な最適化は、複数の `<canvas>` 要素を使用してアイテムをレイヤー化することです。

例えば、 UI があるゲームが最上位にあり、中間にゲームプレイの動作があり、最下位に静止した背景があるとします。この場合、ゲームを３つの `<canvas>` レイヤーに分割することができます。 UI はユーザーの入力のみに基づいて変化し、ゲームプレイレイヤーはフレーム毎に変化し、背景は基本的に変化しないままでいます。

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

<style>
 #stage {
 width: 480px;
 height: 320px;
 position: relative;
 border: 2px solid black;
 }

 canvas {
 position: absolute;
 }
 #ui-layer {
 z-index: 3;
 }
 #game-layer {
 z-index: 2;
 }
 #background-layer {
 z-index: 1;
 }
</style>
```

### 大きな背景画像に CSS を使用する

静止した背景画像がある場合は、ただの `<div>` に CSS の `background` プロパティを使用し、キャンバスの下に配置することで描画することができます。これにより、大きな画像を毎回キャンバスに描画する処理を避けます。

### CSS 座標変換を使用してキャンバスを拡大縮小する

CSS 座標変換は、 GPU を使用しますのでより高速です。もっともよいのは拡大縮小しないことですが、そうでなければ大きなキャンバスを縮小するよりも小さなキャンバスを拡大したほうが良好です。

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

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

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

### 透過をやめる

アプリケーションがキャンバスを使用していて背後のものを透過させる必要がない場合は、 `HTMLCanvasElement.getContext()` で描画コンテキストを生成する際に `alpha` オプションを `false` に設定しましょう。この情報を使用してブラウザーが描画を最適化する可能性があります。

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

### 高解像度のディスプレイでの拡大縮小

高解像度のディスプレイでは、キャンバスのアイテムがぼやけて見えることがあります。多くの解決策がありますが、まず簡単な方法は、キャンバスの属性、スタイル、およびコンテキストのスケールを使用してキャンバスのサイズを同時に拡大/縮小することです。

```js
// Get the DPR and size of the canvas
var dpr = window.devicePixelRatio;
var rect = canvas.getBoundingClientRect();

// Set the "actual" size of the canvas
canvas.width = rect.width \* dpr;
canvas.height = rect.height \* dpr;

// Scale the context to ensure correct drawing operations
ctx.scale(dpr, dpr);

// Set the "drawn" size of the canvas
canvas.style.width = rect.width + "px";
canvas.style.height = rect.height + "px";
```

### その他の TIPS

* キャンバスの呼び出しをひとまとめにします。たとえば、複数に分割した線分ではなくポリラインを描画します。
* 不必要なキャンバスの状態変更を避けます。
* 新しい状態の全体を描画せずに、スクリーンの差分だけを描画します。
* 可能な限り `shadowBlur` プロパティを避けます。
* 可能な限りテキストレンダリングを避けます。
* キャンバスをクリアーする別の方法を試します (`clearRect()` 対 `fillRect()` 対キャンバスのリサイズ)
* アニメーションで `window.setInterval()` の代わりに `window.requestAnimationFrame()` を使用します。
* 高負荷な物理演算ライブラリーに注意してください。
関連情報
----

* Improving HTML5 Canvas Performance – HTML5 Rocks
* Optimizing your JavaScript game for Firefox OS – Mozilla Hacks
* « 前のページ
* 次のページ »


ExtendableEvent.waitUntil() - Web API

ExtendableEvent.waitUntil()
===========================

**`ExtendableEvent.waitUntil()`** メソッドは、作業が進行中であることをイベントディスパッチャーに通知します。 また、その作業が成功したかどうかを検出するためにも使用できます。 サービスワーカーの場合、 `waitUntil()` は、プロミスが決定するまで作業が進行中であることをブラウザーに通知し、サービスワーカーがその作業を完了させたい場合にサービスワーカーを終了させません。

サービスワーカーの `install` イベントは、 `waitUntil()` を使用して、タスクが完了するまでサービスワーカーをインストール中 (`installing`) の段階に保持します。 `waitUntil()` に渡されたプロミスが拒否された場合、インストールは失敗と見なされ、インストール中のサービスワーカーは破棄されます。 これは主に、依存するすべてのコアキャッシュが正常に読み込まれるまで、サービスワーカーがインストール済み (installed) と見なされないようにするために使用します。

サービスワーカーの `activate` イベントは、`waitUntil()` を使用して、`waitUntil()` に渡されたプロミスが解決するまで、`fetch` や `push` などの機能イベントをバッファリングします。 これにより、サービスワーカーはデータベーススキーマを更新し、古いキャッシュを削除する時間を確保できるため、他のイベントは完全にアップグレードされた状態に依存できます。

`waitUntil()` メソッドは、最初はイベントコールバック内で呼び出す必要がありますが、その後、すべてのプロミスが解決するまで、複数回呼び出すことができます。

**メモ:** 上記の段落で説明した動作は、 Firefox 43 で修正されました（Firefox バグ 1180274 を参照）。

構文
--

```js
waitUntil(promise)
```

### 引数

`Promise` です。

### 返値

なし (`undefined`)。

例
-

サービスワーカーの `install` イベント内で `waitUntil()` を使用します。

```js
addEventListener("install", (event) => {
  const preCache = async () => {
    const cache = await caches.open("static-v1");
    return cache.addAll(["/", "/about/", "/static/styles.css"]);
  };
  event.waitUntil(preCache());
});
```

仕様書
---

| Specification |
| --- |
| Service Workers # dom-extendableevent-waituntil |

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

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

関連情報
----

* サービスワーカーの使用
* ServiceWorker の準備はできていますか？（英語）
* `Promise`


ExtendableEvent() - Web API

ExtendableEvent()
=================

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

構文
--

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

### 引数

`type`

文字列で、このイベントの名前を指定します。大文字小文字を区別します。

`options` 省略可

*`Event()` で定義されるプロパティに加え*、イベントオブジェクトに適用したい任意のカスタム設定を含むことができるオブジェクトです。
 現在、使用可能なオプションは必須ではありませんが、これは異なる形の派生イベント間で前方互換性を保つために定義されています。

### 返値

新しい `ExtendableEvent` オブジェクト。

仕様書
---

| Specification |
| --- |
| Service Workers # dom-extendableevent-extendableevent |

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

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

関連情報
----

* サービスワーカーの使用
* サービスワーカーの基本的なコード例
* ServiceWorker の準備はできていますか？（英語）
* `Promise`
* ウェブワーカーの使用


SyncEvent.SyncEvent() - Web API

SyncEvent.SyncEvent()
=====================

**非標準:** この機能は標準ではなく、標準化の予定もありません。公開されているウェブサイトには使用しないでください。ユーザーによっては使用できないことがあります。実装ごとに大きな差があることもあり、将来は振る舞いが変わるかもしれません。

**`SyncEvent()`** コンストラクタは、新規の `SyncEvent` オブジェクトを作成します。

構文
--
```

var mySyncEvent = new SyncEvent(type, init)
```

### パラメータ

*type*

イベントの型。.

*init* 省略可

イベントオブジェクトに適用するカスタム設定を含むオプションオブジェクト。オプションは次の通りです:

* `tag`: この `SyncEvent` の開発者が定義した一意の識別子。
* `lastChance`: `Boolean` は、現在の試行後にユーザーエージェントが同期の試行をこれ以上行わないことを示しています。

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

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


SyncEvent.lastChance - Web API

SyncEvent.lastChance
====================

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

`SyncEvent` インターフェイスの **`SyncEvent.lastChance`** 読み取り専用プロパティは、現在の試行後にユーザーエージェントが同期を試行しない場合に `true` を返します。 これは、 `SyncEvent()` コンストラクタの `lastChance` パラメータに渡される値です。

構文
--
```

var lastChance = SyncEvent.lastChance
```

### 値

`Boolean` は、現在の試行の後にユーザーエージェントがこれ以上同期を試行しないかどうかを示します。

仕様
--

| 仕様 |
| --- |
| Web Background Synchronization |

ブラウザー実装状況
---------

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


SyncEvent.tag - Web API

SyncEvent.tag
=============

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

`SyncEvent` インターフェイスの **`SyncEvent.tag`** 読み取り専用プロパティは、この `SyncEvent` の開発者定義の識別子を返します。これは、 `SyncEvent()` コンストラクタの `tag` パラメータで渡される値です。

構文
--
```

var tag = SyncEvent.tag
```

### 値

この `SyncEvent` の開発者定義の識別子。

仕様
--

| Specification |
| --- |
| Web Background Synchronization # ref-for-dom-syncevent-tag |

ブラウザー実装状況
---------

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


FileSystemFileEntry.createWriter() - Web API

FileSystemFileEntry.createWriter()
==================================

**非推奨:** この機能は非推奨になりました。まだ対応しているブラウザーがあるかもしれませんが、すでに関連するウェブ標準から削除されているか、削除の手続き中であるか、互換性のためだけに残されている可能性があります。使用を避け、できれば既存のコードは更新してください。このページの下部にある互換性一覧表を見て判断してください。この機能は突然動作しなくなる可能性があることに注意してください。

**非標準:** この機能は標準ではなく、標準化の予定もありません。公開されているウェブサイトには使用しないでください。ユーザーによっては使用できないことがあります。実装ごとに大きな差があることもあり、将来は振る舞いが変わるかもしれません。

`FileSystemFileEntry` インターフェイスの **`createWriter()`** メソッドは、ディレクトリー項目によって表現されるファイルにデータを書き込むために使用します。

構文
--

```js
createWriter(successCallback);
createWriter(successCallback, errorCallback);
```

### 引数

`successCallback`

`FileWriter` が正常に作成されたときに呼び出されるコールバック関数です。 `FileWriter` はコールバック関数の唯一の引数として渡されます。

`errorCallback` 省略可

指定する場合は `FileWriter` を作成しようとしたときにエラーが発生したときに呼び出されるメソッドでなければなりません。このコールバック関数は、エラーを記述した `FileError` オブジェクトを入力として受け取ります。

### 返値

なし (`undefined`)。

例
-

この例では、渡されたディレクトリー項目に対応するファイルに文字列を出力する `writeToFileEntry()` メソッドを用意しています。

```js
function writeToFileEntry(entry, text) {
  entry.createWriter(
    function (fileWriter) {
      let data = Blob([text], { type: "text/plain" });

      fileWriter.write(data);
    },
    function (fileError) {
      /\* do whatever to handle the error \*/
    },
  );
}
```

`createWriter()` の呼び出しの成功コールバック関数は、渡されたテキストを受け取り、渡されたテキストを含む新しい `Blob` オブジェクトを `text/plain` 型で作成します。この Blob は、ファイルに書き込むために `FileWriter` オブジェクトに出力されます。

仕様書
---

この機能はもうどの仕様にも含まれていません。標準化される予定もありません。

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

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

関連情報
----

* ファイルとディレクトリー項目 API
* ファイルとディレクトリー項目 API の紹介


FileSystemFileEntry.file() - Web API

FileSystemFileEntry.file()
==========================

`FileSystemFileEntry` インターフェイスの **`file()`** メソッドは、子のディレクトリー項目が表現しているファイルからデータを読むために使用できる `File` オブジェクトを返します。

構文
--

```js
file(successCallback);
file(successCallback, errorCallback);
```

### 引数

`successCallback`

コールバック関数で、 `File` が正常に作成されたときに呼び出されます。コールバックには、唯一の引数として `File` が渡されます。

`errorCallback` 省略可

指定された場合、 `File` を作成しようとしてエラーが発生したときに呼び出されるメソッドである必要があります。このコールバックは、エラーを記述した `DOMException` オブジェクトを入力として受け取ります。

### 返値

なし (`undefined`)。

例
-

この例ではメソッド `readFile()` を作成し、テキストファイルを読み込み、読み込みが完了すると、指定されたコールバック関数を受け取ったテキスト（文字列）つきで呼び出します。エラーが発生した場合は、指定された（オプションの）エラーコールバック関数が呼び出されます。

```js
function readFile(entry, successCallback, errorCallback) {
  entry.file(function (file) {
    let reader = new FileReader();

    reader.onload = function () {
      successCallback(reader.result);
    };

    reader.onerror = function () {
      errorCallback(reader.error);
    };

    reader.readAsText(file);
  }, errorCallback);
}
```

この関数は `file()` を呼び出し、その成功コールバックとして `FileReader` を使ってファイルをテキストとして読み込むメソッドを指定します。 FileReader の `load` イベントハンドラーは、読み込んだ文字列を `readFile()` メソッドが呼ばれたときに指定した `successCallback` に渡すようにセットアップされています。同様に、`error` ハンドラーは、指定された `errorCallback` を呼び出すようにセットアップされます。

仕様書
---

| Specification |
| --- |
| File and Directory Entries API # dom-filesystemfileentry-file |

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

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

関連情報
----

* ファイルとディレクトリー項目 API
* ファイルとディレクトリー項目 API の紹介


HTMLMediaElement.paused - Web API

HTMLMediaElement.paused
=======================

**`HTMLMediaElement.paused`** プロパティは読み取り専用で、メディア要素が一時停止しているかどうかを示します。

値
-

論理値です。 `true` は一時停止中で、`false` は一時停止していません。

例
-

```js
const obj = document.createElement("video");
console.log(obj.paused); // true
```

仕様書
---

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

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

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

関連情報
----

* 定義している `HTMLMediaElement` インターフェイス


HTMLMediaElement.src - Web API

HTMLMediaElement.src
====================

**`HTMLMediaElement.src`** プロパティは、 HTML のメディア要素の `src` 属性の値を反映します。これは、要素で使用するメディアリソースの URL を示します。

**メモ:** この要素が現在実際に使用しているメディアリソースの URL を知る最善の方法は、`currentSrc` 属性の値を調べることです。 これは、（`<source>` 要素を表す）`HTMLSourceElement` で提供されるリストからの最良または優先メディアリソースの選択も考慮されます。

値
-

文字列で、要素で使用するメディアリソースの URL を表します。このプロパティは HTML 要素の `src` 属性の値を反映します。

例
-

```js
const obj = document.createElement("video");
console.log(obj.src); // ""
```

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-media-src |

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

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

関連情報
----

* 定義している `HTMLMediaElement` インターフェイス


HTMLMediaElement: loadeddata イベント - Web API

HTMLMediaElement: loadeddata イベント
=================================

**`loadeddata`** イベントは、メディアの現在の再生位置のフレームの読み込みが完了したときに発生します。ふつうは最初のフレームです。

**メモ:** なお、このイベントはモバイルやタブレットにおいて、ブラウザーの設定でデータセーバーがオンになっていると発生しません。

構文
--

このイベントを `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

一般的な `Event` です。

例
-

これらの例では、 HTMLMediaElement の `loadeddata` イベントにイベントリスナーを追加し、イベントが発生してイベントハンドラーが動作したときにメッセージを投稿します。

`addEventListener()` を使用する場合:

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

video.addEventListener("loadeddata", (event) => {
  console.log(
    "Yay! The readyState just increased to " +
      "HAVE\_CURRENT\_DATA or greater for the first time.",
  );
});
```

`onloadeddata` イベントハンドラープロパティを使用する場合:

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

video.onloadeddata = (event) => {
  console.log(
    "Yay! The readyState just increased to " +
      "HAVE\_CURRENT\_DATA or greater for the first time.",
  );
};
```

仕様書
---

| Specification |
| --- |
| HTML Standard # event-media-loadeddata |
| HTML Standard # handler-onloadeddata |

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

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

関連イベント
------

* HTMLMediaElement `playing` イベント
* HTMLMediaElement `waiting` イベント
* HTMLMediaElement `seeking` イベント
* HTMLMediaElement `seeked` イベント
* HTMLMediaElement `ended` イベント
* HTMLMediaElement `loadedmetadata` イベント
* HTMLMediaElement `loadeddata` イベント
* HTMLMediaElement `canplay` イベント
* HTMLMediaElement `canplaythrough` イベント
* HTMLMediaElement `durationchange` イベント
* HTMLMediaElement `timeupdate` イベント
* HTMLMediaElement `play` イベント
* HTMLMediaElement `pause` イベント
* HTMLMediaElement `ratechange` イベント
* HTMLMediaElement `volumechange` イベント
* HTMLMediaElement `suspend` イベント
* HTMLMediaElement `emptied` イベント
* HTMLMediaElement `stalled` イベント
関連情報
----

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


HTMLMediaElement.duration - Web API

HTMLMediaElement.duration
=========================

`HTMLMediaElement` の読み取り専用プロパティ **`duration`** は、この要素のメディアの長さを秒単位で表します。

値
-

メディアの再生時間を秒単位で示す倍精度浮動小数点値。メディアデータがない場合、値 `NaN` を返します。ライブメディアストリームのように、要素のメディアの再生時間が不明な場合、 `duration` の値は `+Infinity` となります。

例
-

```js
const obj = document.createElement("video");
console.log(obj.duration); // NaN
```

仕様書
---

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

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

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

関連情報
----

* ウェブメディア技術
* `HTMLMediaElement.currentTime`: メディアの現在の再生位置
* `<audio>` および `<video>` 要素


HTMLMediaElement: ended イベント - Web API

HTMLMediaElement: ended イベント
============================

`ended` イベントは、メディアの終わりに達したため、またはそれ以上利用できるデータがないために再生またはストリーミングが停止したときに発生します。

このイベントは、 `HTMLMediaElement`（`<audio>` および `<video>`）においてメディアの再生がメディアの最後に到達して終了した時に、 `ended` が発生します。

このイベントはキャンセル不可で、バブリングしません。

構文
--

このイベントを `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

一般的な `Event` です。

例
-

これらの例では、`HTMLMediaElement` の `ended` イベントのイベントリスナーを追加し、そのイベントハンドラがイベントの発生に反応したときにメッセージを投稿します。

`addEventListener()` を使用する場合:

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

video.addEventListener("ended", (event) => {
  console.log(
    "1）動画が終了した、または 2）それ以上データがない" +
      "ため、動画が停止しました。",
  );
});
```

`onended` イベントハンドラープロパティを使用する場合:

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

video.onended = (event) => {
  console.log(
    "1）動画が終了した、または 2）それ以上データがない" +
      "ため、動画が停止しました。",
  );
};
```

仕様書
---

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

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

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

関連イベント
------

* HTMLMediaElement `playing` イベント
* HTMLMediaElement `waiting` イベント
* HTMLMediaElement `seeking` イベント
* HTMLMediaElement `seeked` イベント
* HTMLMediaElement `ended` イベント
* HTMLMediaElement `loadedmetadata` イベント
* HTMLMediaElement `loadeddata` イベント
* HTMLMediaElement `canplay` イベント
* HTMLMediaElement `canplaythrough` イベント
* HTMLMediaElement `durationchange` イベント
* HTMLMediaElement `timeupdate` イベント
* HTMLMediaElement `play` イベント
* HTMLMediaElement `pause` イベント
* HTMLMediaElement `ratechange` イベント
* HTMLMediaElement `volumechange` イベント
* HTMLMediaElement `suspend` イベント
* HTMLMediaElement `emptied` イベント
* HTMLMediaElement `stalled` イベント
関連情報
----

* `HTMLAudioElement`
* `HTMLVideoElement`
* `<audio>`
* `<video>`
* メディアキャプチャとストリーム
    + メディアキャプチャとストリーム: ended イベント
* ウェブオーディオ API
    + ウェブオーディオ API: ended イベント


HTMLMediaElement.sinkId - Web API

HTMLMediaElement.sinkId
=======================

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

**`HTMLMediaElement.sinkId`** は読み取り専用プロパティで、出力を配信する音声機器の固有の ID である文字列を返します。ユーザーエージェントの既定で使用されている場合は、空文字列を返します。この ID は `MediaDevices.enumerateDevices()`、`id-multimedia`、`id-communications` から返される値のいずれかである必要があります。

値
-

文字列です。

仕様書
---

| Specification |
| --- |
| Audio Output Devices API # dom-htmlmediaelement-sinkid |

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

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


HTMLMediaElement: suspend イベント - Web API

HTMLMediaElement: suspend イベント
==============================

`suspend` イベントは、メディアデータの読み込みが中断されたときに発生します。

このイベントはキャンセル不可で、バブリングしません。

構文
--

このイベントを `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

一般的な `Event` です。

例
-

これらの例では、`HTMLMediaElement` の `suspend` イベントのイベントリスナーを追加し、そのイベントハンドラがイベントの発生に反応したときにメッセージを投稿します。

`addEventListener()` を使用する場合:

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

video.addEventListener("suspend", (event) => {
  console.log("データの読み込みが中断されました。");
});
```

`onsuspend` イベントハンドラープロパティを使用する場合:

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

video.onsuspend = (event) => {
  console.log("データの読み込みが中断されました。");
};
```

仕様書
---

| Specification |
| --- |
| HTML Standard # event-media-suspend |
| HTML Standard # handler-onsuspend |

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

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

関連イベント
------

* HTMLMediaElement `playing` イベント
* HTMLMediaElement `waiting` イベント
* HTMLMediaElement `seeking` イベント
* HTMLMediaElement `seeked` イベント
* HTMLMediaElement `ended` イベント
* HTMLMediaElement `loadedmetadata` イベント
* HTMLMediaElement `loadeddata` イベント
* HTMLMediaElement `canplay` イベント
* HTMLMediaElement `canplaythrough` イベント
* HTMLMediaElement `durationchange` イベント
* HTMLMediaElement `timeupdate` イベント
* HTMLMediaElement `play` イベント
* HTMLMediaElement `pause` イベント
* HTMLMediaElement `ratechange` イベント
* HTMLMediaElement `volumechange` イベント
* HTMLMediaElement `suspend` イベント
* HTMLMediaElement `emptied` イベント
* HTMLMediaElement `stalled` イベント
関連情報
----

* `HTMLAudioElement`
* `HTMLVideoElement`
* `<audio>`
* `<video>`
* ウェブオーディオ API


HTMLMediaElement.videoTracks - Web API

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

**`videoTracks`** は `HTMLMediaElement` オブジェクトの読み取り専用プロパティで、メディア要素の動画トラックを表すすべての `VideoTrack` オブジェクトを列挙した `VideoTrackList` オブジェクトを返します。

返されたリストは*生きて*います。つまり、トラックがメディア要素に追加されたり取り除かれたりすると、リストの内容は動的に変化します。 リストへの参照を取得したら、新しい動画トラックが追加されたのか既存のトラックが取り除かれたのかを検出するために変更を監視できます。 メディア要素のトラックリストへの変更を監視する方法の詳細については、VideoTrackList のイベントを参照してください。

値
-

メディア要素に含まれる動画トラックのリストを表す `VideoTrackList` オブジェクト。 トラックのリストは、配列記法や、オブジェクトの `getTrackById()` メソッドを使ってアクセスできます。

各トラックは、トラックに関する情報を提供する `VideoTrack` オブジェクトによって表されます。

仕様書
---

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

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

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

関連情報
----

* 定義している `HTMLMediaElement` インターフェイス
* `<video>`
* `VideoTrack` および `VideoTrackList`


HTMLMediaElement.setSinkId() - Web API

HTMLMediaElement.setSinkId()
============================

**`HTMLMediaElement.setSinkId()`** メソッドは、出力に使用するオーディオ機器の ID を設定し、 `Promise` を返します。
 これは、アプリケーションが指定された機器を使用することを許可されている場合にのみ動作します。

構文
--

```js
setSinkId(sinkId)
```

### 引数

`sinkId`

オーディオ出力機器の `MediaDeviceInfo.deviceId` です。

### 返値

`Promise` で、 `undefined` に解決します。

### 例外

`NotAllowedError` `DOMException`

`speaker-selection` 許可ポリシーが音声出力の使用をブロックするために使用された場合に返されます。

`NotFoundError` `DOMException`

`deviceId` がどの音声機器にも一致しない場合に返されます。

`AbortError` `DOMException`

音声出力機器から新しい音声機器への切り替えに失敗した場合に返されます。

例
-

```js
const devices = await navigator.mediaDevices.enumerateDevices();
const audioDevice = devices.find((device) => device.kind === "audiooutput");
const audio = document.createElement("audio");
await audio.setSinkId(audioDevice.deviceId);
console.log(`Audio is being played on ${audio.sinkId}`);
```

仕様書
---

| Specification |
| --- |
| Audio Output Devices API # dom-htmlmediaelement-setsinkid |

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

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


HTMLMediaElement: waiting イベント - Web API

HTMLMediaElement: waiting イベント
==============================

`waiting` イベントは、一時的にデータが欠落したために再生が停止したときに発生します。

このイベントはキャンセル不可で、バブリングしません。

構文
--

このイベントを `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

一般的な `Event` です。

例
-

これらの例は、 HTMLMediaElement の `waiting` イベントのイベントリスナーを追加し、イベントの発生によりイベントハンドラーが動作したときにメッセージを登録します。

`addEventListener()` を使用する場合

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

video.addEventListener("waiting", (event) => {
  console.log("Video is waiting for more data.");
});
```

`onwaiting` イベントハンドラープロパティを使用する場合

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

video.onwaiting = (event) => {
  console.log("Video is waiting for more data.");
};
```

仕様書
---

| Specification |
| --- |
| HTML Standard # event-media-waiting |
| HTML Standard # handler-onwaiting |

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

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

関連イベント
------

* HTMLMediaElement `playing` イベント
* HTMLMediaElement `waiting` イベント
* HTMLMediaElement `seeking` イベント
* HTMLMediaElement `seeked` イベント
* HTMLMediaElement `ended` イベント
* HTMLMediaElement `loadedmetadata` イベント
* HTMLMediaElement `loadeddata` イベント
* HTMLMediaElement `canplay` イベント
* HTMLMediaElement `canplaythrough` イベント
* HTMLMediaElement `durationchange` イベント
* HTMLMediaElement `timeupdate` イベント
* HTMLMediaElement `play` イベント
* HTMLMediaElement `pause` イベント
* HTMLMediaElement `ratechange` イベント
* HTMLMediaElement `volumechange` イベント
* HTMLMediaElement `suspend` イベント
* HTMLMediaElement `emptied` イベント
* HTMLMediaElement `stalled` イベント
関連情報
----

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


HTMLMediaElement: play イベント - Web API

HTMLMediaElement: play イベント
===========================

`play` メソッドは `autoplay` 属性の結果として、`paused` プロパティが `true` から `false` に変更されたときに発生します。

このイベントはキャンセル不可で、バブリングしません。

構文
--

このイベントを `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

一般的な `Event` です。

例
-

これらの例では、`HTMLMediaElement` の `play` イベントのイベントリスナーを追加し、そのイベントハンドラがイベントの発生に反応したときにメッセージを投稿します。

`addEventListener()` を使用する場合:

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

video.addEventListener("play", (event) => {
  console.log(
    "Boolean の paused プロパティは false になりました。 " +
      "play() メソッドが呼び出されたか、autoplay 属性が切り替えられました。",
  );
});
```

`onplay` イベントハンドラープロパティを使用する場合:

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

video.onplay = (event) => {
  console.log(
    "Boolean の paused プロパティは false になりました。 " +
      "play() メソッドが呼び出されたか、autoplay 属性が切り替えられました。",
  );
};
```

仕様書
---

| Specification |
| --- |
| HTML Standard # event-media-play |
| HTML Standard # handler-onplay |

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

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

関連イベント
------

* HTMLMediaElement `playing` イベント
* HTMLMediaElement `waiting` イベント
* HTMLMediaElement `seeking` イベント
* HTMLMediaElement `seeked` イベント
* HTMLMediaElement `ended` イベント
* HTMLMediaElement `loadedmetadata` イベント
* HTMLMediaElement `loadeddata` イベント
* HTMLMediaElement `canplay` イベント
* HTMLMediaElement `canplaythrough` イベント
* HTMLMediaElement `durationchange` イベント
* HTMLMediaElement `timeupdate` イベント
* HTMLMediaElement `play` イベント
* HTMLMediaElement `pause` イベント
* HTMLMediaElement `ratechange` イベント
* HTMLMediaElement `volumechange` イベント
* HTMLMediaElement `suspend` イベント
* HTMLMediaElement `emptied` イベント
* HTMLMediaElement `stalled` イベント
関連情報
----

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


HTMLMediaElement.textTracks - Web API

HTMLMediaElement.textTracks
===========================

**`textTracks`** は `HTMLMediaElement` オブジェクトの読み取り専用プロパティで、メディア要素のテキストトラックを表す `TextTrackList` (en-US) オブジェクトをすべて、テキストトラックのリストと同じ順序で掲載しているオブジェクトを返します。

`addtrack` と `removetrack` イベントを使用すると、`<audio>` や `<video>` 要素へのトラックの追加や削除を検出することができます。しかし、これらのイベントはメディア要素自体に直接送られるわけではありません。代わりに、要素に追加されたトラックの種類に対応する `HTMLMediaElement` のトラックリストオブジェクトに送られます。

返されたリストは生きています。つまり、メディア要素にトラックが追加されたり削除されたりすると、リストのコンテンツは動的に変更されます。一度リストへの参照を保有すると、新しいテキストトラックが追加されたり、既存のものが削除されたりしたときにそれを検出するために、変更を監視することができます。

メディア要素のトラックリストの変更を監視する方法については、TextTrackList のイベント (en-US)を参照してください。

値
-

メディア要素に含まれるテキストトラックのリストを表す `TextTrackList` (en-US) オブジェクトです。トラックのリストは、`textTracks[n]` を使用してこのオブジェクトのテキストトラックのリストから n 番目のテキストトラックを取得したり、 `textTracks`.`getTrackById()` (en-US) メソッドを使用してアクセスしたりすることができます。

それぞれのトラックは `TextTrack` オブジェクトで表され、トラックに関する情報を提供します。

例
-

`<video>` に子要素としていくつかの `<track>` が含まれているものから始めましょう。

```html
<video controls poster="/images/sample.gif">
  <source src="sample.mp4" type="video/mp4" />
  <source src="sample.ogv" type="video/ogv" />
  <track kind="captions" src="sampleCaptions.vtt" srclang="en" />
  <track kind="descriptions" src="sampleDescriptions.vtt" srclang="en" />
  <track kind="chapters" src="sampleChapters.vtt" srclang="en" />
  <track kind="subtitles" src="sampleSubtitles\_de.vtt" srclang="de" />
  <track kind="subtitles" src="sampleSubtitles\_en.vtt" srclang="en" />
  <track kind="subtitles" src="sampleSubtitles\_ja.vtt" srclang="ja" />
  <track kind="subtitles" src="sampleSubtitles\_oz.vtt" srclang="oz" />
  <track kind="metadata" src="keyStage1.vtt" srclang="en" label="Key Stage 1" />
  <track kind="metadata" src="keyStage2.vtt" srclang="en" label="Key Stage 2" />
  <track kind="metadata" src="keyStage3.vtt" srclang="en" label="Key Stage 3" />
</video>
```

`HTMLMediaElement.textTracks` は `textTracksList` を返すので、それを反復処理することができます。ここでは、それぞれの英語トラックのすべてのプロパティをコンソールに表示しています。

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

for (const track of tracks) {
  if (track.language === "en") {
    console.dir(track);
  }
}
```

仕様書
---

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

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

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

関連情報
----

* 定義している `HTMLMediaElement` インターフェイス
* `<video>` および `<audio>`
* `VideoTrack` および `VideoTrackList`
* `AudioTrack` および `AudioTrackList`
* VideoTrackList の
 `change`、
 `addtrack`、
 `removetrack`
 イベント
* AudioTrackList の
 `change`、
 `addtrack`、
 `removetrack`
 イベント


HTMLMediaElement.controller - Web API

HTMLMediaElement.controller
===========================

**非推奨:** この機能は非推奨になりました。まだ対応しているブラウザーがあるかもしれませんが、すでに関連するウェブ標準から削除されているか、削除の手続き中であるか、互換性のためだけに残されている可能性があります。使用を避け、できれば既存のコードは更新してください。このページの下部にある互換性一覧表を見て判断してください。この機能は突然動作しなくなる可能性があることに注意してください。

**非標準:** この機能は標準ではなく、標準化の予定もありません。公開されているウェブサイトには使用しないでください。ユーザーによっては使用できないことがあります。実装ごとに大きな差があることもあり、将来は振る舞いが変わるかもしれません。

**`HTMLMediaElement.controller`** プロパティは、要素に割り当てられたメディアコントローラーを表します。

値
-

`MediaController` オブジェクトまたは、要素にメディアコントローラーが割り当てられていない場合は `null`。既定値は `null` です。

仕様書
---

2016 年に、 Media Controller の全機能が HTML 仕様書から削除されました。標準化する予定がなくなりました。

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

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


HTMLMediaElement: ratechange イベント - Web API

HTMLMediaElement: ratechange イベント
=================================

`ratechange` イベントは、再生レートが変更されたときに発生します。

このイベントはキャンセル不可で、バブリングしません。

構文
--

このイベントを `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

一般的な `Event` です。

例
-

これらの例では、`HTMLMediaElement` の `ratechange` イベントのイベントリスナーを追加し、そのイベントハンドラがイベントの発生に反応したときにメッセージを投稿します。

`addEventListener()` を使用する場合:

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

video.addEventListener("ratechange", (event) => {
  console.log("再生レートが変わりました。");
});
```

`onratechange` イベントハンドラープロパティを使用する場合:

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

video.onratechange = (event) => {
  console.log("再生レートが変わりました。");
};
```

仕様書
---

| Specification |
| --- |
| HTML Standard # event-media-ratechange |
| HTML Standard # handler-onratechange |

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

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

関連イベント
------

* HTMLMediaElement `playing` イベント
* HTMLMediaElement `waiting` イベント
* HTMLMediaElement `seeking` イベント
* HTMLMediaElement `seeked` イベント
* HTMLMediaElement `ended` イベント
* HTMLMediaElement `loadedmetadata` イベント
* HTMLMediaElement `loadeddata` イベント
* HTMLMediaElement `canplay` イベント
* HTMLMediaElement `canplaythrough` イベント
* HTMLMediaElement `durationchange` イベント
* HTMLMediaElement `timeupdate` イベント
* HTMLMediaElement `play` イベント
* HTMLMediaElement `pause` イベント
* HTMLMediaElement `ratechange` イベント
* HTMLMediaElement `volumechange` イベント
* HTMLMediaElement `suspend` イベント
* HTMLMediaElement `emptied` イベント
* HTMLMediaElement `stalled` イベント
関連情報
----

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


HTMLMediaElement: seeking イベント - Web API

HTMLMediaElement: seeking イベント
==============================

`seeking` イベントは、シーク操作が開始されると発生します。つまり、論理属性の `seeking` を `true` に変更し、メディアが新しい位置をシークしている状態になります。

このイベントはキャンセル不可で、バブリングしません。

構文
--

このイベントを `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

一般的な `Event` です。

例
-

これらの例では、`HTMLMediaElement` の `seeking` イベントのイベントリスナーを追加し、そのイベントハンドラがイベントの発生に反応したときにメッセージを投稿します。

`addEventListener()` を使用する場合:

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

video.addEventListener("seeking", (event) => {
  console.log("動画は新しい位置をシーク中です。");
});
```

`onseeking` イベントハンドラープロパティを使用する場合:

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

video.onseeking = (event) => {
  console.log("動画は新しい位置をシーク中です。");
};
```

仕様書
---

| Specification |
| --- |
| HTML Standard # event-media-seeking |
| HTML Standard # handler-onseeking |

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

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

関連イベント
------

* HTMLMediaElement `playing` イベント
* HTMLMediaElement `waiting` イベント
* HTMLMediaElement `seeking` イベント
* HTMLMediaElement `seeked` イベント
* HTMLMediaElement `ended` イベント
* HTMLMediaElement `loadedmetadata` イベント
* HTMLMediaElement `loadeddata` イベント
* HTMLMediaElement `canplay` イベント
* HTMLMediaElement `canplaythrough` イベント
* HTMLMediaElement `durationchange` イベント
* HTMLMediaElement `timeupdate` イベント
* HTMLMediaElement `play` イベント
* HTMLMediaElement `pause` イベント
* HTMLMediaElement `ratechange` イベント
* HTMLMediaElement `volumechange` イベント
* HTMLMediaElement `suspend` イベント
* HTMLMediaElement `emptied` イベント
* HTMLMediaElement `stalled` イベント
関連情報
----

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


HTMLMediaElement.pause() - Web API

HTMLMediaElement.pause()
========================

**`HTMLMediaElement.pause()`** メソッドはメディアの再生を一時停止します。 メディアがすでに一時停止状態にある場合、このメソッドは効果がありません。

構文
--

```js
pause()
```

### 引数

なし。

### 返値

なし (`undefined`)。

### 例外

なし。

仕様書
---

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

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

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


HTMLMediaElement: error イベント - Web API

HTMLMediaElement: error イベント
============================

**`error`** イベントは、リソースがエラーのために読み込めなかったときに発生します（例えば、ネットワーク接続の問題など）。

このイベントはキャンセル不可で、バブリングしません。

構文
--

このイベントを `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

一般的な `Event` です。

例
-

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

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

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

仕様書
---

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

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

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

関連情報
----

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


HTMLMediaElement.defaultPlaybackRate - Web API

HTMLMediaElement.defaultPlaybackRate
====================================

**`HTMLMediaElement.defaultPlaybackRate`** プロパティは、メディアの既定の再生速度を示します。

値
-

double 型です。 `1.0` が「標準速度」で、 `1.0` より小さい値はメディアの再生速度が標準より遅くなり、値を大きくすると再生速度が速くなります。

### 例外

`NotSupportedError` `DOMException`

指定された値に対応していない場合に発生します。

例
-

```js
const obj = document.createElement("video");
console.log(obj.defaultPlaybackRate); // 1
```

仕様書
---

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

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

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

関連情報
----

* 定義している `HTMLMediaElement` インターフェイス


HTMLMediaElement.play() - Web API

HTMLMediaElement.play()
=======================

`HTMLMediaElement` の **`play()`** メソッドは、メディアの再生を開始しようとします。
 再生が正常に開始されると解決するプロミス (`Promise`) を返します。

パーミッションの問題など、何らかの理由で再生を開始しなかった場合、そのプロミスは拒否されます。

構文
--

```js
play()
```

### 引数

なし。

### 返値

再生が開始されたときに解決される、または何らかの理由で再生を開始できない場合は拒否されるプロミス (`Promise`) です。

**メモ:** 古いブラウザーは `play()` から値を返さない可能性があります。

### 例外

プロミスの**拒否ハンドラー**は、 `DOMException` オブジェクトと唯一の引数として渡された例外名で呼び出されます（従来の例外が投げられるのとは対照的です）。想定されるエラーは以下の通りです。

`NotAllowedError` `DOMException`

 ユーザーエージェント（ブラウザー）またはオペレーティングシステムが、現在のコンテキストまたは状況においてメディアの再生を許可しない場合に提供されます。
 ブラウザーは、例えば許可ポリシー のため、ユーザーが明示的に "play" ボタンをクリックしてメディア再生を始めるように要求することがあります。

`NotSupportedError` `DOMException`

メディアソース（例えば `MediaStream`, `MediaSource`, `Blob`, または `File` として指定可能）が、対応しているメディア形式を表していない場合に提供されます。

ブラウザーの実装の詳細、メディアプレーヤーの実装などによっては、他の例外が報告されることがあります。

使用上のメモ
------

「自動再生 (autoplay)」という用語は通常、読み込まれるとすぐにメディアの再生を開始するページを指すと考えられていますが、ウェブブラウザーの自動再生ポリシーは、`play()` の呼び出しを含むスクリプト起動によるメディアの再生にも適用されます。

ユーザーエージェントが自動またはスクリプト起動によるメディアの再生を許可しないように設定されている場合、`play()` を呼び出すと返されたプロミスが直ちに `NotAllowedError` で拒否されます。 ウェブサイトはこの状況に対処する準備をしておくべきです。 例えば、サイトには再生が自動的に開始されたことを前提としたユーザーインターフェイスを表示するのではなく、返されたプロミスが解決されたか拒否されたかに基づいて UI を更新する必要があります。 詳しくは、以下の例を参照してください。

**メモ:** `play()` メソッドを使用すると、ユーザーはメディアの再生を許可するように要求され、返されたプロミスが解決されるまでに遅延が生じる可能性があります。 コードが即座の応答を期待していないことを確認してください。

自動再生および自動再生のブロックの詳細については、メディアおよびウェブオーディオ API の自動再生ガイドを参照してください。

例
-

この例では、再生が開始されたことを確認する方法と、ブロックされた自動再生を適切に処理する方法を示します。

```js
let videoElem = document.getElementById("video");
let playButton = document.getElementById("playbutton");

playButton.addEventListener("click", handlePlayButton, false);
playVideo();

async function playVideo() {
  try {
    await videoElem.play();
    playButton.classList.add("playing");
  } catch (err) {
    playButton.classList.remove("playing");
  }
}

function handlePlayButton() {
  if (videoElem.paused) {
    playVideo();
  } else {
    videoElem.pause();
    playButton.classList.remove("playing");
  }
}
```

この例では、動画の再生は非同期 (`async`) 関数によってオンとオフをトグル切り替えします。動画を再生しようとし、成功した場合は `playButton` 要素のクラス名を `"playing"`（再生中）に設定します。 再生が開始されない場合、`playButton` 要素のクラスはクリアされ、既定の外観に戻ります。 これは、`play()` によって返されたプロミス (`Promise`) の解決または拒否を監視することによって、再生ボタンが実際の再生状態と一致することを保証します。

この例が実行されると、再生のオンとオフを切り替えるために使用する `<video>` 要素への参照を `<button>` と同様に収集することから始めます。 次に、再生トグルボタンの `click` イベントのイベントハンドラーを設定し、`playVideo()` を呼び出して自動的に再生を開始しようとします。

この例を Glitch でリアルタイムで試したり、リミックスしたりすることができます。

仕様書
---

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

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

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

関連情報
----

* ウェブメディア技術
* 学習: 動画と音声のコンテンツ
* メディアおよびウェブオーディオ API の自動再生ガイド
* ウェブオーディオ API の利用


HTMLMediaElement: loadstart イベント - Web API

HTMLMediaElement: loadstart イベント
================================

**`loadstart`** イベントは、ブラウザーがリソースの読み込みを開始したときに発生します。

構文
--

このイベントを `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

一般的な `Event` です。

例
-

### ライブデモ

#### HTML

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

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

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

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

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

video {
  grid-area: video;
}

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

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

#### JavaScript

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

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

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

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

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

#### 結果

仕様書
---

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

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

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

関連情報
----

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


HTMLMediaElement.mediaGroup - Web API

HTMLMediaElement.mediaGroup
===========================

**非推奨:** この機能は非推奨になりました。まだ対応しているブラウザーがあるかもしれませんが、すでに関連するウェブ標準から削除されているか、削除の手続き中であるか、互換性のためだけに残されている可能性があります。使用を避け、できれば既存のコードは更新してください。このページの下部にある互換性一覧表を見て判断してください。この機能は突然動作しなくなる可能性があることに注意してください。

**非標準:** この機能は標準ではなく、標準化の予定もありません。公開されているウェブサイトには使用しないでください。ユーザーによっては使用できないことがあります。実装ごとに大きな差があることもあり、将来は振る舞いが変わるかもしれません。

**`HTMLMediaElement.mediaGroup`** プロパティは HTML の `mediaGroup` 属性を反映し、所属する要素のグループの名前を示します。メディア要素のグループは、共通の `controller` を共有します。

値
-

文字列です。

仕様書
---

2016年、 Media Controller の全機能が HTML 仕様書から削除されました。標準化する予定がなくなりました。

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

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

関連情報
----

* 定義している `HTMLMediaElement` インターフェイス


HTMLMediaElement: canplaythrough イベント - Web API

HTMLMediaElement: canplaythrough イベント
=====================================

`canplaythrough` イベントは、ユーザーエージェントがメディアを再生可能なときに発生し、コンテンツをさらにバッファリングするために再生を停止することなく、メディアを最後まで再生するのに十分なデータが読み込まれたと推定します。

このイベントはキャンセル不可で、バブリングしません。

構文
--

このイベント名を `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

一般の `Event` です。

例
-

これらの例では、 HTMLMediaElement の `canplaythrough` イベントのイベントリスナーを追加し、そのイベントハンドラーがイベントの発生に反応したときにメッセージを投稿します。

`addEventListener()` を使用する場合:

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

video.addEventListener('canplaythrough', (event) => {
  console.log('バッファリングを止めることなく、' +
      '動画全体を再生できると思います。');
});
```

`oncanplaythrough` イベントハンドラープロパティを使用する場合:

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

video.oncanplaythrough = (event) => {
  console.log('バッファリングを止めることなく、' +
      '動画全体を再生できると思います。');
};
```

仕様書
---

| Specification |
| --- |
| HTML Standard # event-media-canplaythrough |
| HTML Standard # handler-oncanplaythrough |

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

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

関連イベント
------

* HTMLMediaElement `playing` イベント
* HTMLMediaElement `waiting` イベント
* HTMLMediaElement `seeking` イベント
* HTMLMediaElement `seeked` イベント
* HTMLMediaElement `ended` イベント
* HTMLMediaElement `loadedmetadata` イベント
* HTMLMediaElement `loadeddata` イベント
* HTMLMediaElement `canplay` イベント
* HTMLMediaElement `canplaythrough` イベント
* HTMLMediaElement `durationchange` イベント
* HTMLMediaElement `timeupdate` イベント
* HTMLMediaElement `play` イベント
* HTMLMediaElement `pause` イベント
* HTMLMediaElement `ratechange` イベント
* HTMLMediaElement `volumechange` イベント
* HTMLMediaElement `suspend` イベント
* HTMLMediaElement `emptied` イベント
* HTMLMediaElement `stalled` イベント
関連情報
----

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


HTMLMediaElement.fastSeek() - Web API

HTMLMediaElement.fastSeek()
===========================

**`HTMLMediaElement.fastSeek()`** メソッドは、精度と引き換えにで新しい時間へのメディアを迅速にシークします。

**メモ:** 正確にシークする必要がある場合は、代わりに `HTMLMediaElement.currentTime` を設定してください。

構文
--

```js
fastSeek(time)
```

### 引数

`time`

倍精度浮動小数点値です。

### 返値

なし (`undefined`)。

例
-

この例では、 video 要素の 20 秒の位置に素早くシークします。

```js
let myVideo = document.getElementById("myVideoElement");

myVideo.fastSeek(20);
```

仕様書
---

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

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

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

関連情報
----

* HTMLMediaElement.currentTime:
 精度を犠牲にすることなくシークを行う


HTMLMediaElement.muted - Web API

HTMLMediaElement.muted
======================

**`HTMLMediaElement.muted`** プロパティは、メディア要素がミュートされているかどうかを示します。

値
-

論理値です。 `true` はミュートされていることを意味し、`false` はミュートされていないことを意味します。

例
-

```js
const obj = document.createElement("video");
console.log(obj.muted); // false
```

仕様書
---

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

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

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

関連情報
----

* 定義している `HTMLMediaElement` インターフェイス
* `HTMLMediaElement.defaultMuted`
* `HTMLMediaElement.volume`


HTMLMediaElement.captureStream() - Web API

HTMLMediaElement.captureStream()
================================

**`captureStream()`** は `HTMLMediaElement` インターフェイスのプロパティで、このメディア要素でレンダリングされているコンテンツのリアルタイムキャプチャをストリーミングしている `MediaStream` オブジェクトを返します。

これは、例えば WebRTC の `RTCPeerConnection` のソースとして使用できます。

構文
--

```js
captureStream()
```

### 引数

なし。

### 返値

他のメディア処理コードによる音声データおよび/または動画データのソースとして、または WebRTC のソースとして使用できる `MediaStream` オブジェクトです。

例
-

この例では、イベントハンドラーが確立されているため、ボタンをクリックすると、ID が `"playback"` のメディア要素のコンテンツの `MediaStream` へのキャプチャを開始します。 これにより、WebRTC を介したストリーミングのソースなど、他の目的にストリームを使用して、動画通話中に録画済みの動画を他の人と共有できるようになります。

```js
document.querySelector(".playAndRecord").addEventListener("click", () => {
  const playbackElement = document.getElementById("playback");
  const captureStream = playbackElement.captureStream();
  playbackElement.play();
});
```

より長くより複雑な例と説明については、メディア要素の記録を参照してください。

仕様書
---

| Specification |
| --- |
| Media Capture from DOM Elements # dom-htmlmediaelement-capturestream |

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

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

### Firefox 特有のメモ

Firefox 51 より前のバージョンでは、 `captureStream()` はソースそれ自体が `MediaStream` であるメディア要素では使用できませんでした（`RTCPeerConnection` を介して受信されるストリームを表示している `<video>` 要素など）。 Firefox 51 以降では機能します。これは、動画要素からストリームをキャプチャし、それを記録するために `MediaRecorder` を使用できることを意味します。 詳細は Firefox バグ 1259788 をご覧ください。

ただし、明確な理由から、Firefox では `captureStream()` に接頭辞が付いて `mozCaptureStream()` となっています。現在の実装には、次のような注目に値するいくつかの奇妙な点があるからです。

* Firefox の実装は現在、メディア要素のソース自体が `MediaStream` である場合にのみ、仕様書での説明通りに動作します。
* メディア要素のソースが `MediaStream` ではない場合、このメソッドからの出力は仕様書と互換性がありません。 そして、キャプチャの開始後にソースを変更した場合、その非互換性のために出力キャプチャストリームは新しいソースデータを受け入れることができません。したがって、新しいソースの `MediaStream` からの `MediaStreamTrack` はキャプチャしたストリームに追加されず、更新されたソースをキャプチャしない出力になります。
* ソースを `MediaStream` に戻すと、トラックをストリームに戻して追加し、期待どおりに機能します。
* `mozCaptureMediaStream()` を `MediaStream` のソースを使用して要素に対して呼び出すと、要素が `MediaStream` を再生している間はトラックのみを含むストリームを返します。
* ソースメディアのないメディア要素で `mozCaptureMediaStream()` を呼び出すと、その互換モードは最初に追加されたソースに基づきます。 例えば、`MediaStream` の場合、キャプチャストリームはそれ以降 MediaStream のソースでのみ機能します。
* `MediaStream` 以外のソースのサポートが仕様に達した時点で、接頭辞なしのメソッドの場合、この特別なふるまいは取り除かれます。 詳細は Firefox バグ 1259788#160 をご覧ください。
関連情報
----

* メディア要素の記録
* MediaStream 収録 API
* `HTMLCanvasElement.captureStream()`
* `MediaStream`
* WebRTC API


HTMLMediaElement.controls - Web API

HTMLMediaElement.controls
=========================

**`HTMLMediaElement.controls`** プロパティは、 HTML の `controls` 属性を反映し、メディア項目を再生するためのユーザーインターフェイスのコントロールを表示するかどうかを制御します。

値
-

論理値です。値が `true` の場合、コントロールが表示されます。

例
-

```js
const obj = document.createElement("video");
obj.controls = true;
```

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-media-controls |

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

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

関連情報
----

* これを定義しているインターフェイスである `HTMLMediaElement`


HTMLMediaElement.seekable - Web API

HTMLMediaElement.seekable
=========================

**`seekable`** は `HTMLMediaElement` オブジェクトの読み取り専用プロパティで、新しい静的な正規化された `TimeRanges` オブジェクトを返します。これは `seekable` プロパティがアクセスされた時点でユーザーエージェントがシーク可能なメディアリソースがあれば、その範囲を表します。

値
-

新しい静的な正規化された `TimeRanges` オブジェクトを返します。これは `seekable` プロパティがアクセスされた時点でユーザーエージェントがシーク可能なメディアリソースがあれば、その範囲を表します。

例
-

```js
const video = document.querySelector("video");
const timeRangesObject = video.seekable;
const timeRanges = [];
// オブジェクトを走査し、配列へ出力
for (let count = 0; count < timeRangesObject.length; count++) {
  timeRanges.push([timeRangesObject.start(count), timeRangesObject.end(count)]);
}
```

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-media-seekable-dev |
| Media Source Extensions™ # htmlmediaelement-extensions |

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

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

関連情報
----

* 定義している `HTMLMediaElement` インターフェイス
* メディアソース拡張 API
* メディアのバッファリング、シーク、時間の範囲 (en-US)


HTMLMediaElement: loadedmetadata イベント - Web API

HTMLMediaElement: loadedmetadata イベント
=====================================

`loadedmetadata` イベントは、メタデータが読み込まれたときに発生します。

構文
--

このイベントを `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

一般的な `Event` です。

例
-

これらの例では、HTMLMediaElement の `loadedmetadata` イベントのイベントリスナーを追加し、そのイベントハンドラがイベントの発生に反応したときにメッセージを投稿します。

`addEventListener()` を使用する場合:

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

video.addEventListener("loadedmetadata", (event) => {
  console.log("メディアとトラックの長さと寸法は現在わかっています。");
});
```

`onloadedmetadata` イベントハンドラープロパティを使用する場合:

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

video.onloadedmetadata = (event) => {
  console.log("メディアとトラックの長さと寸法は現在わかっています。");
};
```

仕様書
---

| Specification |
| --- |
| HTML Standard # event-media-loadedmetadata |
| HTML Standard # handler-onloadedmetadata |

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

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

関連イベント
------

* HTMLMediaElement `playing` イベント
* HTMLMediaElement `waiting` イベント
* HTMLMediaElement `seeking` イベント
* HTMLMediaElement `seeked` イベント
* HTMLMediaElement `ended` イベント
* HTMLMediaElement `loadedmetadata` イベント
* HTMLMediaElement `loadeddata` イベント
* HTMLMediaElement `canplay` イベント
* HTMLMediaElement `canplaythrough` イベント
* HTMLMediaElement `durationchange` イベント
* HTMLMediaElement `timeupdate` イベント
* HTMLMediaElement `play` イベント
* HTMLMediaElement `pause` イベント
* HTMLMediaElement `ratechange` イベント
* HTMLMediaElement `volumechange` イベント
* HTMLMediaElement `suspend` イベント
* HTMLMediaElement `emptied` イベント
* HTMLMediaElement `stalled` イベント
関連情報
----

* `HTMLAudioElement`
* `HTMLVideoElement`
* `<audio>`
* `<video>`
* このイベントは Gecko の 音声 API 拡張の一部です。


HTMLMediaElement.disableRemotePlayback - Web API

HTMLMediaElement.disableRemotePlayback
======================================

**`HTMLMediaElement.disableRemotePlayback`** プロパティは、メディア要素がリモート再生 UI を持つことを許可するかどうかを決定します。

値
-

メディア要素がリモート再生 UI を持つことができるかどうかを示す論理値。（false は「無効ではない」、すなわち「有効」を意味します）

例
-

```js
const obj = document.createElement("audio");
obj.disableRemotePlayback = true;
```

仕様書
---

| Specification |
| --- |
| Remote Playback API # the-disableremoteplayback-attribute |

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

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

関連情報
----

* 定義している `HTMLMediaElement` インターフェイス


HTMLMediaElement.srcObject - Web API

HTMLMediaElement.srcObject
==========================

**`srcObject`** は `HTMLMediaElement` インターフェイスのプロパティで、 `HTMLMediaElement` に関連付けられたメディアソースを提供するオブジェクトを設定または取得します。

このオブジェクトは `MediaStream`、`MediaSource`、`Blob` や（Blob から派生している） `File` です。

**メモ:** 2020 年 3 月現在、 Safari のみが `srcObject` に対して完全に、すなわち `MediaSource`、`MediaStream`、`Blob`、`File` のオブジェクトを値にすることに対応しています。他のブラウザーは `MediaStream` に対応しています。他のブラウザーが追いつくまで、代替として `URL.createObjectURL()` を使用して URL を作成し、それを `HTMLMediaElement.src` に代入するようにしてください（以下の例を参照してください）。さらに、バージョン 108 の Chromium は、専用ワーカーの `MediaSource` オブジェクトを、そのオブジェクトの（ワーカーから転送された） `MediaSourceHandle` (en-US) インスタンスを `srcObject` に割り当てることで装着することに対応しています。

値
-

`MediaStream`、`MediaSource`、`Blob`、`File` オブジェクト。（実際に何が対応されているのかは互換性一覧表を確認してください。)

使用上の注意
------

メディアソース仕様書の古いバージョンでは、オブジェクト URL を作成するために `createObjectURL()` を使用してから、その URL を `src` に設定する必要がありました。 現在は、`MediaStream` を `srcObject` に直接設定できます。

例
-

### 基本的な例

この例では、メディアソースを新しく作成した `<video>` 要素に割り当てています。

```js
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true });
const video = document.createElement("video");
video.srcObject = mediaStream;
```

この例では、新しい `MediaSource` が新しく作成された `<video>` に割り当てられます。

```js
const mediaSource = new MediaSource();
const video = document.createElement("video");
video.srcObject = mediaSource;
```

### src プロパティへの代替の対応

以下の例では、 `srcObject` に対応していない場合、オブジェクト URL を作成して `src` に代入する必要がある古いバージョンのブラウザーに対応しています。

最初に、カメラから取得した `MediaStream` を新しく生成した `<video>` 要素に、古いブラウザーへの代替手段つきで割り当てます。

```js
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true });
const video = document.createElement("video");
if ("srcObject" in video) {
  video.srcObject = mediaStream;
} else {
  // この機能はなくなる予定であるため、新しいブラウザーでは使用を避けてください。
  video.src = URL.createObjectURL(mediaStream);
}
```

次に、新しく作成された `<video>` 要素に、古いブラウザーや `MediaSource` の割り当てにまだ対応していないブラウザーのための代替手段を直接割り当てます。

```js
const mediaSource = new MediaSource();
const video = document.createElement("video");
// 古いブラウザーの場合、srcObject がない場合があります。
if ("srcObject" in video) {
  try {
    video.srcObject = mediaSource;
  } catch (err) {
    if (err.name !== "TypeError") {
      throw err;
    }
    // 対応していても、 MediaStream にしか対応していない場合があります。
    video.src = URL.createObjectURL(mediaSource);
  }
} else {
  video.src = URL.createObjectURL(mediaSource);
}
```

### ワーカーで `MediaSource` を構築し、それをメインスレッドに渡して再生する

専用ワーカー内部で `MediaSource.handle` (en-US) プロパティにアクセスでき、結果として `MediaSourceHandle` (en-US) オブジェクトが `postMessage()` コールによりワーカーを作成したスレッド（この場合はメインスレッド）に転送されます。

```js
// 専用ワーカー内
let mediaSource = new MediaSource();
let handle = mediaSource.handle;
// ワーカーを作成したコンテキストでハンドルを処理する
postMessage({ arg: handle }, [handle]);

mediaSource.addEventListener("sourceopen", () => {
  // MediaSource で sourceopen を待ってから、 SourceBuffer を
  // 作成し、フェッチしたメディアを投入します。 MediaSource は、
  // HTMLMediaElement に接続され、その readyState が
  // "open" になるまで SourceBuffer の作成を受け入れません。
});
```

メインスレッドでは、`message` イベントハンドラーからハンドルを受け取り、 `<video>` に `HTMLMediaElement.srcObject` プロパティを通してそれを追加し、`play` ビデオ追加しています。

```js
worker.addEventListener("message", (msg) => {
  let mediaSourceHandle = msg.data.arg;
  video.srcObject = mediaSourceHandle;
  video.play();
});
```

**メモ:** `MediaSourceHandle` (en-US)s は、共有ワーカーまたはサービスワーカーへの、または共有ワーカーを介した移譲は正常にはできません。

仕様書
---

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

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

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