Hatena::ブログ(Diary)

あらびき日記 Twitter

2012-07-24

HTML5 の Canvas で getTransform が使えるようにしてみた

CanvasRenderingContext2D には setTransform があるのに getTransform はありません。

transform, rotate, save, restore などを駆使して変換しまくってると、現在どのような変換行列が適用されているのかよくわからなくなり、表示が乱れていてもデバッグしにくいこと極まりないです。

実際、「canvas gettransform」でググると「getTransform 欲しいよね」とか、「どうやったら現在の変換行列の状態が取得できるか?」とか、出てきます。その割に誰も getTransform を実装している気配がありません。


というわけで実装してみました。

------ 2012-07-24 追記 --------

行列の掛け算が逆になっているという悲惨な状態だったので修正しました。ご指摘ありがとうございます。


このスクリプトをロードすることで CanvasRenderingContext2D#getTransform が使えるようになります。

現在の変換行列の状態を長さ6の配列で返します。配列の各要素の順番は CanvasRenderingContext2D#setTransform の引数の順番に対応しています。



サンプル

こちらのサンプルを拝借して途中の変換行列の状態を表示してみます。

<html>
<head>
<script type="text/javascript" src="canvas_get_transform.js"></script>
<script type="text/javascript">
function draw() {
    var ctx = document.getElementById('canvas').getContext('2d');
    ctx.translate(75,75);

    for (var i=1;i<6;i++){ // Loop through rings (from inside to out)
        ctx.save();
        ctx.fillStyle = 'rgb('+(51*i)+','+(255-51*i)+',255)';

        for (var j=0;j<i*6;j++){ // draw individual dots
            ctx.rotate(Math.PI*2/(i*6));
            ctx.beginPath();
            ctx.arc(0,i*12.5,5,0,Math.PI*2,true);
            ctx.fill();
            console.log(ctx.getTransform());
        }
        ctx.restore();
    }
}
</script>
</head>
<body onload="draw()">
</body>
<canvas id="canvas"></canvas>
</html>

表示結果は次のようになります。

f:id:a_bicky:20120724043342p:image


・・・パッと見ても合ってるのか間違ってるのかよくわかりませんが、とりあえず変換行列の状態が取得できてるっぽいです。



精度の問題で微妙にずれたり、canvas のサイズをいじった時のことを考慮できてなかったりしますが、デバッグ用途としてはそれなりに機能するのではないでしょうか。


というわけで、よかったらお使いください!

anatooanatoo 2012/11/11 09:19 こんにちは。
使いたいのですがこのコードのライセンスって何でしょうか?

a_bickya_bicky 2012/11/11 12:51 ありがとうございます!MIT ライセンスにしました。

anatooanatoo 2012/11/12 00:59 MITライセンスですね!ありがとうございます!
丁度探していたので助かります。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/a_bicky/20120724/1343084686