HTML+JavaScriptだけでブラウザに図形描画 - Canvas API -

2012年6月26日(火)
山田 祥寛(YAMADA, Yoshihiro)

TIPS 009:キャンバスに直線を描画する

キャンバスに直線を描画するには、パスを定義したあと、strokeメソッドを呼び出します。

[リスト2]キャンバスに直線を描画するコード(line.html)

window.addEventListener('DOMContentLoaded',
  function() {
    if (HTMLCanvasElement) {
      var cv = document.querySelector('#cv');
      var c = cv.getContext('2d');
      // パスの開始(1)
      c.beginPath();
      // 始点/終点を設定(2)
      c.moveTo(15, 15);
      c.lineTo(350, 250);
      // パスに沿って直線を描画(3)
      c.stroke();
    }
  }
);
 図2:キャンバスに直線が描画された(クリックで拡大)

Canvas APIを利用する上で、パス(Path)の理解は欠かせません。

パスとは、コンテキストで管理される座標の集合です。Canvas APIでは、今後、パスで表された座標の集合に従って、直線や曲線を描画したり、囲まれた領域を塗りつぶしたりすることになります。

パスは、beginPathメソッドで開始します((1)の部分)。パスを初期化するためのメソッドと言い換えても良いでしょう。既に座標(群)が設定されていた場合には、beginPathメソッドでクリアされます。

続いて、moveToメソッドでパスの始点を、lineToメソッドで終点を、それぞれ設定します((2)の部分)。

ただし、ここまでの操作では、まだ座標を定義しただけです(この時点では、まだキャンバスに図形は描画されません)。パスに沿って直線を描画するには、最後にstrokeメソッドを呼び出してください((3)の部分)。

TIPS 010:折れ線を描画する

折れ線を描画するには、lineToメソッドを繰り返し呼び出します。

[リスト3]折れ線を描画するコード(line2.html)

window.addEventListener('DOMContentLoaded',
  function() {
    if (HTMLCanvasElement) {
      var cv = document.querySelector('#cv');
      var c = cv.getContext('2d');
      c.beginPath();
      c.moveTo(15, 15);
      c.lineTo(30, 250);
      c.lineTo(250, 200);
      c.lineTo(280, 130);
      c.lineTo(250, 80);
      c.stroke();
    }
  }
);
 図3:キャンバスに折れ線が描画された(クリックで拡大)

lineToメソッドで指定した直線の終点は、そのまま次の直線の始点となります。よって、折れ線を描画したいのであれば、lineToメソッドを繰り返し呼び出します。結果として、上のサンプルであれば、(15, 15)→(30, 250)→(250, 200)→(280, 130)→(250, 80)に、順番に線が引かれていることになります。

TIPS 09と同じく、最後にstrokeメソッドを呼び出すのを忘れないようにしてください。

TIPS 011:多角形を描画する

多角形を描画するには、パス定義の最後でclosePathメソッドを呼び出します。

[リスト4]多角形を描画するコード(polygon.html)

window.addEventListener('DOMContentLoaded',
  function() {
    if (HTMLCanvasElement) {
      var cv = document.querySelector('#cv');
      var c = cv.getContext('2d');
      c.beginPath();
      c.moveTo(15, 15);
      c.lineTo(30, 250);
      c.lineTo(250, 200);
      c.lineTo(280, 130);
      c.lineTo(250, 80);
      c.closePath();
      c.stroke();
    }
  }
);
 図4:キャンバスに多角形が描画された(クリックで拡大)

上のコードは、TIPS 10のコードからわずかにアミカケの部分を付け加えただけです。

closePathメソッドは、最後の座標と最初の座標とを結ぶためのメソッドです。lineToメソッドで、いちいち最初の座標を指定する必要はない点に注目です。

このように、始点と終点とが結ばれたパスのことを「クローズパス」と言います。一方、closePathメソッドが呼び出されなかった(=始点と終点とが結ばれていない)、TIPS 10のようなパスのことをオープンパスと言います。

TIPS 012:ベジェ曲線を描画する

ベジェ曲線とは、以下のような曲線のことを言います。

 図5:ベジェ曲線とは?(クリックで拡大)

制御点が1つのものを二次ベジェ曲線、2つあるものを三次ベジェ曲線と言います。これらのベジェ曲線をCanvas APIで描画するには、quadraticCurveTo(二次ベジェ曲線)、bezierCurveTo(三次ベジェ曲線)メソッドを利用します。

[リスト5]ベジェ曲線を描画するコード(curveTo.html)

window.addEventListener('DOMContentLoaded',
  function() {
    if (HTMLCanvasElement) {
      var cv = document.querySelector('#cv');
      var c = cv.getContext('2d');
      // 二次ベジェ曲線を描画(左)
      c.beginPath();
      c.moveTo(10, 10);
      c.quadraticCurveTo(350, 100, 50, 100);
      c.stroke();
 
      // 三次ベジェ曲線を描画(右)
      c.beginPath();  // 新たなパスの始まり(1)
      c.moveTo(100, 150);
      c.bezierCurveTo(450, 150, 0, 200, 400, 300);
      c.stroke();
    }
  }
);

quadraticCurveTo/bezierCurveToメソッドの構文は、以下のとおりです。

[構文]quadraticCurveTo/bezierCurveToメソッド

  • quadraticCurveTo(x1, y1, x2, y2)
  • bezierCurveTo(x1, y1, x2, y2, x3, y3)

引数x1、y1...は、冒頭の図の座標に対応しています。また、x0、y0はquadraticCurveTo/bezierCurveToメソッドを呼び出す前の最後の座標を表すものとします(サンプルであればmoveToメソッドで指定された座標です)。

なお、上のサンプルでは独立した2つの図形を描画しています。その場合は、新たな図形(パス)の始まりで、beginPathメソッドを呼び出さなければならない点に注意してください((1))。

TIPS 013:円/円弧を描画する

円や円弧を描画するには、arcメソッドを使います。

[リスト6]円/円弧を描画するためのコード(arc.html)

window.addEventListener('DOMContentLoaded',
  function() {
    if (HTMLCanvasElement) {
      var cv = document.querySelector('#cv');
      var c = cv.getContext('2d');
      // 中心(100, 150)、半径50の円を描画(1)
      c.beginPath();
      c.arc(100, 150, 50, 0, 2 * Math.PI, false);
      c.stroke();
      // 中心(300, 150)、半径50、45°~180°の円弧を描画(2)
      c.beginPath();
      c.arc(300, 150, 50, 0.25 * Math.PI, Math.PI, false);
      c.stroke();
    }
  }
);
 6:円、円弧が描画された(クリックで拡大)

arcメソッドの構文は、以下のとおりです。

[構文]arcメソッド

  • arc(中心のX座標, 中心のY座標, 半径, 開始角度, 終了角度, 反時計回りか)

開始角度は右水平方向(3時の方向)を基点に、時計回りで指定します。角度はラジアンという単位で指定します。ラジアンは「度数÷180×円周率」で求められます。

よって、(1)の「2 * Math.PI」は「360÷180×円周率」で360°(完全な円)を意味します。

もしも「終了角度 - 開始角度」が360°未満である場合には、円弧を描画します。例えば、(2)では45°~180°の範囲で円弧を描画します。円弧はデフォルトで時計回りに描画されますが、arcメソッドの最後の引数をtrueにした場合、円弧は反時計回りに描画されます。

以下は、12行目の最後の引数をtrueに切り替えた場合の結果です。

 図7:円弧は反時計回りに描画される(クリックで拡大)
  • Canvas APIを使った複数のHTMLサンプル

著者
山田 祥寛(YAMADA, Yoshihiro)
WINGSプロジェクト

有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表:山田祥寛)。おもな活動は、Web開発分野の書籍/雑誌/Web記事の執筆。ほかに海外記事の翻訳、講演なども幅広く手がける。2011年3月時点での登録メンバは36名で、現在もプロジェクトメンバーを募集中。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています