この記事は編集レビューを必要としています。ぜひご協力ください。
<canvas>
要素
<canvas id="tutorial" width="150" height="150"></canvas>
<canvas>
は <img>
と似ています。src
属性と alt
属性がない点が明確に異なりますが、width
と height
の属性がある点などは共通しています。 これらの属性は必ず指定しなければならないものではありません。このほかに様々な DOM 属性を利用できます。 width
と height
属性が指定されなかった場合、canvas は幅 300 ピクセル、高さ 150 ピクセルの要素として初期化されます。画面上の大きさは CSS によって変更できますが、その場合 canvas に描画される画像は CSS の指定に合わせて拡大 / 縮小されます。この際、元の画像のアスペクト比は考慮されないため、指定の仕方によっては画像が歪んで表示されます。
付記: 画像が歪んでいると感じた時は、<canvas>
の width
と height
属性の値を設定して、CSS によるサイズの変更をしないようにしましょう。
id
属性は 全ての要素が持つ属性 で <canvas>
に固有なものではありません。これを利用することで、ユニークな ID を要素に持たせられます。ID を持たせることで、JavaScript の中から、その要素を探すのが簡単になります。
<canvas>
要素は通常の画像と同じようにレイアウトされます。(margin
や border
、 background
といったルールも利用可能ですが、これらは実際に描画される画像には影響を与えません。スタイルが何も設定されていない場合、canvas は最初透明なものとして描画されます。スタイルとレイアウトに関しては専用のページを設けています。詳細は、そちらをご覧ください。
代替コンテンツ
<canvas>
要素は対応していないブラウザ、例えば Internet Explorer 9 以前、で表示するための代替コンテンツを定義できます。これは <img>
というよりは、むしろ <video>
や <audio>
、<picture>
要素に似ています。
代替コンテンツの定義方法はシンプルで、<canvas>
要素の内部に代わりに表示するコンテンツを記述します。対応していないブラウザは <canvas>
を無視するため、その内部のコンテンツが表示されるというわけです。
次の例では JavaScript によって canvas に対して、代替テキストが設定されています:
<canvas id="stockGraph" width="150" height="150"> 現在の株価: $3.15 +0.15 </canvas> <canvas id="clock" width="150" height="150"> <img src="images/clock.png" width="150" height="150" alt=""/> </canvas>
使用するブラウザを変更するよう利用者に伝えることは、利用者のために全くなりません。どのような代替テキスト / コンテンツを設定するのが適切かは make the canvas more accessible をご覧ください。
</canvas>:
閉じタグが必須です
代替コンテンツを内部に持つ関係上、<img>
要素と異なって <canvas>
要素は閉じタグ (</canvas>
) が必須となっています。タグを閉じなかった場合は、残りのページ全てが代替コンテンツとして処理され、その結果としてそれらが表示されなくなります。
代替コンテンツが必要でない場合は、単に <canvas id="foo" ...></canvas>
と書けば対応するブラウザで動作します。
描画コンテキスト
<canvas>
は固定された大きさの描画可能領域を作成できます。この領域は、1 つ以上の描画コンテキストとして表現され、そのコンテキストを通じて描画領域を操作します。このチュートリアルでは、2 次元グラフィックスを描画するためのコンテキストについてのみ解説しますが、これ以外の描画コンテキストも存在します。その典型例が WebGL です。これは OpenGL ES に基づいた 3 次元グラフィックスを扱える描画コンテキストです。
初期状態での canvas には何も描画されていません。ここに描画を行うには、まず JavaScript で描画コンテキストを取得する必要があります。 <canvas>
要素の getContext()
を呼ぶことで、描画コンテキストは取得できます。呼び出す際の引数によって、取得されるコンテキストの種類が変わります。"2d"
を指定することで、2 次元のグラフィックスを扱える描画コンテキストが取得できます。これで取得されたコンテキストの詳細は CanvasRenderingContext2D
をご覧ください。
var canvas = document.getElementById('tutorial'); var ctx = canvas.getContext('2d');
最初の行では document.getElementById()
メソッドを呼んで、DOM 中から <canvas>
要素をあらわすノードを探しています。2 行目では見つけた要素の getContext()
メソッドを呼んで、描画コンテキストを取得しています。
対応しているかどうかの確認
<canvas>
要素に対応していないブラウザでは、代替コンテンツが表示されます。JavaScript からは getContext()
メソッドの有無を調査することで、ブラウザが対応しているかどうかを確認できます。確認するためのコードは以下のようになります:
var canvas = document.getElementById('tutorial'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); // drawing code here } else { // canvas-unsupported code here }
サンプルコード
以上の点をまとめたサンプルコードは以下のようになります。このサンプルコードは、後の説明でも利用します。
付記:スクリプトを HTML に埋め込むのは、よいやり方ではありません。この例では分かりやすさのために、仕方なく埋め込んでいます。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Canvas tutorial</title> <script type="text/javascript"> function draw(){ var canvas = document.getElementById('tutorial'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); } } </script> <style type="text/css"> canvas { border: 1px solid black; } </style> </head> <body onload="draw();"> <canvas id="tutorial" width="150" height="150"></canvas> </body> </html>
スクリプト中の draw()
関数はページのロード完了時に一度だけ呼び出されます。これは、document の load
イベントを利用しているためです。他の関数同様 window.setTimeout()
や window.setInterval()
、他のイベントハンドラから呼び出すことができますが、今の所ページがロードされた時にのみ呼び出されます。
このサンプルコードでは何も描画されない領域が表示されます。実際の動作は次で確認できます:
単純な描画
手始めに単純な例を見てみましょう。次の例では重なり合う 2 つの四角形が描画されます。そのうちの 1 つは透明度が設定されており、下の色が透けて見えます。この例がどのように動作しているかは、次のページで解説します。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <script type="application/javascript"> function draw() { var canvas = document.getElementById("canvas"); if (canvas.getContext) { var ctx = canvas.getContext("2d"); ctx.fillStyle = "rgb(200,0,0)"; ctx.fillRect (10, 10, 50, 50); ctx.fillStyle = "rgba(0, 0, 200, 0.5)"; ctx.fillRect (30, 30, 50, 50); } } </script> </head> <body onload="draw();"> <canvas id="canvas" width="150" height="150"></canvas> </body> </html>
この例は次のように動作します:
Screenshot | Live sample |
---|---|