Visit Mozilla.org

Drawing Graphics with Canvas

出典: MDC


Most of this content has been rolled into the more expansive Canvas tutorial, this page should probably be redirected there as it's now redundant.

目次

[編集] 導入

Firefox 1.5 とともに、Firefox はプログラム可能な画像のための新しい HTML 要素を含みます。<canvas>WHATWG の canvas 仕様を基にしています。WhatWG canvas 仕様自体は Safari で実装された Apple の <canvas> を基にしています。クライアント上でグラフ、UI 要素、および他のカスタムグラフィックスの描画に使用することができます。

<canvas> は1つ以上の描画コンテクストを公開した固定サイズの描画表面を作ります。私達は2次元描画コンテクストに焦点をあてるつもりです(ちなみに、現在は描画コンテクストのみを定義しました) 。将来、他のコンテクストが違う種類の描画を提供するかもしれません。例えば、OpenGL ES を基にした3次元コンテクストが最終的に<canvas> 仕様に追加されると思われます。

[編集] 2次元描画コンテクスト

[編集] 簡単な例

始めに、ここに2つの交差した長方形を描く簡単な例があります。そのうち1つは、透明度を持っています の

例 1
例 1
<html>
 <head>
  <script type="application/x-javascript">
function draw() {
 var canvas = document.getElementById("canvas");
 var ctx = canvas.getContext("2d");

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

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

draw 関数は canvas 要素を得、次に2次元コンテクストを得ます。 ctx オブジェクトは canvas に実際に描画するのに使うことができます。例では CSS color 仕様による2つの異なる色を fillStyle を設定し、fillRect を呼ぶことにより二つの長方形を単純に塗りつぶしています。2つ目の fillStyle は色と一緒に透明度を定義するために rgba() を使っています。

fillRectstrokeRect 及び clearRect は塗りつぶし、輪郭線を描画、又は長方形部分を消去します。より複雑な形を描画するためにパスが使われます。

[編集] パスの利用

beginPath 関数は新しいパスを開始します、そして moveTolineToarcToarc、及び同じようなメソッドはパスにセグメントを加えるのに使われます。パスは closePath によって閉じることが可能です。一度パスが作られれば、fillstroke を使って canvas にパスを描画できます。

例2
例2
<html>
 <head>
  <script type="application/x-javascript">
function draw() {
  var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");

  ctx.fillStyle = "red";

  ctx.beginPath();
  ctx.moveTo(30, 30);
  ctx.lineTo(150, 150);
  // was: ctx.quadraticCurveTo(60, 70, 70, 150); これは間違い。
  ctx.bezierCurveTo(60, 70, 60, 70, 70, 150); // <- これが右図の正しい書式。 ->
  ctx.lineTo(30, 30);
  ctx.fill();
}
   </script>
 </head>
 <body onload="draw()">
   <canvas id="canvas" width="300" height="300"></canvas>
 </body>
</html>

fill()stroke() を呼ぶと現在のパスが使われます。 もう一度塗りつぶしか輪郭線を描くにはパスを再生成しなくてはなりません。

[編集] 画像状態

fillStylestrokeStylelineWidth 及び lineJoin のようなコンテクストの属性は現在の画像状態の一部です。 コンテクストは現在の状態を状態スタックに/から移動させるのに save()restore() という二つのメソッドを提供してます。

[編集] より複雑な例

ここにはパス、状態を使い、現在の変換行列も紹介している少し複雑な例があります。 translate()scale()、及び rotate() のコンテクストメソッドは全て現在の行列を変換します。 全ての描画された点は最初にこの行列により変換されます。

例 3
例 3
 <html>
  <head>
   <script type="application/x-javascript">
 function drawBowtie(ctx, fillStyle) {
 
   ctx.fillStyle = "rgba(200,200,200,0.3)";
   ctx.fillRect(-30, -30, 60, 60);
 
   ctx.fillStyle = fillStyle;
   ctx.globalAlpha = 1.0;
   ctx.beginPath();
   ctx.moveTo(25, 25);
   ctx.lineTo(-25, -25);
   ctx.lineTo(25, -25);
   ctx.lineTo(-25, 25);
   ctx.closePath();
   ctx.fill();
 }
 
 function dot(ctx) {
   ctx.save();
   ctx.fillStyle = "black";
   ctx.fillRect(-2, -2, 4, 4);
   ctx.restore();
 }
 
 function draw() {
   var canvas = document.getElementById("canvas");
   var ctx = canvas.getContext("2d");

   // 他の全て変換はこの変換から相対的であるることに注意
   ctx.translate(45, 45);

   ctx.save();
   //ctx.translate(0, 0); // 不必要
   drawBowtie(ctx, "red");
   dot(ctx);
   ctx.restore();
 
   ctx.save();
   ctx.translate(85, 0);
   ctx.rotate(45 * Math.PI / 180);
   drawBowtie(ctx, "green");
   dot(ctx);
   ctx.restore();
 
   ctx.save();
   ctx.translate(0, 85);
   ctx.rotate(135 * Math.PI / 180);
   drawBowtie(ctx, "blue");
   dot(ctx);
   ctx.restore();
 
   ctx.save();
   ctx.translate(85, 85);
   ctx.rotate(90 * Math.PI / 180);
   drawBowtie(ctx, "yellow");
   dot(ctx);
   ctx.restore();
 }
    </script>
  </head>
  <body onload="draw()">
    <canvas id="canvas" width="300" height="300"></canvas>
  </body>
 </html>

これは四回呼び出されている drawBotie 及び dot メソッドを定義しています。 それぞれに呼び出しの前に、translate() 及び rotate() は現在の変換行列を用意するために使われます その変換行列は順番に点と蝶ネクタイを配置します。 dot(0, 0) を中心に小さな黒い正方形を描画します。 dot は変換行列によって移動されます。 drawBowtie は引き渡された塗りつぶしスタイルを使って単純な蝶ネクタイのパスを描画します。

行列の操作は累積されるので、save() 及び restore() はそれぞれが設定した元の canvas の状態に復帰するために使われます。 注目すべき1つの事は回転が常に現在の基点の周りで起こるということです。 従って translate() rotate() translate() の連続は translate() translate() rotate() の連続実行とは異なった結果を生みます。

[編集] Appleの <canvas> との互換性

アップル及びその他の実装と <canvas> は互換性があります。 しかし、ここで説明されているいくつかの注意すべき問題があります。

[編集] 必須の </canvas> タグ

Apple の Safari の実装においては、<canvas><img> とほぼ同じような方法で実装された要素で、終了タグを持っていません。 しかしながら、 <canvas> がウェブで広く普及するために、 代替内容のための何らかの方法を提供しなければなりません。 したがって、Mozillaの実装では、 終了タグが必要です。

もし代替内容が必要なければ、単純な <canvas id="foo" ...></canvas> は Safari と Mozilla の両方で完全に互換性を持つでしょう。 -- Safari は単に終了タグを無視するでしょう。

もし代替内容が望まれるならば、(canvas だけが描画されるべき) Safari から代替内容を隠すために、そして(代替内容が表示されるべき) IE から canvas 自体を隠すためにいくつかの CSS のトリックを使わなければなりません。 Todo: Hixie にその CSS を表現させる。


[編集] 更なる機能

[編集] ウェブコンテンツを Canvas に描画する

この機能は Chrome特権コードの実行時のみに存在します。通常のHTMLページでは許可されていません。

Mozilla の canvasdrawWindow メソッドで拡張できます。このメソッドは DOM window の中身のスナップショットを canvas に描画します。たとえば、

ctx.drawWindow(window, 0, 0, 100, 200, "rgb(0,0,0)");

では、現在のウィンドウの、左上から (0,0,100,200) 座標にある四角形の中身を、黒色背景の canvas に描き込みます。"rgba(0,0,0,0)" と色を指定することで、遅くなりますが、透過背景の上に中身を描画することになります。

このメソッドにより、隠し IFRAME に任意の内容 (たとえば、CSS でスタイル付けされた HTML テキストや SVG) を入れて、その内容を canvas に描くことも可能になります。その場合、現在の変形にしたがって、拡大縮小・回転が行われます。

Ted Mielczarek の tab preview 拡張は Web ページのサムネイルを提供するために chrome の中でこのテクニックを使い、ソースコードは参考のために利用可能です。

[編集] 参考