fc2ブログ

HTML5 Canvasで画像を回転させる

HTML5 Canvasで画像を回転させることができたので、自分なりの解説を加えてやり方をまとめる。
自分が作った、画像を回転させるページ
<注意>以下で解説するやり方は、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() を行う。
(「なぜ変形メソッドは変形の順序と逆の順序で記述するのか」については [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: に詳しい解説がある。

なお、canvasの一部を切り取って表示する putImageData() メソッドにはこの方法を適用できない。
putImageData() メソッドの仕様に以下の記述がある。
現在のパス、変換マトリックス、シャドー属性、グローバル・アルファ、クリッピング領域、グローバル・コンポジション演算子は、getImageData() と putImageData()メソッドに影響を与えてはいけません。
つまり、変形メソッドで変換マトリックスを変更しても putImageData() で描画されるImageDataには影響しない。
スポンサーサイト



コメント

FlashCanvas ライブラリの紹介

こんにちは。

ExplorerCanvas と差し換えて使うことのできる FlashCanvas (http://flashcanvas.net/) というライブラリを開発しているのですが、このライブラリを excanvas.js の代わりに用いると、IE でもこのサンプルが動きますので、ぜひ試してみて下さい。

Re: FlashCanvas ライブラリの紹介

コメントありがとうございます。
早速上記の http://www21.atpages.jp/mimami/imgrot.html でFlashCanvasを使わせていただきました。

コメントの投稿

非公開コメント

プロフィール

himax64

Author: 南西
30代後半の無職です。
就活もせずダラダラ生きてます。
作ったもの

最新記事
人気記事
検索フォーム
カテゴリ
月別アーカイブ
最新コメント
最新トラックバック
RSSリンクの表示
QRコード
QRコード
カウンター