グラフィックスの変形
●scale()、rotate()、translate() ●transform()、setTransform()
scale() で拡大、rotate() で回転、translate() で移動をします。
テキストで試してみました。グリッドは20pxです。
function Draw1() {
var ctx1 = document.getElementById('canvas1').getContext('2d');
/*テキストのスタイルを指定*/
ctx1.font= 'bold 15px sans-serif';
ctx1.fillStyle = '#6DD900';
/*テキストをノーマル状態で描画*/
ctx1.fillText('テキスト=ノーマル',30,30);
/*拡大*/
ctx1.scale(2,2);
ctx1.fillText('テキスト=拡大',30,30);
/*回転*/
var angle = 20*Math.PI/180;
ctx1.rotate(angle);
ctx1.fillText('テキスト=回転',30,30);
/*移動*/
ctx1.translate(140,0);
ctx1.fillText('テキスト=移動',30,30);
}
上記では、1度指定した拡大・回転が、ずっと影響しているのがわかります。
サンプル1と同じように拡大・回転・移動を連続して指定しますが、
今度は1回の変形ごとにノーマル状態に戻してからやってみます。
function Draw2() {
var ctx2 = document.getElementById('canvas2').getContext('2d');
/*テキストのスタイルを指定*/
ctx2.font= 'bold 15px sans-serif';
ctx2.fillStyle = '#00BFFF';
/*テキストをノーマル状態で描画*/
ctx2.fillText('テキスト=ノーマル',30,30);
/*拡大*/
ctx2.scale(2,2);
ctx2.fillText('テキスト=拡大',30,30);
ctx2.scale(1/2,1/2);/*拡大を元に戻しています*/
/*回転*/
var angle = 20*Math.PI/180;
ctx2.rotate(angle);
ctx2.fillText('テキスト=回転',30,30);
ctx2.rotate(-angle);/*回転を元に戻しています*/
/*移動*/
ctx2.translate(140,0);
ctx2.fillText('テキスト=移動',30,30);
ctx2.translate(-140,0);/*移動も元に戻しています*/
/*テキストを位置を変えて再びノーマルで描画*/
ctx2.fillText('テキスト=ノーマル再び',30,90);
}
1回ずつ変形を初期化(元に戻す)してから描画すると「サンプル1」との見た目の違いが一目瞭然です。
これで「サンプル1」で、1回の変形がその後もずっと影響しているのがわかります。
transform(m11, m12, m21, m22, dx, dy) で変形を指定する。
引数は左から「水平スケール, 垂直傾斜, 水平傾斜, 垂直スケール, 水平移動, 垂直移動」
変形無しのノーマル状態なら「transform(1, 0, 0, 1, 0, 0) 」
transform() でテキストの鏡像が映り込んでいるような描画をしてみます。
垂直スケールにマイナスの値を指定する事で鏡像にしています。
function Draw3() {
var ctx3 = document.getElementById('canvas3').getContext('2d');
/*テキストのスタイルを指定*/
ctx3.font= 'bold 60px Century Gothic';
ctx3.textAlign = 'center';
ctx3.fillStyle = '#FF71D6';
/*テキストをノーマル状態で描画*/
ctx3.fillText('TRANSFORM',300,80);
/*テキストを半透明に*/
ctx3.globalAlpha =0.3;
/*テキストを反転させて描画*/
ctx3.transform(1,0,0,-1,0,160);
ctx3.fillText('TRANSFORM',300,80);
}
transform() は、サンプル1の拡大,回転,移動と同様、指定をその後も引きずります。
setTransform() は、いったん初期化してから()内の引数を使って transform() を呼び出します。
下のサンプルでは、transform() を2回指定しています(12行目と15行目)。
2回目の transform() は、1回目を引きずっているのがわかります。
そのあと setTransform() を色をブルーにしてから使っています(20行目)。
それまでの transform() による変形を初期化して、引数の内容どおりに変形していることがわかります。
function Draw4() {
var ctx4 = document.getElementById('canvas4').getContext('2d');
/*テキストのスタイルを指定*/
ctx4.font= 'bold 60px Century Gothic';
ctx4.textAlign = 'center';
ctx4.fillStyle = '#FF71D6';
/*テキストをノーマル状態で描画*/
ctx4.fillText('TRANSFORM',300,100);
/*テキストを半透明に*/
ctx4.globalAlpha =0.3;
/*テキストを「transform」で反転させて縦に拡大して描画*/
ctx4.transform(1,0,0,-2,0,300);
ctx4.fillText('TRANSFORM',300,100);
/*テキストを「transform」で反転させて等倍に*/
ctx4.transform(1,0,0,-1,0,200);
ctx4.fillText('TRANSFORM',300,100);
/*テキストの色を変えて*/
ctx4.fillStyle = '#00BFFF';
/*テキストを「setTransform」で反転させて等倍に描画*/
ctx4.setTransform(1,0,0,-1,0,200);
ctx4.fillText('TRANSFORM',300,100);
}
2回目の transform()(15行目)では、垂直スケールを「-1」にしていますが、
1回目(12行目)の「-2」に対して行っているため、縦に2倍のまま鏡像の鏡像すなわち実像(正体)になっています。
setTransform()(20行目)で、すべてを忘れて、引数どおりの変形をしています。