連載
» 2012年08月01日 00時00分 UPDATE

Webグラフィックをハックする(4):Canvas APIの基礎 (1/5)

もともと、Appleが主にDashboardウィジェットの描画のためにWebKitに導入したCanvas API。サンプルコードと見比べながら、効率良く学習しよう

[伊藤千光,WebOS Goodies]

Canvas APIの基礎

 本連載では、Webブラウザ上で利用できるグラフィック技術を分かりやすく紹介しています。今回はHTML5のcanvas要素で使える2次元描画コンテキスト、俗にいう「Canvas API」を取り上げます。

 Canvas APIは、もともとAppleが主にDashboardウィジェットの描画のためにWebKitに導入したものです。それがFirefoxやOpera、Internet Explorer(9以降)に実装され、現在はW3Cによって標準化が進められています。JavaScriptのメソッドで直接図形を描画するのが特徴で、ビットマップ画像の加工や、ゲームのようなインタラクティブ性の高いアプリケーションに向いています。

 今回もこれまで同様に5ページを使ってCanvas APIの主要な機能を解説します。網羅性を上げるために文章による説明は最小限に抑えていますが、サンプルコードと見比べながら読み進めれば効率良く学習できるはずです。

 Canvas APIによる描画の流れ

 さっそくですが、Canvas APIの解説に入りましょう。まずは輪郭線付きの四角形を描画する以下のHTML/JavaScriptコードを例にして、基本的な流れを説明します。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Canvas APIの基礎</title>
  </head>
  <body>
    <canvas id="canvas" width="400" height="400">
      赤い四角形を表示
    </canvas>
    <script>
      var canvas = document.getElementById('canvas');
      if(canvas && typeof(canvas.getContext) === 'function') {
        var ctx = canvas.getContext('2d');
        if(ctx) {
          ctx.clearRect(0, 0, 300, 300);
          ctx.strokeStyle = "#c00";
          ctx.fillStyle   = "#fcc";
          ctx.fillRect(50, 50, 200, 200);
          ctx.strokeRect(50, 50, 200, 200);
        }
      }
    </script>
  </body>
</html>

 Canvas APIで図形を描画するには、まず、canvasタグをドキュメント内に配置して描画を行う領域を確保します。width/height属性は領域の縦/横ピクセル数です。canvasタグ以下の内容は、Canvas API未サポートのブラウザで表示される代替コンテンツで、表示内容の説明などを書くことが推奨されています。id属性はJavaScriptから参照するためのもので、必須ではありませんが、多くの場合記述することになるでしょう。

canvasタグの書式 canvasタグの書式

 ここからはJavaScriptによる処理となります。まずgetElementById()などでcanvasタグのDOMオブジェクトを取得し、getContext()メソッドで「描画コンテキスト」を取得します。引数は描画コンテキストの種類を示す文字列ですが、Canvas APIの場合は常に"2d"を指定します。

getContext()メソッドの書式 getContext()メソッドの書式

 描画コンテキストが取得できれば、そのメソッドを利用して描画を行います。例えば、矩形の描画メソッドには以下の3つがあります。

矩形の描画メソッド 矩形の描画メソッド

 clearRect()は指定した領域をrgba(0, 0, 0, 0)で塗りつぶすメソッドで、描画処理開始時の画面クリアに使うのが一般的です。fillRect(), strokeRect()はそれぞれ矩形の塗りつぶしと輪郭線の描画を行うメソッドです。Canvas APIでは図形の塗り潰しを行うメソッドと輪郭を描画するメソッドが別々に用意されており、輪郭のみの図形、塗り潰しのみの図形などが描き分けられるようになっています。

 塗り潰し・輪郭線の描画色は、それぞれfillStyle属性とstrokeStyle属性にCSS形式の色指定文字列を設定することで行います。グラデーションやパターンも使えますが、その方法は後のページで解説します。

 パスの描画

 Canvas APIでは、既出の四角形と後述する文字列、画像以外の図形はすべてパスとして描画します。以下に簡単なパスを描画するコード例を示します。

※ 上記のサンプルコードは、変数ctxに描画コンテキストが取得できているものとして、描画部分のコードのみを示しています。以降のサンプルも同様です。

 描画するパスは、beginPath()の呼び出し後に形状を定義する以下のメソッドを並べることで定義できます。

形状定義メソッド 形状定義メソッド

 座標を移動させるmoveTo()を除き、上記のメソッドは前の図形の終点を始点として図形をパスに追加し、その終点を次の図形の始点とします(rect(), arc()は前の図形の終点から矩形・円弧の始点まで直線を引きます)。従って、例えばlineTo()を次々に呼び出すだけで連続した折れ線のパスが定義できます。

 上記のメソッドでパスを定義した後に、fill()やstroke()を呼び出すことで塗り潰しや輪郭線が描画できます。定義したパスは次にbeginPath()を呼び出すまで維持されるので、塗り潰しと輪郭線の両方を描画する場合でもパスを再定義する必要はありません。

 文字列の描画

 文字列の描画は、fillText()およびstrokeText()メソッドで行います。これらのメソッドの呼び出し方法を以下に示します。

文字列描画メソッド 文字列描画メソッド

 x, yで指定する座標がどの位置を示すかは、後述のtextAlign, textBaseline属性の値によって変化します。省略可能な引数maxWidthが指定された場合は、文字列全体がその幅に収まるように、必要に応じてより小さいフォントで描画されます。以下に使用例を示します。

 文字列の描画に使用するフォントは、font属性にCSSのfontと同じ書式で指定します。デフォルトは"10px sans-serif"です。フォントサイズ等を相対指定(em, largerなど)した場合、canvasタグに適用されているフォントを基準に計算されます。

font属性の指定 font属性の指定 実際のサンプルを見る

 fillText()またはstrokeText()メソッドの引数xが示す個所は、textAlign属性によって決まります。指定できる値はleft, center, right, start, end で、最後の2つはCSSのdirection属性によって右端もしくは左端のいずれかとなります。デフォルト値は"start"です。

textAlignの効果 textAlignの効果 実際のサンプルを見る

 同様に、y引数が示す個所はtextBaseline属性によって決まります。指定できる値はtop, hanging, middle, alphabetic, ideographic, bottomです(デフォルトは"alphabetic")。例えば、"top"を指定すると、下図の「top of em square」が引数yの座標になります。

Working Draftより引用 Working Draftより引用

 また、文字列関連の機能として、measureText()メソッドで指定した文字列を描画した際の横幅を取得することも可能です。引数は横幅を取得する文字列で、返り値はTextMetricsオブジェクトです。横幅は、TextMetricsオブジェクトのwidth属性に格納されています。

 measureText()の使用例として、文字列のアンダーラインを描画するコードを以下に示します。Canvas API自体には文字列にアンダーラインを付与する機能はありませんが、measureText()で文字列の横幅を算出して自前で描画できます。

文字列のアンダーラインを描画 文字列のアンダーラインを描画 実際のサンプルを見る

 画像の描画

 画像はdrawImage()メソッドで描画できます。画像のリサイズやトリミングの要/不要によって、以下の3つの呼び出し方があります。

画像描画メソッド 画像描画メソッド

 共通の第1引数であるimageは、img、video、canvasのDOMオブジェクトです。ただし、読み込みが完了していないと描画されないので、loadもしくはloadeddataイベントを待つ必要があります。

 画像のリサイズが必要な場合は、2番目の形式でdrawImage()を呼び出します。画像を横幅dw、高さdhにリサイズして描画します。

画像のリサイズ 画像のリサイズ 実際のサンプルを見る

 画像のトリミングが必要なら3番目の形式を使用します。元画像の(sx, sy)から幅sw、高さshの領域を、canvas内の(dx, dy)の位置に幅dw、高さdhで描画します。

画像のトリミング 画像のトリミング 実際のサンプルを見る

 回転等の変形は、後のページで取り上げる座標変換を併用することで実現します。

       1|2|3|4|5 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

Focus

- PR -

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。