るきおWeb研究所 HTML5 APIリファレンス
HTML5 canvas

tranform メソッド

出典:HTML Canvas 2D Context 2012年3月7日 Editor's Draft版 http://dev.w3.org/html5/2dcontext/


描画する図形の変換行列を直接変更します。

1.構文

void transform(double a, double b, double c, double d, double e, double f);

パラメーター

a c e
b d f
0 0 1

各パラメーターは上記の変換行列上の位置を意味します。

2.解説

このメソッドを呼び出すと現在の変換行列が変更されます。既に描画した内容に影響を与えるのではなく、これから描画する内容に影響を与えます。

変換行列の変更が具体的に描画に及ぼす影響は数学のアフィン変換の法則によります。ただしアフィン変換を理解していなくてもscaleメソッド、rotateメソッド、translateメソッドを使って描画する図形を拡大・縮小・回転・平行移動することができるのでこれらの組み合わせで済む場合transformメソッドを使用する機会はありません。

transformメソッドはこれ以外のあらかじめ用意されていない変換を使用するときに意味があります。たとえば、原点以外を中心とした回転、傾斜(正方形を平行四辺形にするような効果)がこれに該当します。(ただし、原点以外を中心とした回転はtranslateメソッドとrotateメソッドを組み合わせることでも可能です。)

アフィン変換の説明や具体的な行列は末尾の参考サイトで詳しく説明されています。

主な変換は次のような行列で表現できます。

平行移動

X軸方向にdx、Y軸方向にdy平行移動させる変換行列。これはtranslate(dx, dy)の効果と同じです。

1 0 dx
0 1 dy
0 0 1

拡大・縮小

X軸方向にdx倍、Y軸方向にdy倍する変換行列。これはscale(dx, dy)の効果を同じです。

dx 0 0
0 dy 0
0 0 1

回転

原点を中心にθラジアン回転する変換行列。これはrotate(θ)の効果と同じです。

cosθ sinθ 0
-sinθ -cosθ 0
0 0 1

原点以外の点(x, y)を中心にθラジアン回転する変換行列。これはtranslate(x, y)とrotate(θ)を連続して使用した場合の効果と同じです。

cosθ sinθ x(1-θ)+y(sinθ)
-sinθ -cosθ x(-sinθ)+y(1-cosθ)
0 0 1

傾斜

点(x, y)を傾斜に中心にX軸に沿ってΘ、Y軸に沿ってΦ傾斜させる変換行列。これは他のメソッドでは表現できません。

1 tanΦ -y(tanΘ)
tanΘ 1 -x(tanΦ)
0 0 1

transformメソッドで直接変換行列を定義すればどのような変換でも行えるわけではなくあくまでもアフィン変換で扱える範囲での変換に限定されます。アフィン変換では変換前の直線は、変換後も直線であるため歪曲されて歪ませるような効果を使用することはできません。

transformメソッドが変更する変換行列はtransformメソッドとは独立して存在しています。transformメソッドは既定の変換行列とパラメーターで指定した変換行列の積を新しい変換行列にするためtransformメソッドを重ねて使用すると効果は累積します。

変換行列を初期状態に戻すにはsetTransform(1, 0, 0, 1, 0, 0)を使用します。または特定の時点でsaveメソッドで状態を保存し必要に応じてrestoreメソッドでその時点の状態を復元することもできます。

変換行列の影響を受けるのは以下のメソッドです。

transformメソッドのほかに変換行列に影響を与えるのはscaleメソッド、rotateメソッド、translateメソッド、setTransformメソッドです。

3.例

以下の例では2つ四角形を描きます。2つ目の四角形は2倍の大きさでX軸方向に100ピクセル平行移動して描きます。同じ効果を得るのにtranslateメソッドとtranslateメソッドの2つを使った方がわかりやすく書けます。

var canvas1 = document.getElementById('Canvas1');
var ctx = canvas1.getContext('2d');

ctx.fillRect(10, 0, 50, 50);

//2倍にしてX軸方向に100ピクセル平行移動
ctx.transform(2, 0, 0, 2, 100, 0);
ctx.fillRect(10, 0, 50, 50);

以下の例では文字と四角形を30度傾けて描画します。(同時にX軸方向へ100ピクセルの平行移動も行っています。)

transformメソッドで傾ける例

var canvas1 = document.getElementById('Canvas1');
var ctx = canvas1.getContext('2d');

ctx.font = '48pt Bold';
ctx.textBaseline = 'top';

//通常に字を描く
ctx.strokeText('竜', 20, 20);
ctx.strokeRect(20, 20, 70, 70);


//30度傾けて字を描く
var inclination = Math.tan(30 * Math.PI / 180);
ctx.strokeStyle = 'red';
ctx.transform(1, inclination, 0, 1, 100, 0);
ctx.strokeText('竜', 20, 20);
ctx.strokeRect(20, 20, 70, 70);

4.プラットフォーム

HTML5

実際に動作確認したブラウザ:IE9

実際に動作確認した結果想定通り動かなかったブラウザ:なし

5.参考

各変換行列については以下から引用しました。このサイトには数学的な説明もありアフィン変換を理解したい人には良い内容だと思います。

付録:行列変換 http://msdn.microsoft.com/ja-jp/library/ff684171(v=vs.85).aspx