flex flash 顯示效果


1.使用自帶效果

在Flex裏面不像在Flash裏面隨意製作動畫了,Flex更趨向於應用程序,而不是動畫製作了,所以沒有了時間軸的概念。在Flex中使用動畫效果,可以用Flex自帶的Effect,或者自已定製Effect,因爲很多人都想借Flash裏面的一樣操作Flex,比如在Flash裏面做一個動態按鈕很容易,當鼠標移動到上面時,會有很多發光的點跑出來(熒火蟲效果),這種效果在Flash十分容易實現,但在Flex裏面要實現這種效果就不是那麼簡單的了,下面說說在Flex裏的的動務效果的使用與自定義製作。

首先介紹一下Flex裏面的自帶的效果有以下幾種:
  Blur                            模糊效果
  Move                          移動效果
  Fade                          淡入淡出效果            
  Glow                          發光效果
  Resize                       調整大小效果
  Rotate                       旋轉效果
  Zoom                         縮放效果
  WipeLeft                    用遮罩實現畫面收放效果,下同,分別爲不同方向
  WipeRight
  WipeUp
  WipeDown

不同的效果所需要設置的屬性也不一樣,比如Blur效果需要設置它的X與Y軸的模糊像素
<mx:Blur id="blur" blurXFrom="0" blurXTo="10" />
而Move效果需要設置移動的位置信息
<mx:Move id="moveEffect" xFrom="-100" />
其它設置可以參考Flex語言參考

下面說說如何使用這些效果。要運行這些效果有兩種方法:一種是調用該效果的play()方法,另外一種是使用觸發器來觸發效果。
(1)使用play()方法:

以下代碼:




Flex代碼
<?xml version="1.0" encoding="utf-8"?>  
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">  
    <mx:Script>  
        <![CDATA[  
            private function onClick(event:Event):void {  
                be.target = event.currentTarget;  
                be.play( );  
            }  
        ]]>  
    </mx:Script>  
     
    <mx:Blur id="be" blurXTo="50" blurYTo="50" duration="1000" />  
 
    <mx:Panel id="p" width="200" height="180" click="onClick(event)" />  
</mx:Application> 
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
     <mx:Script>
         <![CDATA[
             private function onClick(event:Event):void {
                 be.target = event.currentTarget;
                 be.play( );
             }
         ]]>
     </mx:Script>
   
     <mx:Blur id="be" blurXTo="50" blurYTo="50" duration="1000" />

     <mx:Panel id="p" width="200" height="180" click="onClick(event)" />
</mx:Application>

在代碼中看到,要使用效果,先定好一個效果,如上面的<mx:Blur ...>該標籤就是模糊效果的MXML標籤,定好效果後在Panel的點擊事件裏再對該效果進行一些設置,如be.target = event.currentTarget 設置該效果將要應用到的目標組件(Component),之後再調用play()方法後,該效果就會應用在Panel上面播放!

(2)使用觸發器播放效果:
使用觸發器播放效果的話,可以不用寫ActionScript代碼,直接在組件的效果觸發器上指明使用哪個效果就可以了,比較簡單明瞭,但就不能進行更多的屬性定製,而用AS控制播放的話,可以對效果進行很多的設置再相應根據情況播放,先看看觸發器播放的代碼:



Flex代碼
<?xml version="1.0" encoding="utf-8"?>  
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">  
     
    <mx:Blur id="be" blurXTo="50" blurYTo="50" duration="2000" />  
 
    <mx:Panel id="p" width="200" height="180" creationCompleteEffect="{be}" />  
</mx:Application> 
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  
    <mx:Blur id="be" blurXTo="50" blurYTo="50" duration="2000" />

    <mx:Panel id="p" width="200" height="180" creationCompleteEffect="{be}" />
</mx:Application>



看以上代碼,先寫好了Blur的效果並設置好屬性後,duration="2000"這個是播放的時間以毫秒爲單位。
在Panel標籤裏有這樣一句:creationCompleteEffect="{be}" 這個就是觸發器,是該Panel組件的效果觸發器,當Panel組件加載完成時,會由系統自動調用該效果觸發器,觸發器裏面指了觸發 be 這個Blur效果
在Flex裏面還有很多觸發器如:
  addedEffect                                       被添加進容器時觸發效果
  removedEffect                                   被從容器中移除時觸發效果
  creationCompleteEffect                     被創建成功時觸發效果
  focusInEffect                                     獲得焦點時觸發
  focusOutEffect                                   失去焦點時觸發
  hideEffect                                          被隱藏時(visible=false)觸發
  showEffect                                        被顯示時(visible=true)觸發
  rollOverEffect                                     鼠標經過時觸發
  rollOutEffect                                       鼠標離開時觸發
  mouseDownEffect                              鼠標按下時觸發
  mouseUpEffect                                   鼠標鬆開時觸發
  moveEffect                                         被移動時觸發
  resizeEffect                                       被重整大小時觸發

注意:這些都是效果觸發器,不要與事件觸發器混亂了。事件觸發器是rollOver,事件觸發器與效果觸發器差不多,事件觸發器是當用戶執行相就操作時觸發事件,將會調用自定的事件觸發處理函數,而效果觸發器是執行相應操作時被觸發並由系統自動調用所定的效果的play()方法。

現在說說效果的一些其它屬性:
每個效果都有reverse( );方法,該方法是反向播放,原本由小到大的變化,而調用reverse( );後再運行play()的話,效果將會從大到小進行播放。
但要注意的一點是,reverse( );不會自動播放,即是單單調用reverse( );的話,效果並不會播放,他只會記錄該效果爲倒轉,而要再調用play()後倒轉效果纔會開始播放。而調用pause( )與resume( )就是暫停與繼續播放效果

startDelay這個屬性是設置效果的播放延時,以毫秒爲單位,即要等待多少毫秒後效果纔開始播放,如:
<mx:Blur id="be" blurXTo="50" startDelay="3000" />
該模糊效果將會在調用play()之後3秒纔開始播放

repeatCount這個屬性是設置效果的重複次數,默認爲1,設置爲0的話就是不停循環播放
<mx:Blur id="be" blurXTo="50" startDelay="3000" repeatCount="5" />

每個效果都有兩個事件:effectStart 與 effectEnd
你可以在該效果事件的處理函數裏面對效果作相應的操作,如:



Flex代碼
<?xml version="1.0" encoding="utf-8"?>  
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">  
    <mx:Script>  
        <![CDATA[  
            import mx.events.EffectEvent;  
            public function onEffEnd(e:EffectEvent):void{  
                e.effectInstance.reverse();  
                e.effectInstance.play();  
            }  
        ]]>  
    </mx:Script>  
    <mx:Blur id="be" blurXTo="50" blurYTo="50" duration="2000" />  
 
    <mx:Panel id="p" width="200" height="180" creationCompleteEffect="{be}" effectEnd="onEffEnd(event)" />  
</mx:Application> 
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script>
        <![CDATA[
            import mx.events.EffectEvent;
            public function onEffEnd(e:EffectEvent):void{
                e.effectInstance.reverse();
                e.effectInstance.play();
            }
        ]]>
    </mx:Script>
    <mx:Blur id="be" blurXTo="50" blurYTo="50" duration="2000" />

    <mx:Panel id="p" width="200" height="180" creationCompleteEffect="{be}" effectEnd="onEffEnd(event)" />
</mx:Application>


當效果播放完時,系統將會自動觸發effectEnd事件,在處理函數裏面,將該效果Instance即現時播放的效果實例進行倒轉並播放,當播放完,又會觸發effectEnd事伯,這樣一直循環!

現在再來說說效果的組合:
通常如果你覺得只應用一個效果很單調的話,可以進行效果組合應用,即多個效果同時播放或者順序播放,
如,當加載頁面時,你想Panel先模糊到一定程度,再將Panel移動到某個位置,再把Panel還原成原來的清淅度(即消退模糊)。這樣分析一下,一共用了三個效果,一,先應用Blur(由清至模)效果,當Blur完成時,再應用Move效果,當Move完成時,再應用另外一個Blur(由模至清)效果。這樣三個效果組合就是按順序組合,先後運行。



看看代碼:



Flex代碼
<?xml version="1.0" encoding="utf-8"?>  
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">  
     
    <mx:Sequence id="sequenceEffect">  
        <mx:Blur id="beOut" blurXTo="50" blurYTo="50" duration="500" />  
        <mx:Move id="mv" xTo="200" yTo="150" duration="500" />  
        <mx:Blur id="beIn" blurXFrom="50" blurYFrom="50" blurXTo="0" blurYTo="0" duration="500" />  
    </mx:Sequence>  
     
    <mx:Panel id="p" width="200" height="180" mouseDownEffect="sequenceEffect"  />  
</mx:Application> 
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  
    <mx:Sequence id="sequenceEffect">
        <mx:Blur id="beOut" blurXTo="50" blurYTo="50" duration="500" />
        <mx:Move id="mv" xTo="200" yTo="150" duration="500" />
        <mx:Blur id="beIn" blurXFrom="50" blurYFrom="50" blurXTo="0" blurYTo="0" duration="500" />
    </mx:Sequence>
  
    <mx:Panel id="p" width="200" height="180" mouseDownEffect="sequenceEffect"  />
</mx:Application>


看以上代碼,<mx:Sequence id="sequenceEffect">標籤就是順序組合效果標籤,當應用sequenceEffect效果的時候,它會按順序播放該標籤裏面的三個子效果。

另外的就是同時播放了,



Flex代碼
<mx:Parallel id="parallelEffect">  
          <mx:Blur id="beOut" blurXTo="50" blurYTo="50" duration="500" />  
      <mx:Move id="mv" xTo="200" yTo="150" duration="500" />  
</mx:Parallel> 
<mx:Parallel id="parallelEffect">
          <mx:Blur id="beOut" blurXTo="50" blurYTo="50" duration="500" />
      <mx:Move id="mv" xTo="200" yTo="150" duration="500" />
</mx:Parallel>


這個標籤就是同時播放的效果標籤,放在它裏面的子效果都會同時播放,即一邊模糊一邊移動。這個都可以自由組合,<mx:Parallel>與<mx:Sequence>標籤都可以自由組合,例如先按順序先播放模糊,再同時播放移動與隱藏等。這裏就不多說了。

使用Flex自帶的效果基本用法就這些,下篇文章將討論自定義效果的製作,下篇將會詳細說說這篇文章上面說到的 effectInstance 即實例與工廠的概念。




2.自己製作Flex動畫



上面講到了使用Flex系統裏面自帶的一些動來效果的使用,但很多開發者都並不滿足Flex裏提供的簡單的漸變大小,透明,移動,遮罩等的效果,如果是Flash的開發者的話,更不用說了,在Flash,多數人都是隨意的製作一些動畫效果等,而且形態多變。但是不是Flex裏就不能實現呢?肯定不是,在Flex裏也可以自定義動畫效果,只不過就是沒有Flash裏面那麼簡單隨意了。不過熟悉了之後,也會覺得在Flex裏製作動畫也不是什麼難事,不多說了,轉入正題!

在這裏我先介紹一下Flex裏面的動畫效果機制,在Flex裏面要使用動畫效果的話,先要創建一個效果標籤,之後在組件裏(如TextInput)寫上效果觸發器,但可能會有人問,如果程序裏我就只定義一個移動效果
<mx:Move>,之後我程序裏面有5個組件,每個組件的動畫效果都指向這個Move效果,那麼它是不是組件一運行了效果後,組件二再觸發效果,是不是組件一的效果會消失纔會到組件二里播放?其它不是,雖然我們只定義了一個Move,但我們定義的只是Move效果的工廠,這裏就用到了設計模式中的“工廠方法”模式,其實5個組件都可以同時運行效果,而5個效果都是不同的一個實例,彼此獨立。所謂工廠方法模式,就好比是一家衣服制造工廠,A走進這家工廠說要一件衣服,工廠就製作一件合適A的Size的衣服,B進去,就會生產合適B的衣服,但A與B的衣服都是一樣的。就好等於面向對象中的類與對象的關係一樣。(我可能說多了-_-)
效果運行的時候,其實運行的不是Move這個對象,而是MoveInstance這個對象,Move只是工廠,既然一個動畫效果就主要分這兩大部份,我們就先建造一個工廠吧!

在Flex裏面所有的效果的工廠都是繼承自 mx.effects.Effect 這個類,我們也不能搞特殊,我們自定義的效果也要繼承那個類,先看以下整個工廠類的代碼:




Flex代碼
package com.jiangzone.flex.effects {  
     import mx.effects.Effect;  
     import mx.effects.IEffectInstance;  
      
     public class MyEffect extends Effect {  
         private var _color:Number = 0xFF0000;  
                  
                 public function set color(value:Number):void {  
                          _color = value;  
                 }  
   
         public function MyEffect(newTarget:Object = null) {  
             super(newTarget);  
             instanceClass = MyEffectInstance;  
         }  
          
         override public function getAffectedProperties( ):Array {  
             return [];  
         }  
          
         override protected function initInstance(instance:IEffectInstance):void {  
             super.initInstance(instance);  
                         MyEffectInstance(instance).color = _color;  
         }  
     }  

package com.jiangzone.flex.effects {
     import mx.effects.Effect;
     import mx.effects.IEffectInstance;
   
     public class MyEffect extends Effect {
         private var _color:Number = 0xFF0000;
               
                 public function set color(value:Number):void {
                          _color = value;
                 }

         public function MyEffect(newTarget:Object = null) {
             super(newTarget);
             instanceClass = MyEffectInstance;
         }
       
         override public function getAffectedProperties( ):Array {
             return [];
         }
       
         override protected function initInstance(instance:IEffectInstance):void {
             super.initInstance(instance);
                         MyEffectInstance(instance).color = _color;
         }
     }
}


大家看看上面的代碼,其中先看構造函數,構造函數要接收一個默認爲空的Object對象
public function MyEffect(newTarget:Object = null)
之後在該構造函數裏面調用父類的構造函數,並且將instanceClass這個屬性設置爲你的該效果的實例類,因爲這個類是工廠類,所以要知道你這個工廠生產什麼產品,即上面說的“衣服”,所以這裏我們將其命名爲MyEffectInstance,注意:在Flex中的所有效果實例類都是在工廠類後面加Instance,也不是一定,只是規範而已。還有注意,下面一會定義的實例類的類名一定要跟這裏的一致。
大家還會看到,上面的代碼中,複寫(override)了二個方法:getAffectedProperties( )與initInstance(instance:IEffectInstance)
這兩個方法都是要複寫的,先說說getAffectedProperties( )這個方法,這個方法是獲取被改變的屬性值,怎麼說呢,比如說,你做的動畫效果如果要用到組件對象的一些屬性的話,就要返回這些屬性的名字,如:你的效果是對組件做旋轉的話,則:



Flex代碼
override public function getAffectedProperties( ):Array {  
    return ["rotation"];  

override public function getAffectedProperties( ):Array {
    return ["rotation"];
}


反正你做的效果需要對組件修改什麼屬性的話,都在這個方法裏返回名字,修改多個屬性的話就往數組裏加就是了。
後面就是這個方法了initInstance,該方法接收一個instance:EffectInstance參數,也就是效果實例類啦,因爲每個效果實例類都要繼承EffectInstance類,所以這個方法裏的參數寫的是父類,在裏面要做其它的話,需要將 instance 轉換爲你相應的效果類。在這個方法裏面,也是要調用父類的同名方法:super.initInstance(instance);
基本上,一個工廠類就寫好了,但這樣只是最簡單的寫法,試想想,每個人穿衣服的Size不同,喜歡的顏色也不同,所以,是不是可以由用戶來定義他們想要的效果的顏色等屬性呢?當然,你對衣服有什麼要求,都是向工廠提出的,沒有人會對衣服說吧?所以,這些可設置的屬性也是定義在工廠類裏面,所以下面,我們爲該衣服可定製顏色爲例,在工廠類裏面加入如下代碼:



Flex代碼
private var _color:Number = 0xFF0000;  
public function set color(value:Number):void {  
        _color = value;  

private var _color:Number = 0xFF0000;
public function set color(value:Number):void {
        _color = value;
}


你想運行時的效果可以設置不同的顏色的話,就可以直接設置MyEffect的color屬性,之後將這個屬性傳給效果實例類:



Java代碼
override protected function initInstance(instance:EffectInstance):void {  
    super.initInstance(instance);  
        MyEffectInstance(instance).color = _color;  

override protected function initInstance(instance:EffectInstance):void {
    super.initInstance(instance);
        MyEffectInstance(instance).color = _color;
}


這些對效果實例類的設置,都是要定在initInstance方法裏了,你想對運行時的效果設置什麼屬性的話,都要先告訴工廠類,之後工廠類在這個方法裏面轉嫁給實例類,這樣,同一個效果,可以運行不同的顏色。但前提是你後面要寫的實例類要有color這個屬性。
現在已做好了工廠類了,下面要做效果實例類了,先貼出完整代碼:




Flex代碼
package com.jiangzone.flex.effects {  
     import mx.effects.EffectInstance;  
     import flash.display.Shape;  
     import flash.events.Event;  
      
     public class MyEffectInstance extends EffectInstance {  
                  
         private var _color:Number;  
         private var shape:Shape;  
          
         public function set color(value:Number):void {  
             _color = value;  
         }  
          
         public function MyEffectInstance(newTarget:Object) {  
             super(newTarget);  
         }  
          
         override public function play( ):void {  
             super.play( );  
             drawShape();  
         }  
          
         private function drawShape():void{  
             shape = new Shape();  
             shape.graphics.beginFill(_color);  
             shape.graphics.drawRect(target.width * -0.5,target.height * -0.5,target.width,target.height);  
             shape.graphics.endFill();  
             shape.x = target.x + target.width * 0.5;  
             shape.y = target.y + target.height * 0.5;  
             target.parent.rawChildren.addChild(shape);  
             target.addEventListener(Event.ENTER_FRAME,onEnterFrame);  
         }  
          
         private function onEnterFrame(e:Event):void{  
             shape.scaleX += 0.1;  
             shape.scaleY += 0.1;  
             shape.alpha -= 0.05;  
             if(shape.alpha <= 0){  
                 target.parent.rawChildren.removeChild(shape);  
                 target.removeEventListener(Event.ENTER_FRAME,onEnterFrame);  
             }  
         }  
     }  

package com.jiangzone.flex.effects {
     import mx.effects.EffectInstance;
     import flash.display.Shape;
     import flash.events.Event;
   
     public class MyEffectInstance extends EffectInstance {
               
         private var _color:Number;
         private var shape:Shape;
       
         public function set color(value:Number):void {
             _color = value;
         }
       
         public function MyEffectInstance(newTarget:Object) {
             super(newTarget);
         }
       
         override public function play( ):void {
             super.play( );
             drawShape();
         }
       
         private function drawShape():void{
             shape = new Shape();
             shape.graphics.beginFill(_color);
             shape.graphics.drawRect(target.width * -0.5,target.height * -0.5,target.width,target.height);
             shape.graphics.endFill();
             shape.x = target.x + target.width * 0.5;
             shape.y = target.y + target.height * 0.5;
             target.parent.rawChildren.addChild(shape);
             target.addEventListener(Event.ENTER_FRAME,onEnterFrame);
         }
       
         private function onEnterFrame(e:Event):void{
             shape.scaleX += 0.1;
             shape.scaleY += 0.1;
             shape.alpha -= 0.05;
             if(shape.alpha <= 0){
                 target.parent.rawChildren.removeChild(shape);
                 target.removeEventListener(Event.ENTER_FRAME,onEnterFrame);
             }
         }
     }
}

我們看到,每一個動畫效果實例類,都要繼承自EffectInstance這個類,構造函數也是需要接收一個Object,這個Object其實就是你要應用到的組件對象,這個會是系統自動傳遞的,接收了Object後還要用該Object 調用父類的構造函數:super(newTarget);
之後還有一件必做的事,就是重寫play()這個方法:override public function play( ):void
是不是對play()很熟悉?因爲第一篇文章中,就用到這個方法來發動效果的播放的,所以,你需要做的動畫編程都是在這個方法裏。但還是要先調用父類的同名方法,super.play();之後的,就是你想怎麼畫就怎麼畫啦。我將畫一個與要應用效果的組件一樣大小的矩型,之後該矩形會放大並透明,效果都寫在drawShape()方法裏了。看到這個方法裏面的代碼,是不是跟Flash裏的一樣了?
這裏再貼上MXML代碼:




Flex代碼
<?xml version="1.0" encoding="utf-8"?>  
<mx:Application layout="absolute" xmlns:mx="http://www.adobe.com/2006/mxml" 
                                                         xmlns:pf="com.jiangzone.flex.effects.*">  
         <pf:MyEffect id="myEffect" color="0xFFFFFF" />  
         <mx:VBox x="100" y="43">  
                 <mx:TextInput focusInEffect="{myEffect}" />  
                 <mx:TextInput focusInEffect="{myEffect}" />  
                 <mx:TextInput focusInEffect="{myEffect}" />  
                 <mx:TextInput focusInEffect="{myEffect}" />  
         </mx:VBox>  
</mx:Application> 
<?xml version="1.0" encoding="utf-8"?>
<mx:Application layout="absolute" xmlns:mx="http://www.adobe.com/2006/mxml"
                                                         xmlns:pf="com.jiangzone.flex.effects.*">
         <pf:MyEffect id="myEffect" color="0xFFFFFF" />
         <mx:VBox x="100" y="43">
                 <mx:TextInput focusInEffect="{myEffect}" />
                 <mx:TextInput focusInEffect="{myEffect}" />
                 <mx:TextInput focusInEffect="{myEffect}" />
                 <mx:TextInput focusInEffect="{myEffect}" />
         </mx:VBox>
</mx:Application>

在這裏,我用了ENTER_FRAME的寫法,但是如果不用ENTER_FRAME方式製作動畫的話,還有另外一種方法的,那就是Tween了,Tween是以“時間”爲準,而ENTER_FRAME是以“幀”爲準,其實到這裏,一個基本的Flex自定義動畫效果就完成了,但擴展一下的,還可以用Tween來實現,而且建議用Tween來寫動畫效果,易控制,清淅一點。用Tween實現的話,效果與寫法都是差不多的,要用Tween就要將效果實例類繼承自TweenEffectInstance這個類,並重寫它的onTweenUpdate( )方法與onTweenEnd( )方法,這種Tween效果的寫法,將會比ENTER_FRAME的寫法方便,因爲它根據的是時間,所以,你可以指定效果播放的時間,並且當播放完畢會自動調用onTweenEnd()方法,你可以在該方法裏寫一些處理操作,如釋放資源等等
由於編幅關係,就不在這裏詳細介紹TweenEffectInstence了,就簡單貼出該類的寫法與註釋吧:




Flex代碼
package com.jiangzone.flex.effects {  
     import mx.effects.effectClasses.TweenEffectInstance;  
     import flash.display.Shape;  
     import flash.events.Event;  
     import mx.effects.Tween;  
      
     public class MyEffectInstance extends TweenEffectInstance {  
                  
         private var _color:Number;  
         private var shape:Shape;  
          
         public function set color(value:Number):void {  
             _color = value;  
         }  
          
         //構造函數  
         public function MyEffectInstance(newTarget:Object) {  
             super(newTarget);  
         }  
          
         //同樣的要重寫play()方法與調用父類同名方法  
         override public function play( ):void {  
             super.play();  
             drawShape();        //先創建一個矩形  
             /*注意:用Tween效果寫法的話,就一定要創建一個Tween對象  
             第一個參數是偵聽器,即偵聽Update與End的,這兩個方法都在這個類裏,  
             所以這裏就寫this,第二和第三個參數都是一個數組  
             第二個參數是初始值數組,第三個是結果值數組,都要一一對應,第四個是變化時間  
             這裏的是[1,1]分別是初始時的scale比例與alpha,[3,0]就是最終結果數值  
             系統會自動在1000毫秒裏平分這些值來得到漸變效果  
             並將每一次數值的改變時調用Update方法,結束後調用End方法  
                     你也可以將時間的參數發佈到工廠類屬性裏,可以方便設置播放時間,像Flex自帶效果一樣  
                          */  
             new Tween(this,[1,1],[3,0],1000);  
         }  
          
         override public function onTweenUpdate(value:Object):void{  
             //這裏將改變的數值應用到組件對象中。注意:也要與上面的數值數組相對應。  
             shape.scaleX = Number(value[0]);  
             shape.scaleY = Number(value[0]);  
             shape.alpha = Number(value[1]);  
         }  
          
         override public function onTweenEnd(value:Object):void {  
             //當播放完時會自動調用該方法,這裏就做刪除該矩形的操作吧  
             target.parent.rawChildren.removeChild(shape);  
         }  
          
         private function drawShape():void{  
             shape = new Shape();  
             shape.graphics.beginFill(_color);  
             shape.graphics.drawRect(target.width * -0.5,target.height * -0.5,target.width,target.height);  
             shape.graphics.endFill();  
             shape.x = target.x + target.width * 0.5;  
             shape.y = target.y + target.height * 0.5;  
             target.parent.rawChildren.addChild(shape);  
         }  
     }  

package com.jiangzone.flex.effects {
     import mx.effects.effectClasses.TweenEffectInstance;
     import flash.display.Shape;
     import flash.events.Event;
     import mx.effects.Tween;
   
     public class MyEffectInstance extends TweenEffectInstance {
               
         private var _color:Number;
         private var shape:Shape;
       
         public function set color(value:Number):void {
             _color = value;
         }
       
         //構造函數
         public function MyEffectInstance(newTarget:Object) {
             super(newTarget);
         }
       
         //同樣的要重寫play()方法與調用父類同名方法
         override public function play( ):void {
             super.play();
             drawShape();        //先創建一個矩形
             /*注意:用Tween效果寫法的話,就一定要創建一個Tween對象
             第一個參數是偵聽器,即偵聽Update與End的,這兩個方法都在這個類裏,
             所以這裏就寫this,第二和第三個參數都是一個數組
             第二個參數是初始值數組,第三個是結果值數組,都要一一對應,第四個是變化時間
             這裏的是[1,1]分別是初始時的scale比例與alpha,[3,0]就是最終結果數值
             系統會自動在1000毫秒裏平分這些值來得到漸變效果
             並將每一次數值的改變時調用Update方法,結束後調用End方法
                     你也可以將時間的參數發佈到工廠類屬性裏,可以方便設置播放時間,像Flex自帶效果一樣
                          */
             new Tween(this,[1,1],[3,0],1000);
         }
       
         override public function onTweenUpdate(value:Object):void{
             //這裏將改變的數值應用到組件對象中。注意:也要與上面的數值數組相對應。
             shape.scaleX = Number(value[0]);
             shape.scaleY = Number(value[0]);
             shape.alpha = Number(value[1]);
         }
       
         override public function onTweenEnd(value:Object):void {
             //當播放完時會自動調用該方法,這裏就做刪除該矩形的操作吧
             target.parent.rawChildren.removeChild(shape);
         }
       
         private function drawShape():void{
             shape = new Shape();
             shape.graphics.beginFill(_color);
             shape.graphics.drawRect(target.width * -0.5,target.height * -0.5,target.width,target.height);
             shape.graphics.endFill();
             shape.x = target.x + target.width * 0.5;
             shape.y = target.y + target.height * 0.5;
             target.parent.rawChildren.addChild(shape);
         }
     }
}


就寫到這裏吧,關於Tween其它的,就留作爲作業,讓大家思考與探索吧!之後如果有時間的話,將會寫完下篇文章介紹Flex的“變面”動畫,即狀態變換!這裏先謝謝大家支持!


3.Flex的Transitions



這篇文章是Flex動畫效果變換的最後一編了,這篇將會講述Flex中的“變面”(我自已的理解)技術,即是Transitions!
如果看過Flex SDK裏面的自帶的例子程序,有一個叫“Flex Store”的應用,在裏面的手機列表中看某一個手機的詳細時,就是這種效果,不多說,這篇會比較簡單.



看看代碼再解析:



Flex代碼
<?xml version="1.0" encoding="utf-8"?>  
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="695" height="555">  
<mx:states>  
<mx:State name="A">  
    <mx:SetProperty target="{windowA}" name="width" value="500"/>  
    <mx:SetProperty target="{windowA}" name="height" value="300"/>  
    <mx:SetProperty target="{windowC}" name="width" value="150"/>  
    <mx:SetProperty target="{windowC}" name="height" value="150"/>  
    <mx:SetProperty target="{windowC}" name="y" value="333"/>  
    <mx:SetProperty target="{windowD}" name="x" value="373"/>  
    <mx:SetProperty target="{windowD}" name="width" value="150"/>  
    <mx:SetProperty target="{windowD}" name="height" value="150"/>  
    <mx:SetProperty target="{windowD}" name="y" value="333"/>  
    <mx:SetProperty target="{windowB}" name="x" value="23"/>  
    <mx:SetProperty target="{windowB}" name="y" value="333"/>  
    <mx:SetProperty target="{windowB}" name="width" value="150"/>  
    <mx:SetProperty target="{windowB}" name="height" value="150"/>  
    <mx:SetProperty target="{windowC}" name="x" value="200"/>  
</mx:State>  
<mx:State name="B">  
    <mx:SetProperty target="{windowD}" name="width" value="150"/>  
    <mx:SetProperty target="{windowD}" name="height" value="150"/>  
    <mx:SetProperty target="{windowC}" name="width" value="150"/>  
    <mx:SetProperty target="{windowC}" name="height" value="150"/>  
    <mx:SetProperty target="{windowA}" name="width" value="150"/>  
    <mx:SetProperty target="{windowA}" name="height" value="150"/>  
    <mx:SetProperty target="{windowB}" name="width" value="500"/>  
    <mx:SetProperty target="{windowB}" name="height" value="300"/>  
    <mx:SetProperty target="{windowA}" name="y" value="333"/>  
    <mx:SetProperty target="{windowC}" name="x" value="200"/>  
    <mx:SetProperty target="{windowC}" name="y" value="333"/>  
    <mx:SetProperty target="{windowB}" name="x" value="23"/>  
    <mx:SetProperty target="{windowD}" name="x" value="373"/>  
    <mx:SetProperty target="{windowD}" name="y" value="333"/>  
</mx:State>  
<mx:State name="C">  
    <mx:SetProperty target="{windowD}" name="width" value="150"/>  
    <mx:SetProperty target="{windowD}" name="height" value="150"/>  
    <mx:SetProperty target="{windowB}" name="width" value="150"/>  
    <mx:SetProperty target="{windowB}" name="height" value="150"/>  
    <mx:SetProperty target="{windowA}" name="width" value="150"/>  
    <mx:SetProperty target="{windowA}" name="height" value="150"/>  
    <mx:SetProperty target="{windowC}" name="width" value="500"/>  
    <mx:SetProperty target="{windowC}" name="height" value="300"/>  
    <mx:SetProperty target="{windowA}" name="y" value="333"/>  
    <mx:SetProperty target="{windowB}" name="x" value="200"/>  
    <mx:SetProperty target="{windowB}" name="y" value="333"/>  
    <mx:SetProperty target="{windowC}" name="x" value="23"/>  
    <mx:SetProperty target="{windowC}" name="y" value="19"/>  
    <mx:SetProperty target="{windowD}" name="x" value="373"/>  
    <mx:SetProperty target="{windowD}" name="y" value="333"/>  
</mx:State>  
<mx:State name="D">  
<mx:SetProperty target="{windowC}" name="width" value="150"/>  
<mx:SetProperty target="{windowC}" name="height" value="150"/>  
<mx:SetProperty target="{windowB}" name="width" value="150"/>  
<mx:SetProperty target="{windowB}" name="height" value="150"/>  
<mx:SetProperty target="{windowA}" name="width" value="150"/>  
<mx:SetProperty target="{windowA}" name="height" value="150"/>  
<mx:SetProperty target="{windowD}" name="width" value="500"/>  
<mx:SetProperty target="{windowD}" name="height" value="300"/>  
<mx:SetProperty target="{windowA}" name="y" value="333"/>  
<mx:SetProperty target="{windowB}" name="x" value="200"/>  
<mx:SetProperty target="{windowB}" name="y" value="333"/>  
<mx:SetProperty target="{windowD}" name="x" value="23"/>  
<mx:SetProperty target="{windowD}" name="y" value="19"/>  
<mx:SetProperty target="{windowC}" name="x" value="373"/>  
<mx:SetProperty target="{windowC}" name="y" value="333"/>  
</mx:State>  
</mx:states>  
<mx:transitions>  
<mx:Transition fromState="*" toState="*">  
<mx:Parallel targets="{[windowA, windowB, windowC, windowD]}">  
<mx:Move />  
<mx:Resize />  
</mx:Parallel>  
</mx:Transition>  
</mx:transitions>  
<mx:TitleWindow x="23" y="19" width="250" height="200" layout="absolute" title="A" id="windowA" click="currentState='A'" />  
<mx:TitleWindow x="309" y="19" width="250" height="200" layout="absolute" title="B" id="windowB" click="currentState='B'" />  
<mx:TitleWindow x="23" y="260" width="250" height="200" layout="absolute" title="C" id="windowC" click="currentState='C'" />  
<mx:TitleWindow x="309" y="260" width="250" height="200" layout="absolute" title="D" id="windowD" click="currentState='D'" />  
</mx:Application> 
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="695" height="555">
<mx:states>
<mx:State name="A">
     <mx:SetProperty target="{windowA}" name="width" value="500"/>
     <mx:SetProperty target="{windowA}" name="height" value="300"/>
     <mx:SetProperty target="{windowC}" name="width" value="150"/>
     <mx:SetProperty target="{windowC}" name="height" value="150"/>
     <mx:SetProperty target="{windowC}" name="y" value="333"/>
     <mx:SetProperty target="{windowD}" name="x" value="373"/>
     <mx:SetProperty target="{windowD}" name="width" value="150"/>
     <mx:SetProperty target="{windowD}" name="height" value="150"/>
     <mx:SetProperty target="{windowD}" name="y" value="333"/>
     <mx:SetProperty target="{windowB}" name="x" value="23"/>
     <mx:SetProperty target="{windowB}" name="y" value="333"/>
     <mx:SetProperty target="{windowB}" name="width" value="150"/>
     <mx:SetProperty target="{windowB}" name="height" value="150"/>
     <mx:SetProperty target="{windowC}" name="x" value="200"/>
</mx:State>
<mx:State name="B">
     <mx:SetProperty target="{windowD}" name="width" value="150"/>
     <mx:SetProperty target="{windowD}" name="height" value="150"/>
     <mx:SetProperty target="{windowC}" name="width" value="150"/>
     <mx:SetProperty target="{windowC}" name="height" value="150"/>
     <mx:SetProperty target="{windowA}" name="width" value="150"/>
     <mx:SetProperty target="{windowA}" name="height" value="150"/>
     <mx:SetProperty target="{windowB}" name="width" value="500"/>
     <mx:SetProperty target="{windowB}" name="height" value="300"/>
     <mx:SetProperty target="{windowA}" name="y" value="333"/>
     <mx:SetProperty target="{windowC}" name="x" value="200"/>
     <mx:SetProperty target="{windowC}" name="y" value="333"/>
     <mx:SetProperty target="{windowB}" name="x" value="23"/>
     <mx:SetProperty target="{windowD}" name="x" value="373"/>
     <mx:SetProperty target="{windowD}" name="y" value="333"/>
</mx:State>
<mx:State name="C">
     <mx:SetProperty target="{windowD}" name="width" value="150"/>
     <mx:SetProperty target="{windowD}" name="height" value="150"/>
     <mx:SetProperty target="{windowB}" name="width" value="150"/>
     <mx:SetProperty target="{windowB}" name="height" value="150"/>
     <mx:SetProperty target="{windowA}" name="width" value="150"/>
     <mx:SetProperty target="{windowA}" name="height" value="150"/>
     <mx:SetProperty target="{windowC}" name="width" value="500"/>
     <mx:SetProperty target="{windowC}" name="height" value="300"/>
     <mx:SetProperty target="{windowA}" name="y" value="333"/>
     <mx:SetProperty target="{windowB}" name="x" value="200"/>
     <mx:SetProperty target="{windowB}" name="y" value="333"/>
     <mx:SetProperty target="{windowC}" name="x" value="23"/>
     <mx:SetProperty target="{windowC}" name="y" value="19"/>
     <mx:SetProperty target="{windowD}" name="x" value="373"/>
     <mx:SetProperty target="{windowD}" name="y" value="333"/>
</mx:State>
<mx:State name="D">
<mx:SetProperty target="{windowC}" name="width" value="150"/>
<mx:SetProperty target="{windowC}" name="height" value="150"/>
<mx:SetProperty target="{windowB}" name="width" value="150"/>
<mx:SetProperty target="{windowB}" name="height" value="150"/>
<mx:SetProperty target="{windowA}" name="width" value="150"/>
<mx:SetProperty target="{windowA}" name="height" value="150"/>
<mx:SetProperty target="{windowD}" name="width" value="500"/>
<mx:SetProperty target="{windowD}" name="height" value="300"/>
<mx:SetProperty target="{windowA}" name="y" value="333"/>
<mx:SetProperty target="{windowB}" name="x" value="200"/>
<mx:SetProperty target="{windowB}" name="y" value="333"/>
<mx:SetProperty target="{windowD}" name="x" value="23"/>
<mx:SetProperty target="{windowD}" name="y" value="19"/>
<mx:SetProperty target="{windowC}" name="x" value="373"/>
<mx:SetProperty target="{windowC}" name="y" value="333"/>
</mx:State>
</mx:states>
<mx:transitions>
<mx:Transition fromState="*" toState="*">
<mx:Parallel targets="{[windowA, windowB, windowC, windowD]}">
<mx:Move />
<mx:Resize />
</mx:Parallel>
</mx:Transition>
</mx:transitions>
<mx:TitleWindow x="23" y="19" width="250" height="200" layout="absolute" title="A" id="windowA" click="currentState='A'" />
<mx:TitleWindow x="309" y="19" width="250" height="200" layout="absolute" title="B" id="windowB" click="currentState='B'" />
<mx:TitleWindow x="23" y="260" width="250" height="200" layout="absolute" title="C" id="windowC" click="currentState='C'" />
<mx:TitleWindow x="309" y="260" width="250" height="200" layout="absolute" title="D" id="windowD" click="currentState='D'" />
</mx:Application>


代碼會比較多,我們先看看<mx:states>標籤,它是一個集合,就是你的程序有多少個狀態,什麼是狀態呢?我自已理解就即是有多少個“面譜”,即是現在程序裏面有四個顯示界面狀態,所以裏面有四個<mx:State>標籤,每個<mx:State>狀態都需要有一個名字name屬性,以區分是哪個界面狀態,在每個狀態裏面都有很多<mx:SetProperty>的標籤,看英文都知道了,該標籤用於設置這個狀態下的所有界面元素的屬性(組件的屬性),因爲每個界面狀態中各個組件的大小布局都不同,所以在狀態標籤裏就要預先設置好該狀態下的組件的位置與大小,那個target="{windowC}"屬性就是設置你要設置的哪個組件的名字拉,name="height"就是你要設置的屬性value="333"就是你要設置該屬性的值,我們細心看看的話,可能會發現,每個狀態裏面設置的屬性,都是width,height,x,y這四個屬性,我們看看上面的最終效果就知道無論切換哪個狀態,組件間的變換來來去去都是移動位置與大小改變,就是說當你變換狀態時,需要改動哪些屬性的,就將它的目標值設置在<mx:SetProperty>標籤裏。再看看下面的<mx:transitions>標籤,這個也是個集合,裏面放着不同的變換方法<mx:Transition>,我們來看看變換標籤的代碼:



Flex代碼
<mx:Transition fromState="*" toState="*">  
<mx:Parallel targets="{[windowA, windowB, windowC, windowD]}">  
<mx:Move />  
<mx:Resize />  
</mx:Parallel>  
</mx:Transition> 
<mx:Transition fromState="*" toState="*">
<mx:Parallel targets="{[windowA, windowB, windowC, windowD]}">
<mx:Move />
<mx:Resize />
</mx:Parallel>
</mx:Transition>


formState與toState屬性是要設置該狀態變換是怎樣觸發的,裏面要填上狀態的名字,<mx:State name="C">   C就是狀態的名字,即是如果你formState="A",toState="C"的話,只有從A狀態切換到C狀態時,纔會產生以上的變換動畫效果,如果不附合該規則如A切換到B狀態的話,則只會按狀態的屬性設置值來直接生成視圖,而沒有動畫漸變效果了。如果填上“*”的話,就是無論是哪個狀態切換到哪個,都會運行動畫效果,至於變換期間用到哪種動畫效果來進行漸變,就在它的下級標籤裏定義了,這裏它用到了<mx:Parallel>並列播放移動與重整大小的動畫效果,之前文章講過,這裏不多說了。基本上,一個變換就做好了,但我們還需要觸發它,也就是去改變程序當前的顯示狀態:click="currentState='A'" 在每個組件的click事件裏,改變程序的currentState值,就是改變程序的當前顯示狀態!之後動畫效果就會觸發了!

遲點有時間,再做一個3D的動畫效果,將會用到PV3D的框架,再整理一個代碼與教程也貼出來跟大家分享吧,不過不知道大家對PV3D這個東東熟悉不,不熟悉的話,可能看得痛苦點,至於PV3D方面的教程,我也看看抽點時間寫寫吧!先謝過大家的支持!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章