画像を変形する
イメージ図のようにするために、画像を回転させて、縦方向に圧縮しましょう。
EaselJS には回転、拡大縮小、移動などを行列で行うクラス Matrix2D がある。
こちらのブログで、matrix を用いた回転や拡大縮小の例を分かりやすく解説している。
EaselJSのMatrix2Dクラスを使った変換行列の操作 | kudox.jp
この時点(EaselJS 0.5.0)では、Matrix2D のscale メソッドは、matrix にmatrix を乗算したものと違う挙動をしていた。
FN1305002 – EaselJSのMatrix2D.scale()メソッドを他の変換の後に呼出すと正しく伸縮されない – HTML5 : テクニカルノート
2013年5月15日付けEaselJS 0.6.1 以降は、Matrix2D の scale メソッドのバグは修正されている。
ボタンを押すと、だんだんと変形の度合いが強くなるようにした。
var rotation = (endRotation - startRotation) * ratio + startRotation; var scaleX = (endScaleX - startScaleX) * ratio + startScaleX; var scaleY = (endScaleY - startScaleY) * ratio + startScaleY; var matrix = new cj.Matrix2D(1,0,0,1,0,0); matrix.rotate(rotation * Math.PI/180); matrix.scale(scaleX, scaleY); matrix.decompose(container);
この部分で、単位行列 に、回転matrix と拡大縮小matrix をかけてできた行列をcontainer に適用している。
アニメーションする
アニメーションの際は、ゆっくり動き出して速く動いた後、またゆっくりになって止まるなど、スピードを調整したい。
あと、変形が終わった後、さらに移動させたりしたい。
CreateJS には、そのあたりを簡単に記述できるライブラリTweenJS があるので、それを使ってみよう。
TweenJS の使い方は、こちらのブログが分かりやすかった。
トゥイーンで簡単canvasアニメーション!TweenJSの使い方 | kudox.jp
TweenJS で、x やy , rotationなどはあつかいやすい。
けど、matrix に変換行列をかけていくのをやるにはどうしたらいいのかな。プラグインをつくって、そこで計算してターゲットのmatrixに変更を加える事にしよう。
TransformMatrixPlugin.js というのを作って、matrixに変更を加えて適用するようにした。
var tween = cj.Tween.get(imgLayers[i],{override:false}) .to({x:80, y: 80}, i * 10) .set({matEnabled:true}) .to({mat:{rotation:45,scaleX:1.0, scaleY:0.3}, x:160, y:280 - i * 10}, 500,cj.Ease.quadIn) .set({matEnabled:false}) .to({x:160, y: 280 - i * 35},500, cj.Ease.backOut);
ひとつめのtween部分、このうち、
.set({matEnabled:true}) .to({mat:{rotation:45,scaleX:1.0, scaleY:0.3}, x:160, y:280 - i * 10}, 500,cj.Ease.quadIn) .set({matEnabled:false})
部分が、TransformMatrixPlugin が関係している部分。
.to({mat:{rotation:45,scaleX:1.0, scaleY:0.3}, x:160, y:280 - i * 10}, 500,cj.Ease.quadIn)
のところで、matrixを使った変形を指定。
mat というプロパティをTransformMatrixPluginで設定した。
mat は、skewX, skewY, rotation, scaleX, scaleY をもち、値を設定する事が出来る。
そして、mat プロパティを使うときには
.set({matEnabled:true})
をその直前に、そして、
.set({matEnabled:false})
をmat プロパティを使った直後に書く。
TransformMatrixPlugin.js
/* * TransformMatrixPlugin * Visit http://createjs.com/ for documentation, updates and examples. * * Copyright (c) 2013 nackpan * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ // namespace: this.createjs = this.createjs||{}; (function() { /** * TransformMatrixPlugin.js * You can transform the target by tweening its matrix. * These transformation functions include skewing, rotation, and scaling. * *To use, install the plugin after TweenJS has loaded. * * <h4>Example</h4> * * createjs.Tween.get(target).to({x:100, y:40}).set({matEnabled:true}).to({mat:{skewX:20, rotation:20}).set({matEnabled:false}) ; * * You can transform the target's matrix by using the 'mat' property. * The 'mat' has properties: skewX, skewY, rotation, scallX and scallY; * You must insert '.set({matEnabled:true})' just before using 'mat' property. * And add '.set({matEnabled:false})' after using 'mat' property. * @class TransformMatrixPlugin * @constructor **/ var TransformMatrixPlugin = function() { throw("TransformMatrixPlugin cannot be instantiated."); }; // static interface: /** * @property priority * @static **/ TransformMatrixPlugin.priority = -10; /** * Installs this plugin for use with TweenJS, and registers for a list of properties that this plugin will operate * with. Call this once after TweenJS is loaded to enable this plugin. * @method install * @static **/ TransformMatrixPlugin.install = function() { // this registers this plugin to work with the "test" property. createjs.Tween.installPlugin(TransformMatrixPlugin, ["matEnabled","mat"]); }; /** * @method init * @static **/ TransformMatrixPlugin.init = function(tween, prop, value) { if(!value){ value = {rotation:0.0,scaleX:1.0, scaleY:1.0, skewX:0.0, skewY:0.0}; } return value; }; /** * @method init * @static **/ TransformMatrixPlugin.step = function(tween, prop, startValue, endValue, injectProps) { }; /** * @method tween * @static **/ TransformMatrixPlugin.tween = function(tween, prop, value, startValues, endValues, ratio, wait, end) { if (wait) return value; if(tween._target.matEnabled === void 0) return value; if(!tween._target.matEnabled) return value; var tx = tween._target.x; var ty = tween._target.y; var v0 = startValues.mat; var v1 = endValues.mat; var arr = ["rotation","scaleX","scaleY","skewX","skewY"]; for(var i = 0; i < arr.length; i++){ if(v0[arr[i]] === void 0){ if(arr[i] == "rotation"){ v0[arr[i]] = 0; }else{ v0[arr[i]] = 1; } } } for(i = 0; i < arr.length; i++){ if(v1[arr[i]] === void 0){ v1[arr[i]] = v0[arr[i]]; } } var skewX = (v1.skewX - v0.skewX) * ratio + v0.skewX ; var skewY = (v1.skewY - v0.skewY) * ratio + v0.skewY; var rot = (v1.rotation - v0.rotation) * ratio + v0.rotation; var scaleX = (v1.scaleX - v0.scaleX) * ratio + v0.scaleX ; var scaleY = (v1.scaleY - v0.scaleY) * ratio + v0.scaleY; var matrix = new createjs.Matrix2D(1,0,0,1,0,0); matrix.skew(skewX, skewY); matrix.rotate(rot * Math.PI/180); matrix.scale(scaleX, scaleY); matrix.translate(tx, ty); matrix.decompose(tween._target); return value; }; createjs.TransformMatrixPlugin = TransformMatrixPlugin; }());