HTML5 Canvasで画像を回転させる
HTML5 Canvasで画像を回転させることができたので、自分なりの解説を加えてやり方をまとめる。
自分が作った、画像を回転させるページ
<注意>以下で解説するやり方は、Internet Explorer + excanvas.js では(少なくとも現時点では)動作しません。
<2010/10/21 追記>
Internet Explorer + FlashCanvas で、以下で解説するやり方で動作することを確認しました。
<追記ここまで>
1. 使用するメソッド
drawImage() メソッドで画像を表示する。
画像の回転は、変形メソッド rotate() と translate() で行う。
drawImage() メソッドの仕様に以下の記述がある。
(excanvas.js では drawImage() で描画される前に変換マトリックスが適用されないため、Internet Explorer + excanvas.js では回転しない)
2. コーディング例
rotate() メソッドは座標(0,0)を中心として回転するので、座標(cx,cy)を中心として時計回りにθ回転させる場合は次のように変形メソッドを使用する。
x軸方向に -cx 、y軸方向に -cy 移動 : translate(-cx,-cy)
↓
座標(0,0)を中心としてθ回転 : rotate(θ)
↓
x軸方向に cx 、y軸方向に cy 移動 : translate(cx,cy)
この場合のソースコードは以下のようになる。
(「なぜ変形メソッドは変形の順序と逆の順序で記述するのか」については [HTML5 Canvas]変形メソッド scale(),rotate(),translate() の実行順序 で、何となくわかったつもりになれる解説をしています)
画像データの取得およびアニメーション実行部分の例は以下のとおり
なお、canvasの一部を切り取って表示する putImageData() メソッドにはこの方法を適用できない。
putImageData() メソッドの仕様に以下の記述がある。
自分が作った、画像を回転させるページ
<注意>以下で解説するやり方は、Internet Explorer + excanvas.js では(少なくとも現時点では)動作しません。
<2010/10/21 追記>
Internet Explorer + FlashCanvas で、以下で解説するやり方で動作することを確認しました。
<追記ここまで>
1. 使用するメソッド
drawImage() メソッドで画像を表示する。
画像の回転は、変形メソッド rotate() と translate() で行う。
drawImage() メソッドの仕様に以下の記述がある。
drawImage()メソッドが呼び出されると、描画元の矩形で指定されたイメージの領域は、描画先の矩形で指定された canvas の領域に描画されなければいけません。描画される前に、描画先の矩形の地点に現在の変換マトリックスが適用されます。
つまり、変形メソッドで変換マトリックスを変更して drawImage() することにより、画像を回転させることができる。(excanvas.js では drawImage() で描画される前に変換マトリックスが適用されないため、Internet Explorer + excanvas.js では回転しない)
2. コーディング例
rotate() メソッドは座標(0,0)を中心として回転するので、座標(cx,cy)を中心として時計回りにθ回転させる場合は次のように変形メソッドを使用する。
x軸方向に -cx 、y軸方向に -cy 移動 : translate(-cx,-cy)
↓
座標(0,0)を中心としてθ回転 : rotate(θ)
↓
x軸方向に cx 、y軸方向に cy 移動 : translate(cx,cy)
この場合のソースコードは以下のようになる。
// canvasはgetElementByIdで取得したcanvas要素
// ctxはgetContextで取得したcontext
function draw(){
// canvas を消去
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.translate(cx,cy); // x軸方向にcx、y軸方向にcy移動
ctx.rotate(theta); // 座標(0,0)を中心として時計回りにθ回転
ctx.translate(-1 * cx,-1 * cy); // x軸方向に-cx、y軸方向に-cy移動
// Imageオブジェクトmyimageを、左上の角が座標(ix,iy)に来るように描画
ctx.drawImage(myimage,ix,iy);
}
変形メソッドは変形の順序と逆の順序で記述し、変形メソッド記述後に drawImage() を行う。// ctxはgetContextで取得したcontext
function draw(){
// canvas を消去
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.translate(cx,cy); // x軸方向にcx、y軸方向にcy移動
ctx.rotate(theta); // 座標(0,0)を中心として時計回りにθ回転
ctx.translate(-1 * cx,-1 * cy); // x軸方向に-cx、y軸方向に-cy移動
// Imageオブジェクトmyimageを、左上の角が座標(ix,iy)に来るように描画
ctx.drawImage(myimage,ix,iy);
}
(「なぜ変形メソッドは変形の順序と逆の順序で記述するのか」については [HTML5 Canvas]変形メソッド scale(),rotate(),translate() の実行順序 で、何となくわかったつもりになれる解説をしています)
画像データの取得およびアニメーション実行部分の例は以下のとおり
// body onloadで実行される関数
function init(){
// canvasのDOM elementとcontext取得
canvas = document.getElementById("cv1");
if ( ! canvas || ! canvas.getContext ) { return false; }
ctx = canvas.getContext("2d");
// canvasの中心座標(cx,cy)算出
cx = canvas.width / 2;
cy = canvas.height / 2;
// 画像を取得
myimage = new Image();
myimage.src = "nansya0.gif?" + new Date().getTime();
myimage.onload = function(){
// 画像をcanvasの中央に表示するように左上座標算出
ix = (canvas.width - myimage.width) / 2;
iy = (canvas.height - myimage.height) / 2;
ctx.drawImage(myimage,ix,iy);
// 100ミリ秒間隔でアニメーション
theta = Math.PI / 5; // 1回あたりの回転角をπ/5とする
timeoutID = setInterval("draw()",100);
}
}
画像を取得する部分については、画像を組み込む - Canvas - HTML5.JP: に詳しい解説がある。function init(){
// canvasのDOM elementとcontext取得
canvas = document.getElementById("cv1");
if ( ! canvas || ! canvas.getContext ) { return false; }
ctx = canvas.getContext("2d");
// canvasの中心座標(cx,cy)算出
cx = canvas.width / 2;
cy = canvas.height / 2;
// 画像を取得
myimage = new Image();
myimage.src = "nansya0.gif?" + new Date().getTime();
myimage.onload = function(){
// 画像をcanvasの中央に表示するように左上座標算出
ix = (canvas.width - myimage.width) / 2;
iy = (canvas.height - myimage.height) / 2;
ctx.drawImage(myimage,ix,iy);
// 100ミリ秒間隔でアニメーション
theta = Math.PI / 5; // 1回あたりの回転角をπ/5とする
timeoutID = setInterval("draw()",100);
}
}
なお、canvasの一部を切り取って表示する putImageData() メソッドにはこの方法を適用できない。
putImageData() メソッドの仕様に以下の記述がある。
現在のパス、変換マトリックス、シャドー属性、グローバル・アルファ、クリッピング領域、グローバル・コンポジション演算子は、getImageData() と putImageData()メソッドに影響を与えてはいけません。
つまり、変形メソッドで変換マトリックスを変更しても putImageData() で描画されるImageDataには影響しない。
スポンサーサイト