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

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

TIPS 025:画像を繰り返し表示する

fillStyle/strokeStyleプロパティには、パターンを指定することもできます。パターンとは、図形(または枠線)を塗りつぶす際に利用する画像の繰り返しのことを言います。

[リスト8]指定された画像を上下左右に繰り返し貼り付けるコード(pattern.html)

window.addEventListener('DOMContentLoaded',
  function() {
    if (HTMLCanvasElement) {
      var cv = document.querySelector('#cv');
      var c = cv.getContext('2d');
      // 画像を準備
      var img = new Image();
      img.src = 'wings.jpg';
      // 画像が準備できたら、以降の処理を実行
      img.addEventListener('load', function(e) {
        // パターンを作成(1)
        var p = c.createPattern(img, 'repeat');
        // 塗りつぶし色としてパターンをセット(2)
        c.fillStyle = p;
        c.fillRect(0, 0, 400, 300);
      });
    }
  }
);
図10:画像が上下左右に敷き詰められた(クリックで拡大)

パターンは、CanvasPatternオブジェクトで表します。CanvasPatternオブジェクトは、createPatternメソッドで作成できます(1)。

[構文]createPatternメソッド

  • createPattern(画像, パターンの種類)

サンプルでは、画像としてImageオブジェクトを指定していますが、その他、Video/HTMLCanvasElementなどのオブジェクトも指定できます。

パターンの種類は、画像をどのように敷き詰めるかを表すものです。指定できるパターンには、以下のようなものがあります。

設定値 概要
repeat 上下左右双方に繰り返し
repeat-x 水平方向にのみ繰り返し
repeat-y 垂直方向にのみ繰り返し
no-repeat 繰り返さない

パターンを作成できたら、後はこれをfillStyleプロパティにセットすることで、塗りつぶし色としてパターンが適用されます(2)。ここではキャンバス全体をパターンで塗りつぶしたいので、fillRectメソッドでキャンバスと同じ大きさの四角形を描画しています。

TIPS 026:画像の特定領域を切り抜く

clipメソッドを利用することで、キャンバスの特定の領域だけを切り抜きます(これをクリッピング領域と言います)。clipメソッドが呼び出された場合、以降は、クリッピング領域に対してのみ図形が描画できるようになります。

[リスト9]指定された円の領域内のみ画像を描画するコード(clip.html)

window.addEventListener('DOMContentLoaded',
  function() {
    if (HTMLCanvasElement) {
      var cv = document.querySelector('#cv');
      var c = cv.getContext('2d');
      // 円を描画
      c.beginPath();
      c.arc(250, 180, 100, 0, 2 * Math.PI, false);
      c.stroke();
      // 現在のパスに基づいて、クリッピング領域を定義
      c.clip();
 
      // 画像を準備&貼り付け(2)
      var img = new Image();
      img.src = 'rin.jpg';
      img.addEventListener('load', function(e) {
        c.drawImage(img, 0, 0, 400, 300);
      });
    }
  }
);
図11:円の内部でのみ画像を描画(クリックで拡大)

この例では、arcメソッドで円のパスを定義した後で、clipメソッドを呼び出していますので(1)、以降の画像貼り付け(2)は円で囲まれた領域内に対してのみ反映されることになります。

サンプルでは、strokeメソッドで枠囲みしていますが、単にクリッピング領域を定義したいだけであれば、strokeメソッドは省略しても構いません。

クリッピング領域とパスを組み合わせることで、より複雑な画像の貼り付けが可能になります。

TIPS 027:特定の座標がパス領域に含まれるかを判定する

isPointInPathメソッドを利用することで、指定された座標が現在のパス領域に含まれるかを判定できます。

[リスト10]座標がパスに含まれるかを確認するコード(inpath.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();
     
      //c.beginPath();
 
      // 座標(100, 100)がパスの領域内に含まれるかをチェック
      if (c.isPointInPath(100, 100)) {
        window.alert('座標はパスに含まれます。');
      } else {
        window.alert('座標はパスの領域外です。');
      }
    }
  }
);
図12:パスの領域内にある旨をダイアログ表示

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

[構文]isPointInPathメソッド

  • isPointInPath(X座標, Y座標)

isPointInPathメソッドは結果をtrue(含まれる)、false(含まれない)で返します。

なお、isPointInPathメソッドが判定するのは、現在のパスに対してです。よって、16行目をコメントインし、新たなパスを開始すると、いわゆるパスで表される領域がない状態になりますので、結果は「座標はパスの領域外です。」となります。

  • Canvas APIを使ってブラウザに図形を描画するサンプル

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

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

連載バックナンバー

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

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

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

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