Apple が Mac OS X 10.4(Tiger) の Dashboard 実装のために開発し Dashboard 用に 2 次元グラフィックス機能が定義されました。Safari 1.3 に実装されました。その後 Apple、Mozilla、Opera などからなる WHATWG の Web Applicatoin 1.0 の一部分として標準化中にあります。
現在は 2 次元グラフィック機能が提供されていますが、WHATWG では今後 OpenGL ES の API を元にした 3次元グラフィックス用のコンテクストを策定する予定とのことです。
canvas 要素以外にも、Web 上の 2 次元グラフィックスといえば SVG 等がありますが canvas 要素の利点は何でしょうか ? 私は、描画した図形にアクセスすることはできないが、よりプログラミングしやすい設計になっているということではないかと思っています。
書いた後からの編集は必要ないが、図形を手っ取り早く描画したいというときに有効だと思われます。
例えば、四角形を 100 個描画したいという場合、SVG では rect 要素(ないしは path 要素)を DOM で生成して DOM ツリーに追加しなくてはなりません。しかし canvas ではメソッド一つで四角形を描画できます。
他にも、現在の描画を上書きしていくアニメーションを簡単に書くことができます。しかしそれほど他の仕様との住み分けを考えている訳では無いようです。
始めに
canvas 要素に関する情報は Drawing Graphics with Canvas がありますが、そこにはあまり詳しい解説は有りませんでした。そこで「もう少し詳しい解説を書いてみようじゃないか」と無謀にも思い、書きはじめました。ノロノロと少しずつ書いていきましたが、その間に Devmo に Canvas Tutorial の執筆が開始されました。Canvas Tutorial は非常に内容が充実しているのでこの記事も参考にしています。
また、この記事は自分が特に気になった機能をを中心に書いていますので非常に内容が偏っています。
canvas 要素とは
canvas 要素はカスタム描画を行うための要素です。
Apple が Mac OS X 10.4(Tiger) の Dashboard 実装のために開発し Dashboard 用に 2 次元グラフィックス機能が定義されました。Safari 1.3 に実装されました。その後 Apple、Mozilla、Opera などからなる WHATWG の Web Applicatoin 1.0 の一部分として標準化中にあります。
現在は 2 次元グラフィック機能が提供されていますが、WHATWG では今後 OpenGL ES の API を元にした 3次元グラフィックス用のコンテクストを策定する予定とのことです。
canvas 要素以外にも、Web 上の 2 次元グラフィックスといえば SVG 等がありますが canvas 要素の利点は何でしょうか ? 私は、描画した図形にアクセスすることはできないが、よりプログラミングしやすい設計になっているということではないかと思っています。 書いた後からの編集は必要ないが、図形を手っ取り早く描画したいというときに有効だと思われます。 例えば、四角形を 100 個描画したいという場合、SVG では rect 要素(ないしは path 要素)を DOM で生成して DOM ツリーに追加しなくてはなりません。しかし canvas ではメソッド一つで四角形を描画できます。 他にも、現在の描画を上書きしていくアニメーションを簡単に書くことができます。しかしそれほど他の仕様との住み分けを考えている訳では無いようです。
Mozilla の実装
Mozilla では WHATWG の仕様に基づいて 2 次元グラフィック用コンテクストを実装していますが、独自に拡張している部分もあります。公式に使われているバックエンドは cairo ですが、GDI+ や Java2D による実装もあるようです。
Mozilla の実装では canvas 要素には閉じタグ(</canvas>)が必須となっています。また canvas 要素は XHTML の名前空間(http://www.w3.org/1999/xhtml)に属しています。
基本
以降、2 次元グラフィックス機能について紹介していきます。 canvas 要素は
widthとheightという属性とtoDataURLとgetContextというメソッドを持っています。widthとheightはキャンバスの大きさを指定します。widthとheightが変更されるとキャンバスに描かれた内容も初期化されます。描画コンテクストを得るには
getContext()を使います。2次元グラフィックの場合はgetContext('2d')となります。var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d');その他ベンダによるコンテクストは
getContext('ベンダ名-コンテクスト名')となるそうですが、今のところ無いようです。未実装ブラウザ対策
canvas 要素が実装されていないブラウザでは canvas 要素は表示されないので代替内容を書いておきましょう。object 要素等と同じように <canvas> と </canvas> の間に代替内容を書きます。
また JavaScript でエラーを起こさないようにするために Canvas Tutorial では
var canvas = document.getElementById('canvas'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); // drawing code here }というのが紹介されています。また
var canvas = document.getElementById('canvas'); if (!canvas.getContext) return;の方が良いかもしれません。因みに私は以下のようなコードを使っていました。
try { var ctx = document.getElementById('canvas').getContext('2d'); } catch (ex) {} if(!ctx) return;画像をデータ URI に変換する
toDataURL()初期値は image/png ですが、WHATWG の仕様には image/jpeg、image/svg+xml などもあがっています。現在 Mozilla では image/png のみをサポートしており、image/jpeg などが指定されても image/png の結果を出力します(WHATWG の仕様どおり)。Gecko が cairo に移行されと、application/pdf にも対応するかもしれません。
canvas.toDataURL(); canvas.toDataURL('image/png');toDataURLAs()という Mozilla の独自拡張のメソッドがありますが、現在はtoDataURLと変わらないようです。パス
この章は非常にやる気がありません。
beginPath()closePath()moveTo(x 座標, y 座標)lineTo(x 座標, y 座標)quadraticCurveTo(制御点の x 座標, 制御点の y 座標, 終点の x 座標, 終点の y 座標)bezierCurveTo(制御点1の x 座標, 制御点1の x 座標, 制御点2の x 座標, 制御点2の x 座標, 終点の x 座標, 終点の y 座標);arcTo(始点の x 座標, 始点の y 座標, 終点の x 座標, 終点の y 座標, 半径)arc(x 座標, y 座標, 半径, 開始角度, 終了角度, 左回り(時計と逆向き)かどうか?)arcの角度指定は両方とも ラジアン です。左回り(時計と逆向き)かどうか?は true か false の値を取りますrect(x 座標, y 座標, 幅, 高さ)以下のメソッドを実行しないと実際に描画は行われません。
fill()stroke()clip()四角形
fillRect(始点の x 座標, 始点の y 座標, 幅, 高さ)strokeRect(始点の x 座標, 始点の y 座標, 幅, 高さ)clearRect(始点の x 座標, 始点の y 座標, 幅, 高さ)四角形の指定方法は (始点の x 座標, 始点の y 座標, 幅, 高さ)の順に指定します。
fillRect()は指定された範囲を塗りつぶしの四角形で描画します。strokeRect()は指定された範囲を枠の四角形で描画します。clearRect()は指定された範囲を消します(透明の黒で塗りつぶします)色等
strokeStyleは枠のスタイルを、fillStyleは塗りつぶしのスタイルを決定します。後述するグラデーションやパターンを使わない場合は色を指定します。色の記述方法は何通りかあります。CSS 3 Color の記述方法が使えます。標準では黒です。
色名は HTML 4 で定義されているものだけではなく SVG 1.0 で定義された色も指定できます。 transparent は透明で、 rgba(0,0,0,0) を意味します。
clearRect()などで使われる透明の黒はこれを意味しています。 currentColor は現在使われている色を表します。rgb()、rgba() では赤、青、緑の指定に % と 0 から 255 までの数値による指定ができます。rgba()、hsla() とも透明度は 0 から 1 までの数値です。線のスタイル
lineWidth= 数値lineCap= butt/round/squarelineJoin= miter/round/bevel線の太さは
lineWidthで指定します。初期値は 1.0 です。線の端は
lineCapで指定します。 butt、round と square の値を取れます。butt は初期値で端を作りません、round は線の幅の 1/2 の長さの半円の端を作ります。square は線の幅の 1/2 同じ長さの四角い端を作ります。線と線の接続方法
lineJoinは miter は round と bevel の値を取ります。初期値は miter で直線的に接続します。 round は角で常に幅が一定になるように丸めます。bevel は角が削られたような形になります。サンプルが Canvas tutorial にありますので、そちらを御覧ください
画像の表示
drawImage(img/canvas 要素, 表示される x 座標, 表示される y 座標)drawImage(img/canvas 要素, 表示される x 座標, 表示される y 座標, 表示される幅, 表示される高さ)drawImage(img/canvas 要素, 切り抜き始める x 座標, 切り抜き始める y 座標, 切り抜く幅, 切り抜く高さ, 表示される x 座標, 表示される y 座標, 表示される幅, 表示される高さ)HTML の img 要素や canvas 要素の中身を描画できます。img 要素は
new Image()で生成したり、document.images等でアクセスできます。もちろんdocument.getElementById等でも取得したノードを指定することができます。引数の数によって処理方法があるので注意が必要です。引数が足りないとエラーが発生します。引数3個の場合は画像を指定された座標に表示する、引数5個の場合は画像を拡大縮小して表示する。引数9個の場合は切り抜いて表示します。
変形
translate(移動先の x 座標, 移動先の y 座標)scale(倍率)rotate(回転角)translate()は移動を行います。translate()した先が新しく (0,0)になります。scale()は拡大縮小を行います。引数倍されます。rotate()は回転を行います。引数はラジアンでは無く度です引数はラジアンですグラデーション
createLinearGradient(始点の x 座標, 始点の y 座標, 終点の x 座標, 終点の y 座標)createRadialGradient(1始点の x 座標, 始点の y 座標, 始点の半径, 終点の x 座標, 終点の y 座標, 終点の半径)fillStyleやstorkeStyleにグラデーションを設定することでグラデーションを持った図形を描画できます。 線形グラデーションと円形グラデーションがサポートされています。createLinearGradient()は線形グラデーション、createRadicalGradient()は円形グラデーションを作ります。 グラデーションストップはグラデーションにaddColorStop()を使って指定します。第1引数が場所です。場所は 0 がグラデーションの始点で 1 がグラデーションの終点です。また
等と変数としておく方法が Canvas Tutorial にあります。こちらの方がよいでしょう。
パターン
createPattern(img/canvas要素, 繰り返しパターン)WHATWG の仕様ではパターンの実装はオプションですが、Mozilla では実装してます。
fillStyleやstrokeStyleにパターンを設定することでパターンを持った図形を描画できます。 第1引数がパターンとなる img/canvas 要素、第2引数が繰り返し方法です。 繰り返し方法は repeat と repeat-x repeat-y no-repeat です。それぞれの値の意味は CSS の background-repat と同じですといえば分かり易いでしょうか。repeat は縦と横に繰り返し、repeat-x は横に繰り返し、repeat-y は縦に繰り返し、no-repeat は 繰り返し無しです。パターンを未実装の場合は createPattern() は null を返します。
影
shadowColor= 色shadowOffsetX= 数値shadowOffsetY= 数値shadowBlur= 数値影のサポートもオプショナルです。Mozilla では現在の所実装していません。
shadowColorで影の色をshadowOffsetXとshadowOffsetYで影がどれだけ離れるかを設定します。shadowBlurでは影のぼかし具合を指定します。shadowColorは透明の黒、shadowOffsetXとshadowOffsetYは 0、shadowBlurも 0 で初期化されます。コンポジション
globalAlpha= 数値globalCompositeOperation= 方法globalAlphaは全体の透明度を指定します。0(透明)から 1(不透明)までの値を取り、初期値は 1.0 です。globalCompositeOperationは描画されるグラフィックスの処理方法を指定します。詳しいことは仕様書を読むか、実験して下さい(いい加減極まりない)。
ウィンドウのキャプチャ
drawWindow(window, 始点の x 座標, 始点の y 座標, 幅, 高さ, 背景色)これは Mozilla が独自に実装した機能でウィンドウのキャプチャを行います。このメソッドを使うには chrome 特権が必要です。
背景色で塗りつぶされた領域にキャプチャされた結果が書き込まれるようです。'rgba(0,0,0,0)' が背景色に指定されると透明な領域にキャプチャした内容を描画するようです。WMODE="transparent" の Flash 以外のプラグインのキャプチャはできないそうです。
更新記録
10/10 rotate の引数がラジアンだったので度と誤っていた書いていたのを修正。
10/04 改題