Canvas APIは、JavaScriptとHTMLの<canvas>要素を使って画像を描くAPIである。

アニメーションやゲーム、データの視覚化、写真のレタッチ、映像のリアルタイム処理などに幅広く使える割に、あまり難しくない(とドキュメントに書いてある)。JavaScriptとHTMLの基本的な知識があれば、入門はやさしいかと思う。

Canvasの使い方

Canvas APIは、以下のような手順で使う。

  1. Webページの任意の場所に<canvas>要素を含める。
  2. JavaScriptを使い、そのDOMオブジェクト(HTMLCanvasElement)を取得する。
  3. HTMLCanvasElementgetContext("2d") メソッドを実行し、コンテキストを取得する。
  4. コンテキストを操作して任意の画像を描画していく。

コンテキストとは

Canvasでいうコンテキストは、対象の<canvas>要素への諸々の描画を操作するためのオブジェクトである。

コンテキストとは、文脈という意味の英単語だ。例えばマウスを右クリックして表示されるメニューはコンテキストメニューと呼ばれる。これは、右クリックされた状況(文脈)に応じて表示されるメニューが変わるためだ。

Canvasで、諸々の描画を操作するためのオブジェクトがコンテキストと呼ばれる理由も、これと似ている。<canvas>要素はいつでも<canvas>要素だが、その描画内容は使用者の意図(文脈)に応じて異なる。だから、その意図をまとめるオブジェクトをコンテキストと表現する。のだと思う。

getContext()メソッド

getContext()メソッドは以下の2つの引数を取り、後述するコンテキストオブジェクトを返す。

引数の種類 概要
contextType コンテキストの種類を指定。"2d""webgl""webgl2""webgpu""bitmaprenderer"のいずれか。
contextAttributes contextTypeで指定した種類に応じて、必要な属性値を渡す。2dコンテキストのための属性と、WebGLコンテキストのための属性がある(各属性値の詳細

コンテキストオブジェクト

getContext()は、第一引数に渡された値によって、以下のいずれかのコンテキストオブジェクトを返す。

コンテキストオブジェクトは、その種類に応じた描画用のメソッドを保持している。

オブジェクトの種類 概要
CanvasRenderingContext2D 2D画像の描画機能を提供。
WebGLRenderingContext OpenGL ES 2.0に基づく、基本的な3D画像の描画機能を提供。
WebGL2RenderingContext OpenGL ES 3.0に基づく、基本的な3D画像の描画機能を提供。
GPUCanvasContext WebGPU APIの一部で、WebGLよりモダンで高性能な描画機能を提供する。
ImageBitmapRenderingContext ビットマップの高速な描画機能を提供。

画像を描画する際は、これらのオブジェクトを使い、図形ごとに対応するプロパティを指定し、メソッドを呼び出す。

例えばオレンジ色の四角形を描画するとする。

この場合、CanvasRenderingContext2DオブジェクトのfillStyleプロパティで図形の色を指定し、次いでfillRect(x, y, width, height)メソッドを呼び出して矩形を描画する。

複数の図形を描画したい時は、適宜プロパティを追加、上書きしながら、順次描画用のメソッドを呼び出す。

つまりコンテキストは、大きなステートマッスィーンと言える。

簡単なサンプル

2dのコンテキストを用いた簡単なサンプルコードを示す。

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body>
    <canvas id="canvas"></canvas>
    <script>
      const canvas = document.querySelector('#canvas');
      canvas.width = 320;
      canvas.height = 320;

      const context = canvas.getContext('2d');
      const canvasWidth = canvas.width;
      const canvasHeight = canvas.height;

      const rectWidth = 300;
      const rectHeight = 300;

      const rectX = (canvasWidth - rectWidth) / 2;
      const rectY = (canvasHeight - rectHeight) / 2;

      context.fillStyle = 'orange';
      context.fillRect(rectX, rectY, rectWidth, rectHeight);
    </script>
  </body>
</html>

カンバスのサイズが固定であれば、HTMLの属性値として指定した方が楽かと思う。

また、コンテキストの操作に関しては、DOMオブジェクトのstyleプロパティをあれこれして要素の位置やサイズや背景色等々を操作するのとあまり変わらない(ただしCanvas APIはピクセルを直接操作する)。

そのため、望むコンテキストが保持する描画対象のプロパティと描画メソッドをまず知ることが大切と言える。

参考サイト