Canvasによる変形サンプル

icon 項目のみ表示/展開表示の切り替え

scale(x,y)

x x座標の拡大縮小率
y y座標の拡大縮小率
 これから描画する図形の座標の拡大縮小率を指定します。座標の拡大縮小ですので図形の大きさだけではなく位置も変化します。
 拡大縮小率は前回の変形(拡大縮小、回転、移動)に対して適用されます。 下図の例はscale(2,2)を2回指定しています。前回の2倍に対してさらに2倍を指定していますので、最後は4倍となります。
ctx.fillStyle = 'red';
ctx.font='16px serif';
ctx.fillText('1倍',0,20);
ctx.scale(2,2);
ctx.fillText('2倍',20,20);
ctx.scale(2,2);
ctx.fillText('4倍',30,20);

rotate(angle)

angel ラジアン単位の時計回りの回転角
 これから描画する図形の座標の回転角(ラジアン)を指定します。座標の回転ですので図形の傾きだけではなく位置も回転します。
 回転角は前回の変形(拡大縮小、回転、移動)に対して適用されます。 下図の例はrotate(30*Math.PI/180)を2回指定しています。前回の30度に対してさらに30度を指定していますので、最後は60度となります。
ctx2.fillStyle = 'red';
ctx2.font='16px serif';
ctx2.fillText('0',50,20);
ctx2.rotate(30*Math.PI/180);
ctx2.fillText('30',50,20);
ctx2.rotate(30*Math.PI/180);
ctx2.fillText('60',50,20);

translate(x,y)

x x座標の移動量
y y座標の移動量
 これから描画する図形の座標を移動させます。
 移動は前回の変形(拡大縮小、回転、移動)に対して適用されます。 下図の例はtranslate(30,20)を2回指定しています。前回の移動に対してさらに移動を指定していますので、最後は2倍の移動量となります。
ctx3.fillStyle = 'red';
ctx3.font='16px serif';
ctx3.fillText('0,0',0,20);
ctx3.translate(30,20);
ctx3.fillText('30,20',0,20);
ctx3.translate(30,20);
ctx3.fillText('60,40',0,20);

transform(a,b,c,d,e,f)

変換行列を使って座標を変換します。
回転、拡大、移動を一度に指定することができます。
元の座標がx,y、変換後の座標をx',y'とすると以下の式で表せます。
x'=ax+cy+e
y'=bx+dy+f
\begin{pmatrix} x'\\y'\\1\\ \end{pmatrix}=\begin{pmatrix} a&c&e\\b&d&f\\0&0&1\\ \end{pmatrix} \begin{pmatrix} x\\y\\1\\ \end{pmatrix}

回転

R=rotate(\theta)=\begin{pmatrix} \cos \theta&-\sin \theta&0\\ \sin \theta&\cos \theta&0\\0&0&1\\ \end{pmatrix}
x'=x \cos \theta-y \sin \theta
y'=x \sin \theta+y \cos \theta

拡大

S=scale(S_x,S_y)=\begin{pmatrix} S_x&0&0\\0&S_y&0\\0&0&1\\ \end{pmatrix}
x'=S_x x
y'=S_y y

移動

T=translate(D_x,D_y)=\begin{pmatrix} 1&0&D_x\\0&1&D_y\\0&0&1\\ \end{pmatrix}
x'=x+D_x
y'=y+D_y

サンプル

ctx4.fillStyle = 'red';
ctx4.font='16px serif';
ctx4.fillText('0,0',0,20);
ctx4.transform(1,0, -0.8 ,1,0,0);
ctx4.fillText('30,20',50,20);
ctx4.transform(1,0, -0.8 ,1,0,0);
ctx4.fillText('100,20',100,20);

setTransform(a,b,c,d,e,f)

 現在の変換を単位行列によりリセットして変換行列を適用します。
 現在の変換をリセットしたい場合は、以下の単位行列を適用します。
setTransform(1,0,0,1,0,0);

単位行列

\begin{pmatrix} 1&0&0\\0&1&0\\0&0&1\\ \end{pmatrix}

サンプル

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
</head>
<body>
  <canvas id="t1" width="320" height="100">
  </canvas><br />
  <canvas id="t2" width="100" height="80">
  </canvas><br />
  <canvas id="t3" width="100" height="70">
  </canvas><br />
  <canvas id="t4" width="320" height="30">
  </canvas><br />

  <script type="text/javascript">
    window.onload = function(){
      var canvas = document.getElementById('t1');
      var canvas2 = document.getElementById('t2');
      var canvas3 = document.getElementById('t3');
      var canvas4 = document.getElementById('t4');
      if (canvas.getContext){
        var ctx = canvas.getContext('2d');

        ctx.fillStyle = 'red';
        ctx.font='16px serif';
        ctx.fillText('1倍',0,20);
        ctx.scale(2,2);
        ctx.fillText('2倍',20,20);
        ctx.scale(2,2);
        ctx.fillText('4倍',30,20);

        var ctx2 = canvas2.getContext('2d');
        ctx2.fillStyle = 'red';
        ctx2.font='16px serif';
        ctx2.fillText('0',50,20);
        ctx2.rotate(30*Math.PI/180);
        ctx2.fillText('30',50,20);
        ctx2.rotate(30*Math.PI/180);
        ctx2.fillText('60',50,20);

        var ctx3 = canvas3.getContext('2d');
        ctx3.fillStyle = 'red';
        ctx3.font='16px serif';
        ctx3.fillText('0,0',0,20);
        ctx3.translate(30,20);
        ctx3.fillText('30,20',0,20);
        ctx3.translate(30,20);
        ctx3.fillText('60,40',0,20);

        var ctx4 = canvas4.getContext('2d');
        ctx4.fillStyle = 'red';
        ctx4.font='16px serif';
        ctx4.fillText('0,0',0,20);
        ctx4.transform(1,0, -0.8 ,1,0,0);
        ctx4.fillText('30,20',50,20);
        ctx4.transform(1,0, -0.8 ,1,0,0);
        ctx4.fillText('100,20',100,20);
      }
    }
  </script>
</body>
</html>
ソースファイルのダウンロード(trans.zip)