As I discussed in my previous post “O’Reilly’s Flex 4 Cookbook Continues to Disappoint” I recently was frustrated when looking there for sample code to create a Flex 4 custom effect. The Adobe docs have some information on their page “About creating a custom effect” but some of the details are missing, particularly if you want to create an effect based on the Spark Animate class. When I found example 11.8 “Create Custom Animation Effects” in the Flex 4 Cookbook I thought I’d found the info I needed since the sample code on p. 308 shows a class extending Animate. However, I soon found that the code presented on pp. 308-310 is a confusing mish-mash of Flex 3 and Flex 4 that doesn’t even compile. I’ll spare you the gory details here. But if you’re really interested, see my previous post.
Here, I’ll share the code I eventually created to create a custom effect by extending the Flex 4 Animate and AnimateInstance classes. As discussed on the Adobe page mentioned above, you need to write two classes to create a custom animation class. One class is the factory class which the Flex framework uses to create an instance of your animation effect. The other is the class which implements your custom animation. It’s pretty easy once you figure out the basic outline. Here’s my factory class:
public class CustomAnimateEffect extends Animate { public var finalAlpha:Number; public function CustomAnimateEffect (target:Object=null) { super(target); this.instanceClass = CustomAnimateInstance; } // create our new instance override protected function initInstance(instance:IEffectInstance):void { super.initInstance(instance); CustomAnimateInstance(instance).finalAlpha = this.finalAlpha; } override public function getAffectedProperties():Array { return ["alpha"]; } }
The first thing you have to do is provide the effect factory with the name of your effect class. This is done here in the constructor where instanceClass is set. Then you have to set the properties to be animated in the override of initInstance. In this case, I’m only setting the end value finalAlpha. As you’ll see below, this demo effect starts at whatever alpha the target is currently set to.
You could also set multiple properties and animate them all which is where a custom effect could really become useful. Of course, you could also do that with a Parallel or Sequence object. But with a custom effect you have more flexibility to animate whatever you want in whatever way you want. So, for example, you might choose to animate a target object’s alpha value uniformly throughout the effect’s duration but then wait to start animating its color until 50% of the duration has elapsed. Then, you could animate the color change twice as fast during the remaining half the duration. (OK, you could probably do that with a Sequence and a startDelay but you get the idea.)
To complete the two required classes here’s the code for the custom animation:
public class CustomAnimateInstance extends AnimateInstance{ public var finalAlpha:Number = -1; public function CustomAnimateInstance(target:Object) { super(target); } override public function play():void { var motionPath:SimpleMotionPath = new SimpleMotionPath("alpha"); motionPath.valueFrom = (target as DisplayObject).alpha; motionPath.valueTo = finalAlpha == -1 ? 1 : finalAlpha; motionPaths = new Vector.<MotionPath>; motionPaths.push(motionPath); super.play(); } override public function animationUpdate(animation:Animation):void { (target as DisplayObject).alpha = animation.currentValue.alpha as Number; } }
Here, we override a couple of the methods from IAnimationTarget. Most of the code simply creates a SimpleMotionPath which is required by the Animate class. The Animate class calculates the tweened value for you at each frame. Note that the motion path must be created in the play method and not the constructor. This is because the finalAlpha value doesn’t get set until the effect begins to play. That’s when CustomAnimateEffect’s initInstance method is called and that’s where the desired value gets passed in from the client code. And, here’s that client code:
<fx:Declarations> <local:CustomAnimateEffect id="customEffect" finalAlpha="1" target="{btn2}" /> </fx:Declarations> <s:VGroup gap="10" paddingTop="10" paddingLeft="10"> <s:Button label="Click to fade in the button below" click="customEffect.play()"/> <s:Button id="btn2" label="Fade Me In" fontSize="50" alpha="0.2"/> </s:VGroup>
Download the source code for the custom Flex 4 animation effect (fxp).


{ 3 comments… read them below or add one }
Good article! I translated it into Chinese.
http://www.smithfox.com/?e=63
Very Thanks.I have a question that I want to display a custom MovieCilp,can you teach me ? Thanks agin.
Thank You. This is just what I needed.
{ 4 trackbacks }