HOWTO · JavaScript

JavaScript でキャンバスをクリアする

この短い記事では、JavaScript でキャンバスをクリアする方法を示します。

このページの内容

HTML の <canvas> 要素は、JavaScript で描画するビットマップです。フレームを描き直したり、描画をリセットしたり、ユーザーに作業内容を消去させたりするときには、そのビットマップの一部または全体をクリアする必要があります。この記事では、clearRect() を使って JavaScript でキャンバスをクリアする方法を紹介します。サーフェス全体のクリア、ボタンへの呼び出しの割り当て、一部の領域だけの消去を取り上げます。

clearRect() でキャンバス全体をクリアする

clearRect() は <canvas> 要素自体ではなく、2D レンダリング コンテキスト (CanvasRenderingContext2D) のメソッドです。canvas.getContext('2d') が返すコンテキスト オブジェクトに対して呼び出します。引数は 4 つで、矩形の左上隅の x 座標と y 座標、そして width と height です。その矩形の内側にあるすべてのピクセルが消去され、完全に透明になります。

キャンバス全体をクリアするには、ビットマップ全体を覆う矩形を渡します。

context.clearRect(0, 0, canvas.width, canvas.height);

ここで canvas.width と canvas.height は、canvas 要素自身の width 属性と height 属性、つまりピクセル単位のビットマップの寸法です。矩形は原点から始まりビットマップ全体にまたがるため、clearRect() はそれまでに描画されたものをすべて消去します。次の例を実行すると、680 × 420 のビットマップをクリアする呼び出しを確認できます。

このセクションのコードと表示されるラベルや出力は英語のままです。

const canvas = { width: 680, height: 420 };
console.log(`context.clearRect(0, 0, ${canvas.width}, ${canvas.height})`);
context.clearRect(0, 0, 680, 420)

キャンバスを作成して描画する

<canvas> 要素は単なるコンテナであり、実際の描画はコンテキスト オブジェクトを通じて JavaScript が行います。次の例では 680 × 420 のキャンバスを作成し、クリア対象となる見えるコンテンツとして赤い曲線を輪郭描画します。.html ファイルとして保存し、ブラウザで開いてください。この記事のページ例はブラウザで実行するものであり、この記事のテスト環境では実行されていません。

このセクションのコードと表示されるラベルや出力は英語のままです。

<!DOCTYPE HTML>
<html>
  <head>
    <title>Creating a canvas</title>
  </head>
  <body>
    <canvas id="canvsId" width="680" height="420"></canvas>
    <script>
      let canvas = document.getElementById('canvsId');
      let context = canvas.getContext('2d');
      context.beginPath();
      context.moveTo(180, 90);
      context.bezierCurveTo(120, 80, 110, 170, 250, 170);
      context.bezierCurveTo(260, 190, 300, 160, 370, 140);
      context.bezierCurveTo(410, 140, 440, 130, 380, 110);
      context.bezierCurveTo(440, 50, 350, 40, 350, 50);
      context.bezierCurveTo(310, 10, 270, 30, 240, 40);
      context.bezierCurveTo(310, 10, 130, 15, 180, 90);
      context.closePath();
      context.lineWidth = 8;
      context.strokeStyle = 'red';
      context.stroke();
    </script>
  </body>
</html>

レンダリングされたページには、キャンバス上に描画された赤い輪郭線が表示されます。

JavaScript で作成したキャンバス

ボタンでキャンバスをクリアする

ユーザーがクリアを実行できるようにするには、ボタンにクリック ハンドラをアタッチし、その中で clearRect() を呼び出します。下のページは同じ描画を再利用し、id が clear の input ボタンを追加して、クリックするたびにビットマップ全体を消去するリスナを登録しています。

このセクションのコードと表示されるラベルや出力は英語のままです。

<!DOCTYPE HTML>
<html>
  <head>
    <title>Clear a canvas with a button</title>
    <style>
      #button {
        position: absolute;
        top: 5px;
        left: 10px;
      }
      #button input {
        padding: 10px;
        display: block;
        margin-top: 5px;
      }
    </style>
  </head>
  <body>
    <canvas id="myCanvs" width="680" height="420"></canvas>
    <div id="button">
      <input type="button" id="clear" value="Clear">
    </div>
    <script>
      let canvas = document.getElementById('myCanvs');
      let context = canvas.getContext('2d');
      context.beginPath();
      context.moveTo(180, 90);
      context.bezierCurveTo(120, 80, 110, 170, 250, 170);
      context.bezierCurveTo(260, 190, 300, 160, 370, 140);
      context.bezierCurveTo(410, 140, 440, 130, 380, 110);
      context.bezierCurveTo(440, 50, 350, 40, 350, 50);
      context.bezierCurveTo(310, 10, 270, 30, 240, 40);
      context.bezierCurveTo(310, 10, 130, 15, 180, 90);
      context.closePath();
      context.lineWidth = 8;
      context.strokeStyle = 'red';
      context.stroke();
      document.getElementById('clear').addEventListener('click', function() {
        context.clearRect(0, 0, canvas.width, canvas.height);
      }, false);
    </script>
  </body>
</html>

ページを開くと、キャンバスの上にボタンが表示されます。

キャンバスをクリアするためのクリア ボタン

クリックすると、clearRect(0, 0, canvas.width, canvas.height) が描画されたすべてのピクセルを取り除きます。キャンバスは透明になるため、描画があった場所には背後のページが透けて見えます。

ボタンをクリックした後にキャンバスがクリアされた状態

キャンバスの一部をクリアし、よくある間違いを避ける

clearRect() が消去するのは矩形であり、必ずしもキャンバス全体とは限りません。描画の一部だけを取り除くには、その領域の座標とサイズを渡します。たとえば context.clearRect(180, 90, 200, 80) は (180, 90) を起点とする 200 × 80 の領域を消去します。矩形の内側のピクセルは透明になり、それ以外の描画はそのまま残るため、動くオブジェクトや単一のパネルを描き直す場合に便利です。

混乱を招きやすい点がいくつかあります。

  • canvas.width と canvas.height は、要素の属性または JavaScript で設定されるビットマップのピクセル寸法です。CSS の width と height はキャンバスの表示を拡大縮小するだけでビットマップのサイズは変更しないため、clearRect() に渡す値としては誤りです。CSS で引き伸ばされたキャンバスはページ上では大きく見えますが、描画可能な領域は変わりません。
  • clearRect() は現在の変換に従います。translate()、rotate()、scale() を呼び出している場合、渡した矩形も変換されます。生のビットマップ座標でクリアしたいときは、先に context.setTransform(1, 0, 0, 1, 0, 0) を呼び出してください。有効なクリッピング領域があると、消去されるピクセルが制限されることもあります。
  • クリアは白で塗りつぶすのではなく透明なピクセルへ戻す処理なので、キャンバスの背後にあるもの (ページの背景や重なった要素) が、クリアされた領域で再び見えるようになります。
  • clearRect() を含む 2D キャンバス API はすべてのモダン ブラウザで動作しますが、非常に古いブラウザでは <canvas> 自体がサポートされていない場合があるため、レガシーな対象では普遍的な利用可能性を前提にしないでください。