Adobe Flex 3 Help

Writing an effect for a transition

Transitions define how a change of view state appears on the screen. You define a transition by using a combination of the Flex effect classes. For more information on transitions, see Using Transitions.

You can define your own custom effects for use in transitions. To do so, you have to account for the effect being used in a transition when you override the EffectInstance.play() method. The EffectInstance.play() method must be able to determine default values for effect properties when the effect is used in a transition.

Defining the default values for a transition effect

Like any effect, an effect in a transition has properties that you use to configure it. For example, most effects have properties that define starting and ending information for the target component, such as the xFrom, yFrom, xTo, and yTo properties of the Move effect.

Flex uses the following rules to determine the start and end values of effect properties when you use the effect in a transition:

  1. If the effect defines the values of any properties, it uses the properties in the transition, as the following example shows:
    <mx:Transition fromState="*" toState="*">
        <mx:Sequence id="t1" targets="{[p1,p2,p3]}">            
            <mx:Blur duration="100" 
                blurXFrom="0.0" blurXTo="10.0" blurYFrom="0.0" blurYTo="10.0"/>
         <mx:Parallel>
                <mx:Move duration="400"/>
                <mx:Resize duration="400"/>
            </mx:Parallel>    
         <mx:Blur duration="100" 
                blurXFrom="10.0" blurXTo="0.0" blurYFrom="10.0" blurYTo="0.0"/>            
        </mx:Sequence>
    </mx:Transition>
    
    

    In this example, the two Blur filters define the properties of the effect.

  2. If the effect does not define the start values of the effect, the effect determines the values from the EffectInstance.propertyChanges property passed to the effect instance. Flex sets the propertyChanges property by using information from the current settings of the component, as defined by the current view state. For more information on the propertyChanges property, see How Flex initializes the propertyChanges property.

    In the example in step 1, notice that the Move and Resize effects do not define start values. Therefore, Flex determines the start values from the current size and position of the effect targets in the current view state, and passes that information to each effect instance by using the propertyChanges property.

  3. If the effect does not define the end values of the effect, the effect determines the values from the Effectinstance.propertyChanges property passed to the effect instance. Flex sets the propertyChanges property by using information about the component, as defined by the destination view state. For more information on the propertyChanges property, see How Flex initializes the propertyChanges property.

    In the example in rule 1, Flex determines the end values of the Move and Resize effects from the size and position of the effect targets in the destination view state. In some cases, the destination view state defines those values. If the destination view state does not define the values, Flex determines them from the setting of the base view state, and passes that information to each effect instance by using the propertyChanges property.

  4. If there are no explicit values, and Flex cannot determine values from the current or destination view states, the effect uses its default property values.

Using the propertyChanges property

The EffectInstance.propertyChanges property contains a PropertyChanges object. A PropertyChanges object contains the properties described in the following table:

Property

Description

target

A target component of the effect. The end and start properties of the PropertyChanges class define how the target component is modified by the change to the view state.

start

An object that contains the starting properties of the target component, as defined by the current view state. For example, for a target component that is moved and resized by a change to the view state, the start property contains the starting position and size of the component, as the following example shows:

{x:00, y:00, width:100, height:100}
end

An object that contains the ending properties of the target component, as defined by the destination view state. For example, for a target component that is moved and resized by a change to the view state, the end property contains the ending position and size of the component, as the following example shows:

{x:100, y:100, width:200, height:200}

In the body of the Effectinstance.play() method, you can examine the information in the propertyChanges property to configure the effect.

How Flex initializes the propertyChanges property

Before you can use the EffectInstance.propertyChanges property in your effect instance, it has to be properly initialized. When you change the view state, Flex initializes propertyChanges.start and propertyChanges.end separately.

The following steps describe the actions that occur when you change view states. Notice that Flex initializes propertyChanges.start as part of step 4, and initializes propertyChanges.end as part of step 7.

  1. You set the currentState property to the destination view state.
  2. Flex dispatches the currentStateChanging event.
  3. Flex examines the list of transitions to determine the one that matches the change of view state.
  4. Flex calls the Effect.captureStartValues() method to initialize propertyChanges.start for all effect instances.

    You can also call Effect.captureStartValues() to initialize an effect instance used outside of a transition.

  5. Flex applies the destination view state to the application.
  6. Flex dispatches the currentStateChange event.
  7. Flex plays the effects defined in the transition.

    As part of playing the effect, Flex invokes the factory class play() method and the Effect.play() method to initialize propertyChanges.end for effect instances.

Example: Creating a transition effect

The following example modifies the Rotation effect created in Example: Creating a tween effect to make the effect usable in a transition.

This example shows the RotationTrans.as class that defines the factory class for the effect. To create RotationTrans.as, the only modification you make to Rotation.as is to remove the default value definitions for the angleFrom and angleTo properties. The RotationTransInstance.play() method determines the default values.

package myEffects
{
   // myEffects/RotationTrans.as
   import mx.effects.TweenEffect;
   import mx.effects.EffectInstance;
   import mx.effects.IEffectInstance;

   public class RotationTrans extends TweenEffect
   {
       // Define parameters for the effect.
       // Do not specify any default values. 
       // The default value of these properties is NaN.
       public var angleFrom:Number;
       public var angleTo:Number;
 
       // Define constructor with optional argument.
       public function RotationTrans(targetObj:Object = null) {
           super(targetObj);
           instanceClass= RotationTransInstance;           
       }

       // Override getAffectedProperties() method to return "rotation".
       override public function getAffectedProperties():Array {
           return ["rotation"];
       }
    
       // Override initInstance() method.
       override protected function initInstance(inst:IEffectInstance):void {
           super.initInstance(inst);
           RotationTransInstance(inst).angleFrom = angleFrom;
           RotationTransInstance(inst).angleTo = angleTo;
       } 
   }
}

In the RotationTransInstance.as class, you modify the play() method to calculate the default values for the angleFrom and angleTo properties. This method performs the following actions:

  1. Determines whether the user set values for the angleFrom and angleTo properties.
  2. If not, determines whether the Effectinstance.propertyChanges property was initialized with start and end values. If so, the method uses those values to configure the effect.
  3. If not, sets the angleFrom and angleTo properties to the default values of 0 for the angleFrom property, and 360 for the angleTo property.

The following example shows the RotationTransInstance.as class:

package myEffects
{
    // myEffects/RotationTransInstance.as
    import mx.effects.effectClasses.TweenEffectInstance;
    import mx.effects.Tween;

    public class RotationTransInstance extends TweenEffectInstance
    {
        // Define parameters for the effect.
        public var angleFrom:Number;
        public var angleTo:Number;
  
        public function RotationTransInstance(targetObj:Object) {
            super(targetObj);
        }
  
        // Override play() method class.
        override public function play():void {
            // All classes must call super.play().
            super.play();
            
            // Check whether angleFrom is set.
            if (isNaN(angleFrom)) 
            {
              // If not, look in propertyChanges.start for a value. 
              // Otherwise, set it to 0.
              angleFrom = (propertyChanges.start["rotation"] != undefined) ? 
                    propertyChanges.start["rotation"] : 0;

            }
                    
            // Check whether angleTo is set.
            if (isNaN(angleTo)) 
            {
                // If not, look in propertyChanges.end for a value. 
                // Otherwise, set it to 360.
                angleTo = (propertyChanges.end["rotation"] != undefined) ? 
                    propertyChanges.end["rotation"] : 360;
            }
            
            // Create a Tween object. The tween begins playing immediately.
            var tween:Tween = 
                createTween(this, angleFrom, angleTo, duration);  
        }

        // Override onTweenUpdate() method.
        override public function onTweenUpdate(val:Object):void {
            target.rotation = val;
        }
  
        // Override onTweenEnd() method.
        override public function onTweenEnd(val:Object):void {
            // All classes that implement onTweenEnd() 
            // must call super.onTweenEnd().
            super.onTweenEnd(val);
        }
    }
}

The following application uses the RotationTrans effect:

<?xml version="1.0" encoding="UTF-8"?>
<!-- effects/MainRotationTrans.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    xmlns:MyComp="myEffects.*"> 

    <!-- Define the two view states, in addition to the base state.-->
    <mx:states>
        <mx:State name="One">
            <mx:SetProperty target="{p1}" name="x" value="110"/>
            <mx:SetProperty target="{p1}" name="y" value="0"/>
            <mx:SetProperty target="{p1}" name="width" value="200"/>
            <mx:SetProperty target="{p1}" name="height" value="210"/>
            <mx:SetProperty target="{p2}" name="x" value="0"/>
            <mx:SetProperty target="{p2}" name="y" value="0"/>
            <mx:SetProperty target="{p2}" name="width" value="100"/>
            <mx:SetProperty target="{p2}" name="height" value="100"/>
            <mx:SetProperty target="{p3}" name="x" value="0"/>
            <mx:SetProperty target="{p3}" name="y" value="110"/>
            <mx:SetProperty target="{p3}" name="width" value="100"/>
            <mx:SetProperty target="{p3}" name="height" value="100"/>
        </mx:State>
        <mx:State name="Two">
            <mx:SetProperty target="{p2}" name="x" value="110"/>
            <mx:SetProperty target="{p2}" name="y" value="0"/>
            <mx:SetProperty target="{p2}" name="width" value="200"/>
            <mx:SetProperty target="{p2}" name="height" value="210"/>
            <mx:SetProperty target="{p3}" name="x" value="0"/>
            <mx:SetProperty target="{p3}" name="y" value="110"/>
            <mx:SetProperty target="{p3}" name="width" value="100"/>
            <mx:SetProperty target="{p3}" name="height" value="100"/>
        </mx:State>
    </mx:states>
    
    <!-- Define the single transition for all view state changes.-->
    <mx:transitions>
        <mx:Transition fromState="*" toState="*">
            <mx:Sequence id="t1" targets="{[p1,p2,p3]}">            
                <mx:Parallel>
                    <mx:Move  duration="400"/>
                    <mx:Resize duration="400"/>
                </mx:Parallel>  
                <MyComp:RotationTrans filter="move"/>
            </mx:Sequence>
        </mx:Transition>
    </mx:transitions>
    
    <!-- Define the Canvas container holdig the three Panel containers.-->
    <mx:Canvas id="pm" width="100%" height="100%" >
        <mx:Panel id="p1" title="One" 
                x="0" y="0" width="100" height="100" 
                click="currentState='One'" >
            <mx:Label fontSize="24" text="One"/>
        </mx:Panel>
        <mx:Panel id="p2" title="Two" 
                x="0" y="110" width="100" height="100" 
                click="currentState='Two'" >
            <mx:Label fontSize="24" text="Two"/>
        </mx:Panel>
        <mx:Panel id="p3" title="Three" 
                x="110" y="0" width="200" height="210" 
                click="currentState=''" >
            <mx:Label fontSize="24" text="Three"/>
        </mx:Panel>
    </mx:Canvas>
</mx:Application>

The executing SWF file for the previous example is shown below: