canvasの使い方


なんとなくcanvasの簡単な使い方の説明をします。canvasについての細かい話は他のところで見てください。
多少書き方がおかしくても動いてしまうので、正式には間違っている書き方をしている可能性はあります。
htmlとjava scriptの知識が必要になりますが、とりあえず簡単なhtmlを書いてことがあって、java scriptのさわりを知っていればどうにかなると思います。
canvasに用意されている機能を網羅する気もないので、適当なリファレンスを見てください(HTMLクイックリファレンスとか)。

 canvasはhtmlに画像ファイルを使わずに画像を書くためのものです。こう言うと非常に便利なように聞こえますが、実際にはjava scriptを使用するので、結構面倒です。で、canvasはもともとはhtml5の機能の一部で、internet explorerでは完全にサポートされきれていないです(IE9で対応したらしい)。なので、他のブラウザが必要になります。Firefox、google chrome、Opera、Safariなんかはcanvasに対応しています(ブラウザによって動作に多少の違いがあるらしいですが)。ここではSafari(5.1.5)を使って動作確認をしています。
 まず、canvasを使う時の基本的な構成を示すと

 <!DOCTYPE html>
 <html>

 <head>
 <script type="application/javascript">

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

 </script>
 </head>

 <body onload="draw()">
 <canvas id="test" width="300" height="300"></canvas>
 </body>

 </html>

この後に出てくる例はif (canvas.getContext)内のvar ctx = canvas.getContext("2d");以降に貼り付けてやればいいです。
 <!DOCTYPE html>でhtml5を使うと宣言しています。html4.01では<!DOCTYPE HTML PUBLIC "−//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">でした。java scriptを使うのでhead内に、<script type="application/x−javascript">を書きます。typeの指定はここではapplication/javascriptとしていますが、text/javascriptでもapplication/x−javascriptでもいいです。このjava script内にcanvasで描画するための関数を作っていきます。
 まず、動作させる関数を作ります。ここではdrawと名前を付けていますが、任意です。var canvas = document.getElementById("test")でhtmlでcanvasを使うことを示します。これによって変数canvasがcanvasの要素を持つオブジェクトになります。"test"は<body>内で呼び出すための名前なので任意で、canvasは変数名なので好きに変えられます。例えば

 function draw(){
  var ca = document.getElementById("test");
  if (ca.getContext){
   var ctx = ca.getContext("2d");
  }
 }

のようにしてもなんの問題もないです。if(canvas.getContext){}はcanvasに対応していないときに、if内のcanvasの動作を読みこまないようにするためなので、なくてもいいです。var ctx = canvas.getContext("2d")は2次元の描画機能を有効にするためのものです。なので、この記述以降で図を書くようになっています。ctxは変数名なので変更できます(ctxはcontextの略)。このctxを使って描画機能を呼び出して描画します。

 <body onload="draw()">
 <canvas id="test" width="300" height="300" style="background−color:red"></canvas>

 </body>

部分でtestと名前をつけたcanvasの動作を実行します。width="300" height="300"で描画の枠を決めています。style="background−color:red"で背景の色を指定します。色指定は直接色を書く以外に、style="background−color#0000ff"のように16進とか、style="background−color:rgb(0,255,0)"のようにrgbを明記して10進で指定できます(どちらも左から赤、緑、青の強さ)。<body onload="draw()">についてはjava scriptの書き方で話題になるように、window.onloadの方が便利という話もありますが、ここではどうでもいいのでこっちを使います。
 まずは描画の基本である線を書いてみます。線を書くにはctx.beginPath()と書いて線を書ける状態にします(ようは線を書く宣言みたいなもの)。直線を書くなら

 ctx.beginPath();
 ctx.moveTo(100,20);
 ctx.lineTo(150,100);
 ctx.closePath();
 ctx.stroke();

みたいにします。ctx.beginPath()で線を書くことを宣言し、ctx.moveTo(x,y)で開始座標を指定し(左上が原点)、そこからctx.lineTo(x,y)で指定する座標まで線を引くようにしています。ctx.closePath()で線の動きを終わらせ、ctx.stroke()で線を書いています。これで四角形を描くなら、if (canvas.getContext)内で

 if (canvas.getContext){
  var ctx = canvas.getContext("2d");
  ctx.beginPath();
  ctx.moveTo(100,20);
  ctx.lineTo(150,20);
  ctx.lineTo(150,120);
  ctx.lineTo(100,120);
  ctx.lineTo(100,20);
  ctx.closePath();
  ctx.stroke();
 }

みたいにします。また、四角形を書く命令は用意されていて、rect(x,y,幅、高さ)で書くことができ(x,yは左上)


 if (canvas.getContext){
  var ctx = canvas.getContext("2d");
  ctx.beginPath();
  ctx.rect(100,20,50,100);
  ctx.stroke();
 }

これで同じ図が描けます。他にも円と円弧を書くのも用意されています。
 線の色はstrokeStyle="rgb(0, 0, 0)"でr,g,bの設定で色を指定できて

 ctx.strokeStyle = "rgb(255, 0, 255)";
 ctx.beginPath();
 ctx.moveTo(100,20);
 ctx.lineTo(150,20);
 ctx.lineTo(150,120);
 ctx.lineTo(100,120);
 ctx.lineTo(100,20);
 ctx.closePath();
 ctx.stroke();

とか

 ctx.strokeStyle = "rgb(255, 0, 255)";
 ctx.beginPath();
 ctx.rect(100,20,50,100);
 ctx.stroke();

みたいにします。もしくはstrokeStyle="#00ff00"のように16進で指定することもできます(これも左から赤、緑、青の強さです。この場合は緑)
 四角形の内部を塗りつぶすには

 ctx.fillStyle = "rgb(0, 255, 0)";
 ctx.beginPath();
 ctx.moveTo(100,20);
 ctx.lineTo(150,20);
 ctx.lineTo(150,120);
 ctx.lineTo(100,120); 
 ctx.lineTo(100,20);
 ctx.closePath();
 ctx.fill();
 ctx.stroke();

このようにfillStyle = "rgb(0, 0, 0)"でr,g,bの設定で塗りつぶす色を指定します。線を書いた後にctx.fill()で指定した色で塗りつぶすようにしています。
 同様に

 ctx.fillStyle = "rgb(0, 255, 0)";
 ctx.beginPath();
 ctx.rect(100,20,50,100);
 ctx.fill();
 ctx.stroke();

としても同じです。塗りつぶしの時は、線が描かれる必要がないのでstroke()がなくても平気です。線の色を変えて塗りつぶしも行うには

 ctx.fillStyle="rgb(0, 255, 0)";
 ctx.strokeStyle="rgb(255, 0, 255)";
 ctx.beginPath();
 ctx.moveTo(100,20);
 ctx.lineTo(150,20);
 ctx.lineTo(150,120);
 ctx.lineTo(100,120);
 ctx.lineTo(100,20);
 ctx.closePath();
 ctx.fill();
 ctx.stroke();

とか

 ctx.fillStyle = "rgb(0, 255, 0)";
 ctx.strokeStyle = "rgb(255, 0, 255)";
 ctx.beginPath();
 ctx.rect(100,20,50,100);
 ctx.fill();
 ctx.stroke();

とすればいいです。この場合ではstroke()は必要です。
 塗りつぶされた四角形はfillRect()としても書けます

 ctx.beginPath();
 ctx.fillRect(100,20,50,100);

括弧内はrectと同じです。fillRectではstroke()がなくても平気です。これは何の設定もしなければ黒で塗りつぶされます。fillStyleを

 ctx.fillStyle = "rgb(0, 255, 0)";
 ctx.beginPath();
 ctx.fillRect(100,20,50,100);

とすることで色を指定できます。
 次にアニメーションの表現の仕方の基本的な部分を見ていきます。左から右方向に四角が動いていくようにするには例えば

 <!DOCTYPE html>
 <html>
 <head>
 <script type="text/javascript">

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

  var x=0, y=150,tv; //変数の定義
  ctx.fillStyle ="rgb(0,255,0)"; //四角形の色指定

//四角形を右に動かすための関数の定義
  function pic(){
   ctx.clearRect(0,0,300,300); //四角形を消す
   ctx.fillRect(x,y,30,30); //四角形を書く
   x=x+4; //次に四角形が現れる位置の指定

   if(x>300){
    clearInterval(tv); //動きを止める
   }
  }

//関数を実行して描写させる部分
  tv=setInterval(pic,100);

 }
 </script>
 </head>
 <body onload="draw()"
 <canvas id="test" width="300" height="300" style="background−color:rgb(0,100,100)">
 </canvas>
 </body>
 </html>

変数x,yはそのままx,y座標の位置で、tvは関数を実行する変数です。tvはなくても動きますが、スクリプトを停止させるために名前をつけています。
 重要なのは右に動いているように見せるためには、右に動かす時にいちいち前の4角を消すようにしなければいけない点です。なので、まず必要になってくるのが、図を消す関数で、それが.clearRect(0,0,300,300)というやつです。これは消すというより、透明な黒で範囲内を塗りつぶす関数でうs。左側の0,0が始点で、300,300が横と高さです。今はcanvasの範囲を300,300の大きさに指定しているので、全領域を覆うようになっています。領域を具体的に指定せずに横と高さをcanvas.width、canvas.heightとすれば勝手に全体を指定してくれます。clearRect(0,0,100,300)とかに書き換えると、途中から四角が現れ、消されずに連続な直線になります。なので、ctx.clearRect(0,0,300,300)を省けば、端から端までの直線が引かれます。で、消した後に四角形を書くためにctx.fillRect(x,y,30,30)を入れ、次の座標をx=x+4としてx方向に4動かした先に指定しています。
 次に出てくるif文ですが、これはなくても動きます。このif文はxが300より大きくなったら描画を停止しろというものです。なんでそうなっているのかは、tv=setInterval(pic,100)から分かります。setInterval(関数,時間間隔)は指定した時間間隔(単位はミリ秒)で指定した関数を実行しろというものです。今の場合では関数picを時間間隔100ミリ秒ごとに実行するようになっています。そうすると、100ミリ秒ごとに関数picが実行されるので、100ミリ秒間隔で四角がまず消され、その後にx方向に4動いた四角が出てきます(1回目はx=0の地点に四角が出てくる)。このために、右に動いているように見えるというわけです。で、このif文はこの動きを止めるためにいれています(この例ではx>300にとっているので端で止まるようになっている)。例えば、x=100で止めたいと思っても、時間間隔しか指定されていないので、if文がないと右に行き続けます。このx=100で止めたいというのをclearInterval()で行わせています。clearInterval()はsetInterval()の動作を止めるものです。こんなことからわざわざtv=setInterval(pic,100)としています。
 他にも右に行ってから上にいくというようにするためには、例えばpicを

 function pic(){
  ctx.clearRect(0,0,300,300);
  ctx.fillRect(x,y,30,30);
  if(x<100){
   x=x+4;
  }
  else{
   y=y−4;
  }

  if(y<30){
   clearInterval(tv);
  }
 }

とすればいいです。if文の分岐で区別しています。こういったアニメーションの動き方に関しては、作る人の趣味や暗黙の了解のようなものがあるので、自分に合ったものを見つけるのがいいと思います。
 アニメーションの表現の仕方としてsetTimeout(関数,実行までの時間)を使うこともできます。同じ動作をするものをsetTimeoutを使って書くと

 <!DOCTYPE html>
 <html>
 <head>
 <script type="text/javascript">

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

  var x=0, y=150, tv; //変数の定義
  ctx.fillStyle ="rgb(0,255,0)"; //四角形の色指定

//四角形を右に動かすための関数の定義
  function pic(){
   ctx.clearRect(0,0,300,300); //四角形を消す
   ctx.fillRect(x,y,30,30); //四角形を書く
   x=x+4; //次に四角形が現れる位置の指定

   clearTimeout(tv); //なくても動くがあったほうがいい
   tv=setTimeout(pic,100); //時間間隔の指定
  }

//関数の実行
  pic();
 }
 </script>
 </head>
 <body onload="draw()"
 <canvas id="test" width="300" height="300" style="background−color:rgb(0,100,100)">
 </canvas>
 </body>
 </html>


今度のsetTimeoutは指定したミリ秒後に動作するというものです。なので、setTimeout単独では1回しか四角形を出しません。これは

 <script type="text/javascript">
 function draw(){
  var canvas = document.getElementById("test");
  if(canvas.getContext){
   var ctx = canvas.getContext("2d");
  }
  var x=0, y=150,var tv; //変数の定義
  ctx.fillStyle ="rgb(0,255,0)"; //四角形の色指定

//四角形を右に動かすための関数の定義
  function pic(){
   ctx.clearRect(0,0,300,300); //四角形を消す
   ctx.fillRect(x,y,30,30); //四角形を書く
   x=x+4; //次に四角形が現れる位置の指定
  }
  setTimeout(pic,100);
 }
 </script>

とでもしてみれば確認できます。これを連続動作するようにする基本的な手段がここで示したような関数の中に入れてしまうというものです。動作としては、関数picが呼び出されることでまず最初の四角が表示され、その後にpic内のsetTimeout(pic,100)によって100ミリ秒後にまたpicが実行され、xが4右に動いた状況で同じ動作をする、というのが繰り返されていきます。このようにして、四角が右に動いて行っています。clearTimeoutはsetTimeoutによる時間指定を消すものです。この例ではなくても害はないんですが、場合によってはclearTimeoutがないと時間指定が狂ったりします。というわけで、canvasでアニメーション表示をしようと思うと、時間指定をして上手いこと動くように見せるよう動作させる必要があります。
 これが基本的なcanvasの使用法です。ちなみに、Safari(5.1.5)ではcanvasの文字表示の機能が使えないので、省きました。ここで見てきたように、結局のところjava scriptで動かしていくので、canvasの知識というよりjava scriptの技術が必要です。アニメーションをやるなら使い勝手的にはflashの方がお手軽な気がしますし、canvasが下火にならなければそのうちcanvas対応のソフトとか出回ってくるでしょうから、それからやったほうが余計な苦労がないかもしれません。



戻る