サイトトップ

Director Flash 書籍 業務内容 プロフィール

HTML5テクニカルノート

EaselJSのMatrix2Dオブジェクトの変換行列を適用する

ID: FN1308001 Technique: HTML5 and JavaScript Library: EaselJS 0.7.0

*【0.7.0】EaselJS 0.7.0で新たに加わった項目。
Matrix2D.decompose()メソッド
文法 Matrix2Dオブジェクト.decompose(target)
概要

Matrix2Dオブジェクトの変換行列を、引数のオブジェクトに与える。DisplayObjectインスタンスのつぎのプロパティが変わる。

  • x, y
  • scaleX, scaleY
  • skewX, skewY
  • rotation
引数

target − Matrix2Dオブジェクトから変換のプロパティを与える対象のオブジェクト。引数を省くと戻り値となる新たなObjectインスタンスがつくられる。

戻り値 変換のプロパティを与えられた引数のオブジェクト。引数が省かれたときは、新たなObjectインスタンスにプロパティが納められる。
Matrix2D.transformPoint()メソッド【0.7.0】
文法 Matrix2Dオブジェクト.transformPoint(x, y, pt)
概要

参照するMatrix2Dオブジェクトの変換行列で引数のxy座標を変換し、それらの値をもったオブジェクトにして返す。

引数

x, y − 変換行列で変換するxy座標値。

pt − 変換した座標をxとyのプロパティに納めて返すPointまたはObjectインスタンス。引数を省くと戻り値となる新たなObjectインスタンスがつくられる。

戻り値 変換した座標値をxとyのプロパティにもつオブジェクト[*1]。第3引数が省かれたときは、新たなObjectインスタンスにxyプロパティが納められる。

[*1] 本稿改訂時の「EaselJS v0.7.0 API Documentation」のMatrix2D.transformPoint()メソッドの項における戻り値(「Returns」)の説明に誤りがあります。

Returns:
Point: This matrix. Useful for chaining method calls.

メソッドが返すのは、Matrix2Dオブジェクト("matrix")ではありません。前述のとおり「変換した座標値をxとyのプロパティにもつオブジェクト」です。データ型も正しくは「Point」にかぎらない「Object」でしょう(あるいは「Point | Object」)。


説明

Matrix2Dオブジェクトの変換行列は、DisplayObjectやPointのインスタンスに適用して座標変換が加えられます。また、変換した後のプロパティ値をObjectインスタンスに納め、他の座標変換に用いることもできます。

Matrix2Dオブジェクトの変換行列でDisplayObjectインスタンスを変形したいときは、Matrix2D.decompose()メソッドの引数にインスタンスを渡して呼出します。すると、変換行列から導かれる位置や伸縮、傾斜、回転などのプロパティがObjectインスタンスに与えられます。

Matrix2Dオブジェクト.decompose(DisplayObjectインスタンス)

Matrix2D.decompose()メソッドの引数は、DisplayObjectインスタンスにはかぎりません。また、引数を省くとプロパティが納められた新たなObjectインスタンスをつくって返します。そのプロパティ値を後で取出して、DisplayObjectインスタンスに加えることもできます。

Matrix2D.transformPoint()メソッドはEaselJS次期バージョン候補(0.7.0)に備わりました。参照するMatrix2Dオブジェクトの変換行列で、引数のxy座標値を変換し、変換後のxy座標値がプロパティに納められたオブジェクトを返します。

Matrix2Dオブジェクト.transformPoint(x座標, y座標, 格納オブジェクト)

変換されたxyプロパティを加えたいPointなどのオブジェクトは、第3引数として渡します。第3引数を省くと、xyプロパティを納めた新たなObjectインスタンスが返ります。


Matrix2D.decompose()メソッドの例からご紹介します。ステージに置いたインスタンスをクリックしたらMatrix2Dオブジェクトで回してみます。ただし、回転の軸は、マウスクリックした任意の座標とします(図001)。Matrix2Dオブジェクトの座標変換はつねに、そのオブジェクトが置かれた座標空間の原点を基準とすることに注意しなければなりません。この例では、つぎのように考えます。

  1. クリックされたステージ上のマウスポインタの座標をインスタンスの座標から差引く。
  2. インスタンスを親オブジェクトの原点で回す。
  3. 1.で差引いたマウス座標をインスタンスの座標に加えて戻す。

図001■インスタンスがクリックされた座標を中心に回る
図001

まず、インスタンスの座標からマウス座標を差引くと、インスタンスのクリックされた座標が親オブジェクトの原点と重なります。ですから、そこでインスタンスを回せば、回転の軸がクリックされた座標になります。そして、改めてマウス座標を加えることで、インスタンスの回転軸がクリック位置に戻るのです。

以下のコード001は、インスタンス(instance)をクリックするたびに、その座標を軸に30度(π/6ラジアン)回ります。DisplayObject.clickイベントのリスナー関数(transform())は、DisplayObject.getMatrix()メソッドでインスタンス(target)の変換行列が表されたMatrix2Dオブジェクトを取出します(第7行目)。

そのMatrix2Dオブジェクトの変換行列から、まずMatrix2D.translate()メソッドでマウス座標(mouseXとmouseY)を差引く移動が加えられます(第8行目)。これでインスタンスのクリックされた位置が親オブジェクトの原点と重なりますので、つぎにMatrix2D.rotate()メソッドによりインスタンスを30度(π/6ラジアン)回します(第9行目)。そして、改めてMatrix2D.translate()メソッドで変換行列にマウス座標を加えれば、インスタンスがクリックされた座標はもとの位置に戻ります(第10行目)。

以上3つの変換が加えられたMatrix2Dオブジェクトを、Matrix2D.decompose()メソッドでインスタンス(target)に適用すれば、クリックされた座標を軸にインスタンスが回ります(前掲図001)。

コード001■インスタンスをクリックした座標で回転する
  1. instance.addEventListener("click", transform);
  2. function transform(eventObject) {
  3.   var target = eventObject.target;
  4.   var mouseX = eventObject.stageX;
  5.   var mouseY = eventObject.stageY;
  6.   var matrix = target.getMatrix();
  7.   matrix.translate(-mouseX, -mouseY)
  8.   .rotate(Math.PI / 6)
  9.   .translate(mouseX, mouseY)
  10.   .decompose(target);
  11.   stage.update();
  12. }

新しいMatrix2D.transformPoint()メソッドを用いると、xy座標がMatrix2Dオブジェクトで変換できます。以下のコード002は、配列(points)に納めたPointオブジェクトの座標をMatrix2D.transformPoint()メソッドで回転します。これらの座標を直線で結べば、ワイヤーフレームの図形が回ります(図002)。

アニメーションにするため、Ticker.tickイベントにリスナー関数(rotate())を加えます(第3行目)。リスナー関数では、Matrix2Dオブジェクトは予め変数(matrix)にとっておき、Matrix2D.identity()メソッドにより初期化したうえで[*2]Matrix2D.rotate()メソッドで回します(第2および第6行目)[*3]。そして、for文で配列のPointオブジェクトすべてを順に取出し、em>Matrix2D.transformPoint()メソッドで変換します(第7〜10行目)。なお、取出したPointオブジェクトのxy座標を書替えるため、メソッドの第3引数にオブジェクトを渡しています。

図002■座標を直線で結ぶとワイヤーフレームの図形が回る
図002

コード002■配列に入れたPointオブジェクトをMatrix2D.transformPoint()メソッドで回す
  1. var angle = Math.PI / 12;
  2. var matrix = new createjs.Matrix2D();
  3. createjs.Ticker.addEventListener("tick", rotate);
  4. function rotate(eventObject) {
  5.   var count = points.length;
  6.   matrix.identity().rotate(angle);
  7.   for (var i = 0; i < count; i++) {
  8.     var point = points[i];
  9.     matrix.transformPoint(point.x, point.y, point);
  10.   }
  11. }

さらに、Matrix2D.transformPoint()メソッドの応用例として、3次元空間で星形のワイヤーフレームを回すコードがjsdo.itに掲げてあります。JavaScriptコードの中身については「遠近法が投影された座標を求める」をお読みください。


[*2] Matrix2D()コンストラクタで新たな配列を毎回つくるより、すでにあるMatrix2Dオブジェクトを初期化して使い回す方がガベージコレクションなどの負荷が減ります。

[*3] コード002では回転角(angle)は決まっているため、リスナー関数の中でMatrix2D.rotate()メソッドを毎回呼ぶのは無駄です。けれど、角度を動的に変えられるように、リスナー関数に含めました(jsdo.itのサンプルコード参照)。



作成者: 野中文雄
更新日: 2013年10月6日 EaselJS 0.7.0のリリースにともない、次期バージョン候補にもとづいていたMatrix2D.transformPoint()メソッドの説明を補正し、応用例のコードを追加。
作成日: 2013年8月10日


Copyright © 2001-2013 Fumio Nonaka.  All rights reserved.