CreateJSを使ってみる – 読み込んだ画像をアニメーションさせながら変形

イメージ図。
image_transform

前回(CreateJSを使ってみる – 画像の読み込み)は、画像を読み込むところまでやった。

画像を変形する

イメージ図のようにするために、画像を回転させて、縦方向に圧縮しましょう。

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 メソッドのバグは修正されている。

実例。matrix による画像の変形。
ボタンを押すと、だんだんと変形の度合いが強くなるようにした。

        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;
}());

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください