動画・音声のブラウザ対応状況、canvasによる描画

2012年4月24日(火)
飯島 聡(著)山田 祥寛(監修)

動的なグラフィック描画

canvas要素によって、クライアント側の処理だけで、動的にグラフィックスを描画できるようになりました。ゲーム用途ではもちろん、ビジネス用途でもリアルタイムなグラフの描画など、応用が期待できます。

canvas要素自体は、何もない描画領域の宣言だけです。

[サンプル]canvas要素の簡単な使用方法(canvas_sample1.html)

<canvas id="mycanvas" width="600" height="400">
このブラウザではcanvas要素はサポートされていません。</canvas>

描画のロジックは、JavaScriptを使用します。

[サンプル]JavaScriptで描画(canvas_sample1.html)

<script>
  //loadイベントに後述のdrawGraphicsメソッドの関連付け
  window.addEventListener("load",drawGraphics,false);
  //指定した要素のcanvas要素に対応したコンテキストオブジェクトを取得
  function getContext(canvasId){
    return document.getElementById(canvasId).getContext("2d");
  }
  //コンテキストを呼び出し、描画を実行
  function drawGraphics(){
    context = getContext("mycanvas");
    draw1(context);
  };
  //描画の手続きの例。1箇所で曲がる折れ線の例
  function draw1(context){
    context.moveTo(100,50);//始点(パス開始)
    context.lineTo(200,250);//結節点
    context.lineTo(500,100);//終点
    context.stroke();//パスを描画
  };
</script>
 図8:簡単な折れ線(クリックで拡大)

canvasに対する描画は、コンテキストオブジェクトを介して行います。canvas要素オブジェクトのgetContextメソッドで生成できます。引数の"2d"とは2Dの図を描画するという意味です。

コンテキストオブジェクトは、ザックリ言ってしまうならば、現在の描画状態を管理するためのオブジェクトです。具体的には描画状態とは、描画のための座標情報(パス)や線の太さや色、塗りつぶしの色やパターン、テキストならばフォント等を表します。

パスは具体的には複数のサブパスからなります。サブパスとは、ひとつながりの折れ線や曲線の事です。1つのパスは、stroke(パス描画)やfill(パスが囲む領域の塗りつぶし)などのメソッドを使う事で、canvas上に描画されます。

基本的な図形描画の例

以下では、Canvas機能による図形描画の代表的な例を示します。なお、以降のサンプルでは、コンテキストオブジェクトcontextのメソッド呼び出し部分のみ掲載します。

(1)領域のクリア

clearRectメソッドでCanvasを透明色で塗りつぶせます。

[サンプル]領域のクリア(canvas_sample2-1.html)

//Canvasをクリアする
  context.clearRect(0,0,context.canvas.width,context.canvas.height);

領域のサイズは、Canvas要素オブジェクトのwidth/heightプロパティから取得しています。サンプルではあまり意味がありませんが、既に使用されたCanvasを繰り返し使う場合に使用します。

fillStyleプロパティ(塗りつぶし色)に従って図形を塗りつぶすfillRectメソッドを代わりに使用しても構いません。

(2)閉じた図形の描画

closePathメソッドでパスの始点と終点をつないで、閉じた図形を描画します(このようなパスの事を、クローズパスと言います*)。線の太さや接合部の形状、塗りつぶしの色等を変更できます。fillメソッドとstrokeメソッドで、実際にCanvas上に描画します。

*)折れ線グラフのように、始点と終点とが結ばれないパスの事を、オープンパス(開かれたパス)と言います。

[サンプル]閉じた図形の描画(canvas_sample2-1.html)

  //1つ目のパスの開始
  context.beginPath();
  context.moveTo(150,50);//サブパス開始
  context.lineTo(250,150);
  context.lineTo(50,120);
  context.closePath();//サブパスを閉じる(三角形)
  context.strokeStyle = "#000080";//暗い青色
  context.lineWidth = 5;//線の太さ
  context.lineJoin = "round";//線の接合部を丸くする
  context.fillStyle = "#00FF00";//明るい緑色
  context.fill();//塗りつぶし実行
  context.stroke();//パス描画実行
 図9:閉じた図形の描画実行結果(クリックで拡大)

strokeStyle(線の色)、lineWidth(線の太さ)、lineJoin(線の接合部の形状)、fillStyle(塗りつぶしの色、スタイル)は、いずれも描画状態を表すプロパティです。strokeStyle/fillStyleプロパティには、CSSの色指定文字列を使用できます。

(3)パスに図形を追加する(四角形、ベジエ曲線)

rectメソッドは現在のパスに四角形を追加するメソッドです。以下では、(2)のサンプルのコードのfillの前まで同じコードだとします。rectメソッドで四角形を追加した上で、fillメソッドで塗りつぶします。

[サンプル]四角形の追加(canvas_sample2-2.html)

  //・・・((2)のサンプルコード)
  context.rect(200,70,150,90);//四角形を追加
  context.fill();//塗りつぶし実行

さらに、bezierCurveToメソッドを呼び出してベジエ曲線(制御点と端点から定まる曲線)を生成します。lineCapプロパティを"round"(先端の形状を丸く)した上で、strokeメソッドを呼び出したのが、以下の結果です。

[サンプル]ベジエ曲線の追加(canvas_sample2-2.html)

  //・・・(続き)
  context.moveTo(100,150);//サブパス開始
  context.bezierCurveTo(200,150,200,250,300,250);//3次ベジエ曲線
  context.lineCap = "round";//線の先端を丸くする
  context.stroke();//パス描画実行
 図10:図形追加の実行結果(クリックで拡大)

stroke/fillメソッドを呼び出す事で、beginPathメソッド以降のパスが同じ描画情報をもとに描画されます。別の図形を別の色で描画したい場合は、beginPathメソッドを使用して、いったんパスを再開した上で各描画状態プロパティを変更します。

この他にもパスに図形を追加するメソッドとして、quadraticCurveTo(2次ベジエ曲線)、arc(円弧)、arcTo(円弧)などのメソッドがあります。

 図11:さらに図形追加した結果(クリックで拡大)

(4)グラデーション効果を作成する

fillStyle(塗りつぶしスタイル)には、色指定文字列だけでなく、CanvasGradientオブジェクト(グラデーション)を設定できます。

[サンプル]グラデーション効果(canvas_sample2-4.html)

//グラデーションを定義
var g = context.createLinearGradient(350,250,500,350);
g.addColorStop(0,"pink");
g.addColorStop(0.5,"red");
g.addColorStop(1,"yellow");
context.fillStyle = g;	//塗りつぶし色にグラデーションを設定
//直接長方形を描画する
context.fillRect(350,250,150,100);
 図12:グラデーション効果(クリックで拡大)

CanvasGradientオブジェクトはcreateLinearGradient(線形グラデーション)やcreateRadialGradient(放射状グラデーション)で作成します。createLinearGradientの引数はグラデーション方向を示す線分の始点と終点です。createRadialGradientの引数はグラデーションの開始円と終了円(いずれも中心座標と半径)です。

CanvasGradientオブジェクトのaddColorStopメソッドで、0(始点に対応)から1(終点に対応)の間のいくつかのポイントごとの色を設定します。addColorStopメソッドの間の領域が補完されてグラデーションが形成されます。

(5)文字列を描画する

文字列は、fillTextメソッドなどを使用して描画します。この場合の色(または塗りつぶしスタイル)は、他の図形と同じようにfillStyleプロパティで指定します。また、fontにCSSのFont指定文字列を設定する事で、大きさ、フォントファミリ等を指定できます。

[サンプル]文字列の描画(canvas_sample2-5.html)

  //テキストの描画
  context.fillStyle ="blue";//文字色
  context.font = "36px sans-serif";//フォント指定
  context.fillText("こんにちは、HTML5 Canvas!",40,300);//テキストの描画 
 図13:文字列の描画(クリックで拡大)

文字列の描画に関しては、文字列の輪郭だけを描くstrokeTextメソッド、文字列幅を取得するmeasureTextメソッドもあります。

その他、今回説明できなかったcanvasの機能として、以下のようなものもあります。どれも使えるので、気になった方は調べてみてください。

  • 塗りつぶしの繰り返しパターン
  • 画像やピクセルデータをCanvas上に描画
  • Canvas上の領域のピクセルデータ処理
  • 図形や文字列の影の描画
  • clipメソッドによって、描画可能領域を限定して、以降の描画がその部分だけ表示する効果
  • Canvasの座標系を拡大/縮小、回転、その他行列変換によるグラフィックスの変形
  • 描画状態のスタックへの保存と復元(clipや変換を使う場合には必須)

コンテキストオブジェクトの主なメンバ

最後に、コンテキストオブジェクトで利用できる主なプロパティ、メソッドを表にまとめています。

表4:コンテキストオブジェクトのプロパティ

分類 プロパティ名 デフォルト 説明
キャンバス canvas contextに関連づいたcanvas Canvas要素
線関係 lineWidth 1 線の太さ
lineCap butt 線の端点の形状(butt:平らにする, round:丸端点, square:正方形端点)
lineJoin miter 線の接合点の形状(bevel:接合部先端を平らに切る, round:接合部先端を丸める, miter:尖りを表示)
miterLimit 10 マイターリミット(線の接合部の尖り度合い)
スタイル fillStyle #000000 塗りつぶしのスタイル(CSS色指定か、CanvasGradientオブジェクト、 CanvasPatternオブジェクトを設定)
strokeStyle #000000 線のスタイル(CSS色指定か、CanvasGradientオブジェクト、 CanvasPatternオブジェクトを設定)
テキスト font 10px sans-serif フォント(CSSでの指定と同様な書式で指定)
textAlign start 文字列の水平揃え位置(start:始まり揃え, end:終わり揃え, left:左揃え, right:右揃え, center:中央揃え)
textBaseline alphabetic 文字揃えの基準線(top:上揃え, hanging:ハンギング, middle:中揃え, alphabetic:アルファベット揃え, ideographic:漢字揃え, bottom:下揃え)
ピクセル合成 globalAlpha 1 不透明度(0:完全透明?1:不透明)
globalCompositeOperation source-over ピクセルの重ねあわせの時の結果計算方法
shadowBlur 0 影のぼかし度合い
shadowOffsetX 0 影の水平オフセット
shadowOffsetY 0 影の垂直オフセット
shadowColor rgba(0, 0, 0, 0) 影の色

表5:コンテキストオブジェクトのメソッド

分類 メソッド名 説明
パス関係 beginPath() パスの開始
fill() パスをfillStyleで塗りつぶす
stroke() パスをstrokeStyleでなぞる
isPointInPath(x, y) 指定した点が現在のパスに含まれていればtrue
clip() 現在のパスの内側のみを描画可能領域に限定
キャンバス状態 save() キャンバス状態をスタックに保存
restore() キャンバス状態をスタックから復元
サブパス構築 moveTo(x, y) サブパスの開始(始点)
closePath() サブパスと閉じる(終点を始点に設定)
lineTo(x, y) サブパスに端点を追加し直前の点と線分で結ぶ
quadraticCurveTo(cpx, cpy, x, y) サブパスに1つの制御点と端点を追加し直前の点と二次ベジエ曲線で結ぶ
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) サブパスに2つの制御点と端点を追加し直前の点と三次ベジエ曲線で結ぶ
arcTo(x1, y1, x2, y2, radius) サブパスにサブパスの終点と指定した2点からなる三角形に内接する円弧を追加
arc(x, y, radius, startAngle, endAngle [, anticlockwise ] ) サブパスに中心点と半径、開始角、終了角を指定して円弧を追加
rect(x, y, w, h) パスに長方形の閉じたサブパスを追加
長方形描画 clearRect() 指定した長方形領域を透明色で塗りつぶす
fillRect() 指定した長方形領域をfillStyleで塗りつぶす
strokeRect() 指定した長方形をstrokeStyleでなぞる
スタイル createLinearGradient(x0, y0, x1, y1) 線形グラデーション定義(開始点と終了点を指定)
createRadialGradient(x0, y0, r0, x1, y1, r1) 放射状グラデーション定義(開始円と終了円を指定)
gradient.addColorStop(offset, color) (CanvasGradientオブジェクト)0:始点~1:終点の区間に対応した色の指定
createPattern(image, repetition) タイル張りパターン定義(repetitionの値repeat:両方向に繰り返し,repeat-x:水平方向に繰り返し,repeat-y:垂直方向に繰り返し,no-repeat:繰り返さない)
テキスト measureText(text) TextMetricsオブジェクトを取得
strokeText(text, x, y [, maxWidth ] ) 文字列の輪郭をなぞる
fillText(text, x, y [, maxWidth ] ) 文字列の描画
イメージ drawImage(image, dx, dy[, dw, dh]) イメージの描画
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) イメージの一部分を描画
createImageData(sw, sh)、または(imagedata) ImageDataオブジェクトの作成
getImageData(sx, sy, sw, sh) CanvasからImageDataオブジェクトを作成
putImageData(imagedata, dx, dy [, dirtyX, dirtyY, dirtyWidth, dirtyHeight ]) ImageDataオブジェクトを描画
変換 scale(x, y) 拡大変換
rotate(angle) 回転変換
translate(x, y) 平行移動
transform(a, b, c, d, e, f) 現在の変換行列に指定した行列を乗算
setTransform(a, b, c, d, e, f) 現在の変換行列に指定した行列を設定

詳細は「HTML Canvas 2D Context」を参照してください。

まとめ

今回は、動画、音楽、グラフィックスなどのマルチメディア新機能を見てきました。次回は、WebアプリケーションとしてのHTML5新機能を説明します。

【参考文献】

HTML Canvas 2D Context

<リンク先最終アクセス:2012.04>

  • HTML5のマルチメディア機能を使ったサンプル(1/2)

  • HTML5のマルチメディア機能を使ったサンプル(2/2)

著者
飯島 聡(著)山田 祥寛(監修)
WINGSプロジェクト

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

連載バックナンバー

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

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

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

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