情報学部 菅沼ホーム JavaScript 目次 基礎技術目次 索引

移動,回転,縮小・拡大

  1. アフィン変換

      オブジェクトを移動,回転,縮小・拡大させる最も簡単な方法は,「 2d コンテキストのプロパティとメソッド」における「回転,移動,拡大・縮小」内の translate メソッド,rotate メソッド,及び,scale メソッドを利用する方法です.この例は,これらのメソッドを利用して,回転,移動・縮小を行った例です.例えば回転の場合,一見,画像を時計方向に 20 度( -20 度)回転した結果のように見えますが,実際は,反時計方向に 20 度回転した座標軸から見た結果が表示されています.例えば,現在の座標系における点 p(0, 1) は,座標軸を反時計方向に 20 度回転させたとき,その座標系から点 p を見るとどのように見えるかを考えてみてください.点 p の座標は,(cos(20°), -sin(20°)) = (0.940, -0.342) のように見えるはずです.同様に,他の変換についても,座標軸に対する変換であることに注意してください.
    01	<!DOCTYPE HTML>
    02	<HTML>
    03	<HEAD>
    04		<TITLE>回転,拡大・縮小,移動</TITLE>
    05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    06		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    08		<SCRIPT TYPE="text/javascript">
    09			function draw() {
    10				let canvas    = document.getElementById('canvas_e');
    11				canvas.width  = 250;   // キャンバス要素の幅
    12				canvas.height = 130;   // キャンバス要素の高さ
    13				let ctx       = canvas.getContext('2d');
    14						// 回転する前の図形
    15				ctx.beginPath();
    16				ctx.strokeRect(40, 20, 100, 50);
    17				ctx.stroke();
    18						// 座標軸を反時計回りに20度回転
    19				ctx.beginPath();
    20				ctx.fillStyle = "rgb(0, 255, 0)";
    21				ctx.rotate(20*Math.PI/180);
    22				ctx.fillRect(40, 20, 100, 50);
    23						// 座標軸を移動して縮小
    24				ctx.beginPath();
    25				ctx.fillStyle = "rgb(255, 0, 0)";
    26				ctx.rotate(-20*Math.PI/180);
    27				ctx.translate(150, 0);
    28				ctx.scale(0.5, 0.5);
    29				ctx.fillRect(40, 20, 100, 50);
    30			}
    31		</SCRIPT>
    32	</HEAD>
    33	<BODY CLASS="white" STYLE="text-align: center" onLoad="draw()">
    34		<H1>回転,拡大・縮小,移動</H1>
    35		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="250" HEIGHT="130"></CANVAS>
    36	</BODY>
    37	</HTML>
    			
    21 行目

      座標軸を反時計回りに 20 度回転しています.

    26 行目

      座標軸を時計回りに 20 度回転しています(元に戻している).

    27 行目

      座標軸の原点を (150, 0) に変更しています.

    28 行目

      2 つの座標軸を 0.5 倍しています.

      transform メソッドは,右図に示すような変換行列(アフィン変換行列と呼ぶ)を利用して上で示したような変換を行っています.下に示すのは,移動(座標軸を x 軸方向に tx,y 軸方向に ty だけ移動),拡大・縮小(座標軸を x 軸方向に sx 倍,y 軸方向に sy 倍拡大),及び,回転(座標軸を q ラジアン回転)を単独に行う場合における行列の値を示しています.
      この例では,上と全く同じ変換を transform メソッドを利用して行っています.
    01	<!DOCTYPE HTML>
    02	<HTML>
    03	<HEAD>
    04		<TITLE>回転,拡大・縮小,移動(行列)</TITLE>
    05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    06		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    08		<SCRIPT TYPE="text/javascript">
    09			function draw() {
    10				let canvas    = document.getElementById('canvas_e');
    11				canvas.width  = 250;   // キャンバス要素の幅
    12				canvas.height = 130;   // キャンバス要素の高さ
    13				let ctx       = canvas.getContext('2d');
    14						// 回転する前の図形
    15				ctx.beginPath();
    16				ctx.strokeRect(40, 20, 100, 50);
    17				ctx.stroke();
    18						// 座標軸を反時計回りに20度回転
    19				ctx.beginPath();
    20				ctx.fillStyle = "rgb(0, 255, 0)";
    21				let ang = 20 * Math.PI / 180;
    22				let a   = Math.cos(ang);
    23				let b   = Math.sin(ang);
    24				let c   = -Math.sin(ang);
    25				let d   = Math.cos(ang);
    26				ctx.transform(a, b, c, d, 0, 0);
    27				ctx.fillRect(40, 20, 100, 50);
    28						// 座標軸を移動して縮小
    29				ctx.beginPath();
    30				ctx.fillStyle = "rgb(255, 0, 0)";
    31				ctx.transform(a, -b, -c, d, 0, 0);
    32				ctx.transform(0.5, 0, 0, 0.5, 150, 0);
    33				ctx.fillRect(40, 20, 100, 50);
    34			}
    35		</SCRIPT>
    36	</HEAD>
    37	<BODY CLASS="white" STYLE="text-align: center" onLoad="draw()">
    38		<H1>回転,拡大・縮小,移動(行列)</H1>
    39		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="250" HEIGHT="130"></CANVAS>
    40	</BODY>
    41	</HTML>
    			
    21 行目~ 26 行目

      座標軸を反時計回りに 20 度回転しています.

    31 行目

      座標軸を時計回りに 20 度回転しています(元に戻している).

    32 行目

      座標軸の原点を (150, 0) に変更し,2 つの座標軸を 0.5 倍しています.

  2. もう一つの例

      この例では,画面上でマウスをクリックすると,拡大及び移動を行い,再びクリックすると元に戻ります.
    01	<!DOCTYPE HTML>
    02	<HTML>
    03	<HEAD>
    04		<TITLE>拡大と移動(行列)</TITLE>
    05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    06		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    08		<SCRIPT TYPE="text/javascript">
    09			canvas = null;
    10			ctx    = null;
    11			sw     = 0;
    12	
    13			function draw() {
    14				canvas        = document.getElementById('canvas_e');
    15				canvas.width  = 250;   // キャンバス要素の幅
    16				canvas.height = 130;   // キャンバス要素の高さ
    17				ctx           = canvas.getContext('2d');
    18				canvas.addEventListener("click", Click, false);   // クリックイベント
    19						// 元のの図形
    20				ctx.beginPath();
    21				ctx.strokeRect(20, 20, 100, 50);
    22				ctx.stroke();
    23			}
    24						// マウスのクリック
    25			function Click(event)
    26			{
    27				ctx.clearRect(0, 0, canvas.width, canvas.height);
    28				if (sw == 0 ) {
    29					ctx.beginPath();
    30					ctx.fillStyle = "rgb(255, 0, 0)";
    31					ctx.transform(1.5, 0, 0, 1.5, 50, 0);
    32					ctx.fillRect(20, 20, 100, 50);
    33					sw = 1;
    34				}
    35				else {
    36					ctx.setTransform(1, 0, 0, 1, 0, 0);
    37					ctx.beginPath();
    38					ctx.strokeRect(20, 20, 100, 50);
    39					ctx.stroke();
    40					sw = 0;
    41				}
    42			}
    43		</SCRIPT>
    44	</HEAD>
    45	<BODY CLASS="white" STYLE="text-align: center" onLoad="draw()">
    46		<H1>拡大と移動(行列)</H1>
    47		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="250" HEIGHT="130"></CANVAS>
    48	</BODY>
    49	</HTML>
    			
    28 行目~ 34 行目

      初期状態において,マウスでクリックされたときの処理です.31 行目において,座標軸の原点を (50, 0) に変更し,2 つの座標軸を 1.5 倍しています.

    35 行目~ 41 行目

      拡大・移動された状態において,マウスでクリックされたときの処理です.36 行目において,座標軸を元に戻しています.

情報学部 菅沼ホーム JavaScript 目次 基礎技術目次 索引