画像をバラバラに分解してアニメーション


こんにちわ。
最近メモばかりでつまらないっと鮭さんに言われてついカッとなってちょっとプログラムやってみました。
こんな感じ
http://moeten.info/flex/20090419_shopPhotoBig/bin-release/shopeyecacth.html
以前書いた桜パーティクルと画像表示のまんまなのですが、せっかくなのでFlash10の機能の3D回転を追加してみました。
あと、複数画像の読み込みに便利なBulkLoaderがいい感じ。シンプルになっていいね。
読み込みたい画像やらファイルを一括で管理できて簡単に取り出せるのがグッド。
使い方はこんな感じ

private var loader : BulkLoader;
private function init():void{
    //マルチローダー
    loader = new BulkLoader( "main-site" );
    loader.add( "" + hts.lastResult.item[0].titleimage , { id : "myPhoto" } );
    loader.add( "" + hts.lastResult.item[0].image1     , { id : "myImage1" } );
    loader.add( "" + hts.lastResult.item[0].image2     , { id : "myImage2" } );
    loader.add( "" + hts.lastResult.item[0].image3     , { id : "myImage3" } );
    loader.addEventListener(BulkProgressEvent.COMPLETE , onAllItemsLoaded );
    loader.start();
}
//全てのローダー完了イベント
private function onAllItemsLoaded(e:Event):void{
    myPhoto.source  = loader.getBitmap("myPhoto");
    myImage1.source = loader.getBitmap("myImage1");
    myImage2.source = loader.getBitmap("myImage2");
    myImage3.source = loader.getBitmap("myImage3");
}

すべてのソースはこちら。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    backgroundAlpha="1" backgroundColor="0xffffff"
    backgroundGradientAlphas="[1.0,1.0]"
    backgroundGradientColors="[0xffffff,0xffffff]"
    verticalScrollPolicy="off" horizontalScrollPolicy="off"
     creationComplete="init()"
     width="480" height="300"
    >
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.events.EffectEvent;
import mx.effects.*;
import mx.effects.easing.*;
import br.com.stimuli.loading.BulkLoader;
import br.com.stimuli.loading.BulkProgressEvent;
private var loader : BulkLoader;
[Bindable]private var sid:int = 390;
//初期化関数
private function init():void{
    //画像リストを取得
    if(this.parameters.sid)sid = this.parameters.sid;
    hts.send();
}
//リスト取得完了イベント
private function onHtsResult( e:Event ):void{
    //マルチローダー
    loader = new BulkLoader( "main-site" );
    myTitle.text = "" + hts.lastResult.item[0].shopname;
    loader.add( "" + hts.lastResult.item[0].titleimage , { id : "myPhoto" } );
    loader.add( "" + hts.lastResult.item[0].image1     , { id : "myImage1" } );
    loader.add( "" + hts.lastResult.item[0].image2     , { id : "myImage2" } );
    loader.add( "" + hts.lastResult.item[0].image3     , { id : "myImage3" } );
    loader.addEventListener(BulkProgressEvent.COMPLETE , onAllItemsLoaded );
    loader.start();
    myLog.text =  hts.lastResult.item[0].shopname;
    myLog.text += hts.lastResult.item[0].titleimage
}
//全てのローダー完了イベント
private function onAllItemsLoaded(e:Event):void{
    pbar.visible = false;
    myPhoto.source  = loader.getBitmap("myPhoto");
    myImage1.source = loader.getBitmap("myImage1");
    myImage2.source = loader.getBitmap("myImage2");
    myImage3.source = loader.getBitmap("myImage3");
    //画像が完全に表示されるまで待つ
    myPhoto.addEventListener(FlexEvent.UPDATE_COMPLETE , loadImages );
}
//画像を細かく切ったりするエフェクト
private function loadImages(e:Event):void{
    myShow5.play();
    //画像を分割して配列に保存
    var i:int = 0;
    var j:int = 0;
    //区切る大きさ
    var w:int = 50;
    var h:int = 50;
    var duration:int = 700;
    var delay:int = 200;
    var ih:Number = myPhoto.height/h;
    var iw:Number = myPhoto.width/w;
    //画像を分割してエフェクト設定
    for (i = 0; i < ih ; i++ )
    {
        for (j = 0; j <  iw ; j++ )
        {
            //小さい画像作成
            var bd:BitmapData = new BitmapData( w , h );
            //ちょっとづつずらして描画
            var mat:Matrix = new Matrix();
            mat.translate( -w * j , -h * i );
            bd.draw( myPhoto , mat);
            //画像の作成
            var im:Image = new Image();
            im.alpha  = 0;
            im.width  = w;
            im.height = h;
            im.source = new Bitmap( bd );
            myImage.addChild( im );
            //エフェクト追加
            var m:Move = new Move();
            m.easingFunction = Cubic.easeOut;
            m.startDelay = delay * i + delay * j;
            m.duration   = duration;
            m.xFrom      = i * w - 80;
            m.yFrom      = 0 - 80;
            m.xTo        = j * w;
            m.yTo        = i * h;
            //エフェクトが終了したら桜パーティクルを作成
            m.addEventListener(EffectEvent.EFFECT_END,function(e:Event):void{
                var t:Move = e.target as Move;
                //桜パーティクルの作成
                makeParticle( t.xTo + w/2 , t.yTo + h/2 );
            });
            //Fade
            var f:Fade   = new Fade();
            f.startDelay = delay * i + delay * j;
            f.duration   = duration;
            f.alphaFrom  = 0;
            f.alphaTo    = 1;
            //Glow
            /*
            var g:Glow   = new Glow();
            g.color      = 0xffffff;
            g.blurXFrom  = 12;
            g.blurYFrom  = 12;
            g.blurXTo    = 0;
            g.blurYTo    = 0;
            g.alphaFrom  = 1;
            g.alphaTo    = 0;
            g.strength   = 3;
            g.duration   = duration;
            g.startDelay = delay * i + delay * j + 500;
            //Blur
            var b:Blur = new Blur();
            b.blurXFrom  = 16;
            b.blurXTo    = 0;
            b.blurYFrom  = 16;
            b.blurYTo    = 0;
            b.duration   = duration;
            */
            //エフェクトの実行
            var pa:Parallel = new Parallel();
            pa.addChild( m );
            pa.addChild( f );
            pa.play([im]);
        }
    }
    myShow.play([myImage1,myImage2,myImage3]);
    myShow4.play();
}
//桜パーティクル作成。クラス化したいねぇ
[Embed(source='sakura.png')]private var flower:Class
private var _vol:Number     = 3;
private var _drag:Number    = 0.9;
private var _shrink:Number  = 0.95;
private var _gravity:Number = 0.8;
private var _fade:Number    = 0.02;
private var _wind:Number    = 0.3;
private var xVelArr:Array   = new Array();
private var yVelArr:Array   = new Array();
private var rotArr:Array    = new Array();
private var cnt:int         = 0;
private function makeParticle(x:Number,y:Number):void{
    _gravity = -0.2;
    _wind    = -0.2;
    for (var i:uint = 0; i < 2; i++){
        var pt:Point = getNearPoint( new Point( x , y ) );
        var mc:Bitmap = new flower();
        mc.x    = pt.x;
        mc.y    = pt.y;
        mc.alpha = Math.random()*1;
        mc.name = "" + cnt;
        xVelArr[cnt] = getRandRange( -5, 5);
        yVelArr[cnt] = getRandRange( -5, 5);
        rotArr[cnt]  = getRandRange( -20, 20);
        mc.addEventListener(Event.ENTER_FRAME, function(e:Event):void{
            var m:Bitmap = e.target as Bitmap;
            m.filters = [gf2];
            if ( m.alpha > 0){
                var c:int     = int( m.name );
                m.x          += xVelArr[c] + _wind * 10;
                m.y          += yVelArr[c];
                xVelArr[c]   *= _drag;
                yVelArr[c]   *= _drag;
                m.scaleX     *= _shrink;
                m.scaleY     *= _shrink;
                yVelArr[cnt] += _gravity;
                m.alpha      -= _fade;
                m.rotation   += rotArr[c];
            }else{
                m.removeEventListener(Event.ENTER_FRAME, arguments.callee);
                myImage.removeChild(m);
                m = null;
            }
        });
    cnt ++;
    myImage.addChild( mc );
    }
}
private function getRandRange(min:Number, max:Number):Number{
    var randomNum:Number = (Math.random() * (max - min )) + min;
    return randomNum;
}
private function getNearPoint(pt1:Point):Point{
    var len:uint   = Math.round(Math.random() * 10);
    var angle:uint = Math.round(Math.random() * 2 * Math.PI);
    var pt2:Point  = Point.polar(len, angle);
    pt2.offset( pt1.x, pt1.y );
    return pt2;
}
private function onStart():void{
    makeParticle( myImage1.x ,myImage1.y );
    makeParticle( myImage2.x ,myImage2.y );
    makeParticle( myImage3.x ,myImage3.y );
}
private var isShow:Boolean =true;
private function onClick():void{
    if( isShow && !myHide6.isPlaying && !myShow6.isPlaying){
        myHide6.play([myImage1,myImage2,myImage3]);
        isShow = false;
    }else if( !isShow && !myHide6.isPlaying && !myShow6.isPlaying){
        myShow6.play([myImage1,myImage2,myImage3]);
        isShow = true;
    }
}
]]>
</mx:Script>
<!--############ HTTP ############-->
<mx:HTTPService id="hts" resultFormat="e4x" result="onHtsResult(event)"
    url="{'http://moeten.info/maidcafe/?m=api&amp;type=shopbasicpageimage&amp;sid='+sid}"/>
<!--############ フィルター ############-->
<mx:DropShadowFilter id="dsf" blurX="12" blurY="12" color="0xffccff" distance="0"/>
<mx:GlowFilter id="gf" blurX="4" blurY="4" color="0xffffff" strength="10" inner="true" />
<mx:GlowFilter id="gf2" blurX="4" blurY="4" color="0xffffff" strength="1" inner="true" />
<!--############ エフェクト ############-->
<mx:Parallel id="myShow4" target="{myTitle}">
    <mx:Move yTo="0" startDelay="4000"/>
</mx:Parallel>
<mx:Parallel id="myShow">
    <mx:AnimateProperty fromValue="200" toValue="0" property="rotationY" duration="1500" startDelay="4000" easingFunction="Back.easeOut"
        effectEnd="onStart()"/>
    <mx:Fade alphaFrom="0" alphaTo="1" duration="1000" startDelay="4000" effectEnd="onStart()"/>
</mx:Parallel>
<mx:Parallel id="myShow5" target="{myCanvas}">
    <mx:AnimateProperty fromValue="200" toValue="0" property="rotationX" duration="3000"/>
</mx:Parallel>
<mx:Parallel id="myShow6" targets="{[myImage1,myImage2,myImage3]}">
    <mx:Fade alphaFrom="0" alphaTo="1"/>
    <mx:Zoom zoomHeightFrom="0.5" zoomHeightTo="1" zoomWidthFrom="0.5" zoomWidthTo="1"/>
</mx:Parallel>
<mx:Parallel id="myHide6" targets="{[myImage1,myImage2,myImage3]}">
    <mx:Fade alphaFrom="1" alphaTo="0"/>
    <mx:Zoom zoomHeightFrom="1" zoomHeightTo="0.5" zoomWidthFrom="1" zoomWidthTo="0.5"/>
</mx:Parallel>
<!--############ コンポーネント ############-->
<mx:Image id="myPhoto" x="0" y="0" visible="false"/>
<mx:Canvas id="myCanvas" clipContent="false" width="480" height="300" x="100" y="100">
    <mx:Image id="myImage" width="489" height="300" x="-100" y="-100" click="onClick()"/>
</mx:Canvas>
<mx:Image id="myImage1" x="150" y="150" alpha="0" width="100" filters="{[gf,dsf]}" rotation="-30"/>
<mx:Image id="myImage2" x="260" y="90"  alpha="0" width="100" filters="{[gf,dsf]}" rotation="0"/>
<mx:Image id="myImage3" x="390" y="100"  alpha="0" width="100" filters="{[gf,dsf]}" rotation="30"/>
<mx:TextInput id="myTitle" alpha="1" x="0" y="-40"
    backgroundAlpha="0.6" color="0x8537a5" backgroundColor="0xffffff"
    fontSize="20" fontWeight="bold"
    borderThickness="0" borderStyle="solid"
    editable="false" width="100%"
    />
<mx:ProgressBar id="pbar" x="0" y="140" labelPlacement="center" indeterminate="true" themeColor="#ffccff"
    creationCompleteEffect="WipeRight" hideEffect="WipeRight"
    width="489"/>
<mx:TextArea id="myLog" visible="false"/>
</mx:Application>