Custom effects

Flex supplies a number of standard effects that you can use in your application. However, you also can define custom effects for your specific application needs.

For information on the standard effects, see Introduction to effects.

About creating a custom effect

Flex implements effects by using an architecture in which each effect is represented by two classes: a factory class and an instance class. Therefore, to implement a custom effect, you create two classes: the factory class and the instance class.

You create a factory class by creating a subclass of the mx.effects.Effect class, or by creating a subclass of one of the subclasses of the mx.effects.Effect class. You create an instance class by creating a subclass of the mx.effects.EffectInstance class, or a subclass of one of the subclasses of the mx.effects.EffectInstance class.

Defining factory and instance classes

To define a custom effect, you create two classes: the factory class and the instance class:

Factory class

The factory class creates an object of the instance class to perform the effect on the target. You create a factory class instance in your application, and configure it with the necessary properties to control the effect, such as the zoom size or effect duration, as the following example shows:

<fx:Declarations> 
	 <!-- Define factory class. --> 
	<s:Resize id="myResizeEffect" target="{myImage}" 
		widthBy="10" heightBy="10"/> 
</fx:Declarations> 
 
<mx:Image id="myImage" source="@Embed(source='assets/logo.jpg')"/> 
<s:Button label="Resize Me" click="myResizeEffect.end();myResizeEffect.play();"/>

By convention, the name of a factory class is the name of the effect, such as Zoom or Fade.

Instance class

The instance class implements the effect logic. When you invoke an effect, the factory class creates an object of the instance class to perform the effect on the target. When the effect ends, Flex destroys the instance object. If the effect has multiple target components, the factory class creates multiple instance objects, one per target.

By convention, the name of an instance class is the name of the effect with the suffix Instance, such as ZoomInstance or FadeInstance.

About the effect base classes

You define effects by creating a subclass from the effects class hierarchy. Typically, you create a subclass from one of the following classes:

  • mx.effects.Effect Create a subclass from this class for simple effects that do not require an effect to play over a period of time. For example, the Pause effect inserts a delay between two consecutive effects. You can also define a simple sound effect that plays an MP3 file.

  • spark.effects.Animate Create a subclass from this class to define an effect that animates a set of properties between values over a period of time. For example, the Spark AnimateColor effect is a subclass of the Animate class that modifies a color property of its target over a specified duration.

  • mx.effects.TweenEffect Create a subclass from this class to define an effect that plays over a period of time, such as an animation. For example, the MX Resize effect is a subclass of the TweenEffect class that modifies the size of its target over a specified duration.

About implementing your effects classes

You must override several methods and properties in your custom effect classes, and define any new properties and methods that are required to implement the effect. You can optionally override additional properties and methods based on the type of effect that you create.

The following table lists the methods and properties that you define in a factory class:

Factory method/property

Description

constructor

(Required) The class constructor. You typically call the super() method to invoke the superclass constructor to initialize the inherited items from the superclasses.

Your constructor must take at least one optional argument, of type Object. This argument specifies the target component of the effect.

Effect.initInstance() 

(Required) Copies properties of the factory class to the instance class. Flex calls this protected method from the Effect.createInstance() method; you do not have to call it yourself.

In your override, you must call the super.initInstance() method.

Effect.getAffectedProperties() 

(Required) Returns an Array of Strings, where each String is the name of a property of the target object that is changed by this effect. If the effect does not modify any properties, it should return an empty Array.

Effect.instanceClass

(Required) Contains an object of type Class that specifies the name of the instance class for this effect class.

All subclasses of the Effect class must set this property, typically in the constructor.

Effect.effectEndHandler() 

(Optional) Called when an effect instance finishes playing. If you override this method, ensure that you call the super() method.

Effect.effectStartHandler()

(Optional) Called when the effect instance starts playing. If you override this method, ensure that you call the super() method.

Additional methods and properties

(Optional) Define any additional methods and properties that the user requires to configure the effect.

The following table lists the methods and properties that you define in an instance class:

Instance method/property

Description

constructor

(Required) The class constructor. You typically call the super() method to invoke the superclass constructor to initialize the inherited items from the superclasses.

EffectInstance.play() 

(Required) Invokes the effect. You must call super.play() from your override.

EffectInstance.end() 

(Optional) Interrupts an effect that is currently playing, and jumps immediately to the end of the effect.

EffectInstance.initEffect() 

(Optional) Called if the effect was triggered by the EffectManager. You rarely have to implement this method. For more information, see Overriding the initEffect() method.

TweenEffectInstance.onTweenUpdate() 

(Required) Use when you create a subclass from TweenEffectInstance. A callback method called at regular intervals to implement a tween effect. For more information, see Example: Creating a tween effect.

TweenEffectInstance.onTweenEnd() 

(Optional) Use when you create a subclass from TweenEffectInstance. A callback method called when the tween effect ends. You must call super.onTweenEnd() from your override. For more information, see Example: Creating a tween effect.

Additional methods and properties

(Optional) Define any additional methods and properties. These typically correspond to the public properties and methods from the factory class, and any additional properties and methods that you require to implement the effect.

Example: Defining a simple effect

To define a simple custom effect, you create a factory class from the Effect base class, and the instance class from the mx.effects.EffectInstance class. The following example shows an effect class that uses a Sound object to play an embedded MP3 file when a user action occurs. This example is a simplified version of the SoundEffect class that ships with Flex.

package myEffects 
{ 
   // createcomps_effects/myEffects/MySound.as 
   import mx.effects.Effect; 
   import mx.effects.EffectInstance; 
   import mx.effects.IEffectInstance; 
 
   public class MySound extends Effect 
   { 
       // Define constructor with optional argument. 
       public function MySound(targetObj:Object = null) { 
           // Call base class constructor. 
           super(targetObj); 
           
           // Set instanceClass to the name of the effect instance class. 
           instanceClass= MySoundInstance;         
       } 
      
       // This effect modifies no properties, so your 
       // override of getAffectedProperties() method 
       // returns an empty array. 
       override public function getAffectedProperties():Array { 
           return []; 
       } 
        
       // Override initInstance() method. 
       override protected function initInstance(inst:IEffectInstance):void { 
           super.initInstance(inst); 
       }   
   } 
}

The package statement in your class specifies that you should deploy it in a directory called myEffects. In this example, you place it in the subdirectory of the directory that contains your Flex application. Therefore, the namespace definition in your Flex application is xmlns:MyComp="myEffects.*". For more information on deployment, see Component compilation.

To define your instance class, you create a subclass from the mx.effects.EffectInstance class. In the class definition, you must define a constructor and play() methods, and you can optionally define an end() method to stop the effect.

package myEffects 
{ 
    // createcomps_effects/myEffects/MySoundInstance.as 
    import mx.effects.EffectInstance; 
    import flash.media.SoundChannel; 
    import flash.media.Sound; 
 
    public class MySoundInstance extends EffectInstance 
    { 
 
        // Embed the MP3 file. 
        [Embed(source="sample.mp3")] 
        [Bindable] 
        private var sndCls:Class; 
            
        // Define local variables. 
        private var snd:Sound = new sndCls() as Sound; 
        private var sndChannel:SoundChannel; 
            
        // Define constructor. 
        public function MySoundInstance(targetObj:Object) { 
            super(targetObj); 
        } 
 
        // Override play() method. 
        // Notice that the MP3 file is embedded in the class. 
        override public function play():void { 
            super.play(); 
            sndChannel=snd.play(); 
        } 
    
        // Override end() method class to stop the MP3. 
        override public function end():void { 
            sndChannel.stop(); 
            super.end(); 
        } 
    } 
}

To use your custom effect class in an MXML file, you insert a tag with the same name as the factory class in the MXML file. You reference the custom effect the same way that you reference a standard effect.

The following example shows an application that uses the MySound effect:

<?xml version="1.0"?> 
<!-- createcomps_effects/MainSoundEffect.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:MyComp="myEffects.*"> 
    <fx:Declarations> 
        <MyComp:MySound id="mySoundEffect" target="{myLabel}" /> 
    </fx:Declarations> 
 
    <!-- Use the SoundEffect effect with a mouseOver trigger. --> 
    <s:Label id="myLabel" 
        text="play MP3"  
        rollOver="mySoundEffect.end();mySoundEffect.play();"/> 
</s:Application>

Example: Passing parameters to effects

To make your effects more robust, you often design them to let the user pass parameters to them. The example in this section modifies the sound effect from the previous section to take a parameter that specifies the MP3 file to play:

package myEffects 
{ 
    // createcomps_effects/myEffects/MySoundParam.as 
    import mx.effects.Effect; 
    import mx.effects.EffectInstance; 
    import mx.effects.IEffectInstance; 
 
    public class MySoundParam extends Effect 
    { 
    
       // Define a variable for the MP3 URL 
       // and give it a default value. 
       public var soundMP3:String= 
           "http://localhost:8100/flex/assets/default.mp3"; 
    
       // Define constructor with optional argument. 
       public function MySoundParam(targetObj:Object = null) { 
           // Call base class constructor. 
           super(targetObj); 
 
           // Set instanceClass to the name of the effect instance class. 
          instanceClass= MySoundParamInstance;            
       } 
 
       // Override getAffectedProperties() method to return an empty array. 
       override public function getAffectedProperties():Array { 
           return []; 
       } 
    
       // Override initInstance() method. 
       override protected function initInstance(inst:IEffectInstance):void { 
           super.initInstance(inst); 
           // initialize the corresponding parameter in the instance class. 
           MySoundParamInstance(inst).soundMP3 = soundMP3;     
       } 
   } 
}

In the MySoundParam class, you define a variable named soundMP3 that enables the user of the effect to specify the URL of the MP3 file to play. You also modify your override of the initInstance() method to pass the value of the soundMP3 variable to the instance class.

Notice that the getAffectedProperties() method still returns an empty Array. That is because getAffectedProperties() returns the list of properties of the effect target that are modified by the effect, not the properties of the effect itself.

In your instance class, you define a property named soundMP3, corresponding to the property with the same name in the factory class. Then, you use it to create the URLRequest object to play the sound, as the following example shows:

package myEffects 
{ 
    // createcomps_effects/myEffects/MySoundParamInstance.as 
    import mx.effects.EffectInstance; 
    import flash.media.Sound; 
    import flash.media.SoundChannel; 
    import flash.net.URLRequest; 
 
    public class MySoundParamInstance extends EffectInstance 
    { 
 
        // Define local variables. 
        private var s:Sound; 
        private var sndChannel:SoundChannel; 
        private var u:URLRequest; 
 
        // Define a variable for the MP3 URL. 
        public var soundMP3:String; 
 
        // Define constructor. 
        public function MySoundParamInstance(targetObj:Object) { 
            super(targetObj); 
        } 
 
        // Override play() method. 
        override public function play():void     { 
            // You must call super.play() from within your override. 
            super.play(); 
            s = new Sound(); 
            // Use the new parameter to specify the URL. 
            u = new URLRequest(soundMP3); 
            s.load(u); 
            sndChannel=s.play(); 
        } 
    
        // Override end() method to stop the MP3. 
        override public function end():void  { 
            sndChannel.stop(); 
            super.end(); 
        } 
    } 
}

You can now pass the URL of an MP3 to the effect, as the following example shows:

<?xml version="1.0"?> 
<!-- createcomps_effects/MainSoundParam.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:MyComps="myEffects.*"> 
    <fx:Declarations> 
        <MyComps:MySoundParam id="mySoundEffect" 
            soundMP3="http://localhost:8100/flex/assets/sample.mp3"/> 
    </fx:Declarations> 
 
    <!-- Use the SoundEffect effect with a mouseOver trigger. --> 
    <mx:Label id="myLabel" 
        text="play MP3" 
        rollOver="mySoundEffect.end();mySoundEffect.play();"/> 
</s:Application>

About MX tween effects

Most MX effects are implemented by using the tweening mechanism, where a tween defines a transition performed on a target object over a period of time. That transition could be a change in size, such as the Zoom or Resize effects perform; a change in visibility, such as the Fade or Dissolve effects perform; or other types of transitions.

You use the following classes to implement a tween effect:

  • mx.effects.Tween A class used to implement tween effects. A Tween object accepts a start value, an end value, and an optional easing function. When you define tween effect classes, you create an instance of the Tween class in your override of the Effect.play() method.

    The Tween object invokes the mx.effects.TweenEffect.onTweenUpdate() callback method on a regular interval, passing the callback method an interpolated value between the start and end values. Typically, the callback method updates some property of the target component, causing that component's property to animate over time. For example, the Move effect modifies the x and y properties of the target component for the duration of the effect to show an animated movement.

    When the effect ends, the Tween object invokes the mx.effects.TweenEffect.onTweenEnd() callback method. This method performs any final processing before the effect terminates. You must call super.onTweenEnd() from your override.

  • mx.effects.TweenEffect The base factory class for all tween effects. This class encapsulates methods and properties that are common among all Tween-based effects.

  • mx.effects.effectClasses.TweenEffectInstance The instance class for all tween effects.

    When you define effects based on the TweenEffect class, you must override the TweenEffectInstance.onTweenUpdate() method, and optionally override the TweenEffectInstance.onTweenEnd() method.

The following example creates a tween effect. However, Flex supplies the AnimateProperty class that you can use to create a tween effect for a single property of the target component. For more information, see Introduction to effects.

Example: Creating a tween effect

In this example, you create a tween effect that rotates a component in a circle. This example implements a simplified version of the Rotate effect. The rotation is controlled by two parameters that are passed to the effect: angleFrom and angleTo:

package myEffects 
{ 
   // createcomps_effects/myEffects/Rotation.as 
   import mx.effects.TweenEffect; 
   import mx.effects.EffectInstance; 
   import mx.effects.IEffectInstance; 
 
   public class Rotation extends TweenEffect 
   { 
       // Define parameters for the effect. 
       public var angleFrom:Number = 0; 
       public var angleTo:Number = 360; 
  
       // Define constructor with optional argument. 
       public function Rotation(targetObj:* = null) { 
           super(targetObj); 
           instanceClass= RotationInstance;            
       } 
 
       // 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); 
           RotationInstance(inst).angleFrom = angleFrom; 
           RotationInstance(inst).angleTo = angleTo; 
       } 
   } 
}

In this example, the effect works by modifying the rotation property of the target component. Therefore, your override of the getAffectedProperties() method returns an array that contains a single element.

You derive your instance class from the TweenEffectInstance class, and override the play(), onTweenUpdate(), and onTweenEnd() methods, as the following example shows:

package myEffects 
{ 
    // createcomps_effects/myEffects/RotationInstance.as 
    import mx.effects.effectClasses.TweenEffectInstance; 
    import mx.effects.Tween; 
 
    public class RotationInstance extends TweenEffectInstance 
    { 
        // Define parameters for the effect. 
        public var angleFrom:Number; 
        public var angleTo:Number; 
  
        public function RotationInstance(targetObj:*) { 
            super(targetObj); 
        } 
  
        // Override play() method class. 
        override public function play():void { 
            // All classes must call super.play(). 
            super.play(); 
            // 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); 
        } 
    } 
}

In this example, the Tween object invokes the onTweenUpdate() callback method on a regular interval, passing it values between angleFrom and angleTo. At the end of the effect, the Tween object calls the onTweenUpdate() callback method with a value of angleTo. By invoking the onTweenUpdate() callback method at regular intervals throughout the duration of the effect, the target component displays a smooth animation as it rotates.

You use your new effect in an MXML application, as the following example shows:

<?xml version="1.0"?> 
<!-- createcomps_effects/MainRotation.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:MyComp="myEffects.*" 
    height="450"> 
    <fx:Declarations> 
        <MyComp:Rotation id="Rotate90" 
            angleFrom="0" angleTo="360" 
            duration="1000" 
            target="{myImage}"/> 
    </fx:Declarations> 
 
    <mx:Image id="myImage" 
        x="250" y="200" 
        source="@Embed(source='../assets/myRotationImage.jpg')" 
        mouseDown="Rotate90.end();Rotate90.play();"/> 
</s:Application>

In this example, you use the effect to rotate an image when the user clicks it.

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 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 
{ 
   // createcomps_effects/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 
{ 
    // createcomps_effects/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"?> 
<!-- createcomps_effects/MainRotationTrans.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:MyComp="myEffects.*"> 
    <!-- Define the two view states, in addition to the base state.--> 
    <s:states> 
        <s:State name="Default"/> 
        <s:State name="One"/> 
        <s:State name="Two"/> 
    </s:states> 
    
    <!-- Define the single transition for all view state changes.--> 
    <s: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> 
    </s: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" 
                x.One="110" 
                width="100" height="100" 
                width.One="200" height.One="200" 
                click="currentState='One'" > 
            <mx:Label fontSize="24" text="One"/> 
        </mx:Panel> 
        <mx:Panel id="p2" title="Two" 
                x="0" y="110" 
                y.One="0" 
                x.Two="110" y.Two="0" 
                width="100" height="100" 
                width.Two="200" height.Two="210" 
                click="currentState='Two'" > 
            <mx:Label fontSize="24" text="Two"/> 
        </mx:Panel> 
        <mx:Panel id="p3" title="Three" 
                x="110" y="0" 
                x.One="0" y.One="110" 
                x.Two="0" y.Two="110" 
                width="200" height="210" 
                width.One="100" height.One="100" 
                width.Two="100" height.Two="100" 
                click="currentState=''" > 
            <mx:Label fontSize="24" text="Three"/> 
        </mx:Panel> 
    </mx:Canvas> 
</s:Application>

Defining a custom effect trigger for MX effects

You can create a custom effect trigger to handle situations for which the standard Flex triggers do not meet your needs. An effect trigger is paired with a corresponding event that invokes the trigger. For example, a Button control has a mouseDown event and a mouseDownEffect trigger. The event initiates the corresponding effect trigger when a user clicks a component. You use the mouseDown event to specify the event listener that executes when the user selects the component. You use the mouseDownEffect trigger to associate an effect with the trigger.

Suppose that you want to apply an effect that sets the brightness level of a component when a user action occurs. The following example shows a custom Button control that uses a new property, bright, and dispatches two new events, darken and brighten, based on changes to the bright property. The control also defines two new effect triggers, darkenEffect and brightenEffect, which are paired with the darken event and the brighten event.

<?xml version="1.0"?> 
<!-- createcomps_effects\myComponents\MyButton.mxml --> 
<mx:Button xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" > 
 
    <fx:Metadata> 
        <!-- Define the metadata for the events and effect triggers. --> 
        [Event(name="darken", type="flash.events.Event")] 
        [Event(name="brighten", type="flash.events.Event")] 
        [Effect(name="darkenEffect", event="darken")] 
        [Effect(name="brightenEffect", event="brighten")] 
    </fx:Metadata> 
  
    <fx:Script> 
        <![CDATA[ 
            import flash.events.Event; 
 
            // Define the private variable for the bright setting. 
            private var _bright:Boolean = true; 
    
            // Define the setter to dispatch the events 
            // corresponding to the effect triggers. 
            public function set bright(value:Boolean):void { 
                _bright = value; 
                      
                if (_bright) 
                    dispatchEvent(new Event("brighten")); 
                else 
                    dispatchEvent(new Event("darken")); 
            } 
    
            // Define the getter to return the current bright setting. 
            public function get bright():Boolean { 
                return _bright; 
            } 
        ]]> 
    </fx:Script> 
</mx:Button>

When you declare an event in the form [Event(name=" eventName ", type=" package.eventType ")], you can also create a corresponding effect, in the form [Effect(name=" eventname Effect", event=" eventname ")]. As in the previous example, in the <fx:Metadata> tag, you insert the metadata statements that define the two new events, darken and brighten, and the new effect triggers, darkenEffect and brightenEffect, to the Flex compiler.

For more information on using metadata, see Metadata tags in custom components.

The application in the following example uses the MyButton control. The darkenEffect and brightenEffect properties are set to the FadeOut and FadeIn effects, respectively. The click event of a second Button control toggles the MyButton control's bright property and executes the corresponding effect (FadeOut or FadeIn).

<?xml version="1.0"?> 
<!-- createcomps_effects/MainMyButton.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:MyComp="myComponents.*" > 
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
 
    <fx:Declarations> 
        <!-- Define two fade effects for darkening and brightening target. --> 
        <mx:Fade id="FadeOut" 
            duration="1000" 
            alphaFrom="1.00" alphaTo=".20"/> 
        <mx:Fade id="FadeIn" 
            duration="1000" 
            alphaFrom=".20" alphaTo="1.00"/> 
    </fx:Declarations> 
 
    <!-- Define custom button that defines the 
        darkenEffect and brightenEffect. --> 
    <MyComp:MyButton 
        label="MyButton" id="btn" 
        darkenEffect="{FadeOut}" 
        brightenEffect="{FadeIn}" 
        darken="debugW.text='got darken event';" 
        brighten="debugW.text='got brighten event';"/> 
  
    <!-- Define button that triggers darken event. --> 
    <mx:Button 
        label="set bright to false" 
        click="btn.bright = false; myTA.text=String(btn.bright);"/> 
    
    <!-- Define button that triggers brighten event. --> 
    <mx:Button 
        label="set bright to true" 
        click="btn.bright = true; myTA.text=String(btn.bright);"/> 
    
    <!-- TextArea displays the current value of bright. --> 
    <mx:TextArea id="myTA" /> 
    
    <!-- TextArea displays event messages. -->  
    <mx:TextArea id="debugW" /> 
 
    <!-- Define button to make sure effects working. --> 
    <MyComp:MyButton id="btn2" label="test effects" 
        mouseDownEffect="{FadeOut}" 
        mouseUpEffect="{FadeIn}"/> 
</s:Application>

Overriding the initEffect() method

The EffectInstance class defines the initEffect() method that you can override in your custom effect. This method has the following signature:

 public initEffect(event:Event):void

where event is the Event object dispatched by the event that triggered the effect.

For example, a user might create an instance of an effect, but not provide all of the configuration information that is required to play the effect. Although you might be able to assign default values to all properties within the definition of the effect class, in some cases you might have to determine the default values at run time.

In this method, you can examine the event object and the effect target to calculate values at run time. For more information on how to create a custom event and an effect trigger, see Defining a custom effect trigger for MX effects. As part of that example, you can add properties to the event object passed to the dispatchEvent() method. You can then access that event object, and its additional properties, from the initEffect() method.

By overriding the initEffect() method, you can also access the target property of the Event object to reference the target component of the effect. For example, if you must determine the current x and y coordinates of the component, or its current height and width, you can access them from your override of the initEffect() method.

Navigation

Using Flex » Custom components

Adobe and Adobe Flash Platform are either registered trademarks or trademarks of Adobe Systems Incorporated in the United States and/or other countries and are used by permission from Adobe. No other license to the Adobe trademarks are granted.