Aborting Flex 2 Effects

The effect classes in Flex 2 have a wonderful new API. In particular, you can pause and rewind the effects as well as access them by id. They do not, however, act like I’d expect when you abort them. For example, I’m building a scrubbable component. You can scroll the slider, and the View it’s attached too will show and hide objects over time, like markers on a map that are date specific.

I want these markers to fade in when they appear, and fade out when they are no longer relevant to the date range. The problem I kept running into is that the effects wouldn’t either finish all the way, or wouldn’t play what I told them too correctly and would just blink in without fading in. In this case, the Fade effect wasn’t always fading correctly. It is a race condition you can easily repeat. You basically just tell one effect to fade something out from 1 alpha to 0 alpha, and another to fade in from alpha 0 to alpha 1. If you call the disappear method before the appear method’s fade effect is done, you can see it’ll either interrupt it and not fade out, or just flash. Really gross looking.

I implemented 2 methods, appear and disappear. It seems that calling fade.stop() is not enough. I tried fade.end(), but that didn’t work either. I also removed the event listener for the end, and then null’d the Fade effect property before creating the new one that did the opposite, but to no avail. I’m guessing that because garbage collection doesn’t run immediately even if I told the effect to stop and removed all pointers to it, the effect still held onto the applicable properties of the UIComponent it was affecting. I’m sure I could open up the classes and look, but I don’t really have time; on a tight deadline. Best excuse I have, anyway.

Suffice it to say, fade.pause() did the trick. For some reason, this particular method, as opposed to stop, or end, allows another effect to override the properties the original one had set, and continue on. Seems trivial, but to get fast, good looking transitions and visuals, this took me an hour to figure out. Blogging so others don’t have to spend that time.

Example code:

public override function disappear():void
{
        if(__fadeIn != null)
        {
                __fadeIn.removeEventListener(EffectEvent.EFFECT_END, onFadeInDone);
                __fadeIn.pause(); // magic method!
                __fadeIn = null;
        }
        
        if(__fadeOut == null)
        {
                __fadeOut = new Fade(this);
                __fadeOut.duration = fadeOutSpeed;
                __fadeOut.alphaFrom = alpha;
                __fadeOut.alphaTo = 0;
                __fadeOut.addEventListener(EffectEvent.EFFECT_END, onFadeOutDone);
                __fadeOut.play();
        }
}

5 Replies to “Aborting Flex 2 Effects”

  1. Maybe I’m missing something, but I’m not sure why your taking this apporach. You can just check the isPlaying property, and if its is playing invoked reverse(). If it aint playing, set the alphaTo, and play the effect.

    <mx:Script>
       <![CDATA[

    private function set show( value:Boolean ):void
    {
            if( myFade.isPlaying )
            {
                    myFade.reverse();
            }
            else
            {
                    myFade.xTo = ( value ) ? 100 : 0;
                    myFade.play();
            }
    }
    

       ]]>
    </mx:Script>

    <mx:Fade id=’myFade’ target='{myComponent}’ duration=’500’/>

  2. You’re not missing anything Tink. I have a deadline of Friday, am coding at mach-2 with little regard to optimization, and haven’t had anyone take a look at my code. So, thanks for taking the time to do so!

  3. Just a side note if anyone else comes here looking to basically send any effects to a screaming halt. If you have two effects one for fadeIn and one for fade Out, when you are setting the visibilities of the component most can call .endEffectsStarted() which will end any current effects and begin the new ones.

Comments are closed.