Aviar
Aviar

Reputation: 1

Glow filter alpha does not cycle

    public function pulse(obj:DisplayObject, glow:GlowFilter):void
    {
        obj.filters = [glow];
        obj.addEventListener(Event.ENTER_FRAME, function():void { 
            if(glow.alpha >= 1)
                glow.alpha -= 0.05;
            else if(glow.alpha <= 0)
                glow.alpha += 0.05;
            else
                glow.alpha -= 0.5;
            obj.filters = [glow];
        });
    }

The glow filters alpha cycles once halfway (drops from one to zero), but never goes back up. I understand that it has to do with the midrange values (between 0 and 1) but I cannot think of an elegant solution. Even when using two whiles (one for above zero, another for below), it still only cycles halfway. How can I solve this.

Upvotes: 0

Views: 830

Answers (2)

CrociDB
CrociDB

Reputation: 1234

You decrease 0.05 from the alpha when it's greater (or equals to) than 1. When it's between 0 and 1, you still decrease (the final else). When it's less than (or equals to) 0, you increase 0.05. But, look, when it's 0 again, you will decrease, and then it will be less than 0, so you will increase. At this point you won't see the element anymore. :P

Try using the TweenMax library. You can get this effect with one line of code, or maybe two. If you still want to do that this way, use a boolean var, when it's 0, turn that boolean to true. As this boolean is true, you increase the alpha value. When the alpha value is 1, you make the boolean false and decrease the alpha as it's false. :)

Upvotes: 0

sberry
sberry

Reputation: 132098

Think about what is going on here....

First time the glow comes in, I assume the alpha is 1. If not, my explanation is a little off, but pretty close.

  1. So, alpha is 1. Your first if statement, if(glow.alpha >= 1) is true. So, subtract off 0.05, apply the filter and repeat.
  2. alpha is now 0.95. That is not >= 1, and it is not <= 0. So the final else runs, glow.alpha -= 0.5. And the loop repeats.
  3. alpha is now 0.45. Same situation as in number 2 above. So glow.alpha -= 0.5 runs again. And repeat.
  4. alpha is now -0.05. Now your else if runs, adding 0.05. So alpha is now at 0. Repeat.
  5. Same thing happens as in number 4. Now alpha is 0.05.
  6. Now we are back to the else. Subtracting off 0.5. Leaving us at -0.45.
  7. The loop is now in a state where is will continue add 0.05 until it reaches +0.05, then will go back down to -0.45.

Doing it your way, I would take a slightly different approach.

Make a new .fla, make this the DocumentClass and run it.

package  {

    import flash.display.MovieClip;
    import flash.display.DisplayObject;
    import flash.filters.GlowFilter;
    import flash.events.Event;
    import flash.display.Sprite;

    public class GlowTest extends MovieClip {

        public var filter:GlowFilter;
        public var target:Sprite;
        public var pulseDown:Boolean = true;
        private var _glowTarget:DisplayObject;

        public function GlowTest() {

            target = new Sprite();
            target.graphics.beginFill(int(Math.random() * 0xFFFFFF), 1);
            target.graphics.drawCircle(0, 0, int(Math.random() * 200));
            target.graphics.endFill();
            target.x = int(Math.random() * stage.stageWidth);
            target.y = int(Math.random() * stage.stageHeight);
            addChild(target);

            // constructor code
            var color:Number = 0x33CCFF;
            var alpha:Number = 0.8;
            var blurX:Number = 35;
            var blurY:Number = 35;
            var strength:Number = 2;
            var inner:Boolean = false;
            var knockout:Boolean = false;
            var quality = 1;
            //var quality:Number = BitmapFilterQuality.HIGH;

            filter = new GlowFilter(color, alpha, blurX, blurY, strength, quality, inner, knockout);
            startPulse(target, filter);

        }

        public function startPulse(obj:DisplayObject, glow:GlowFilter):void {
            _glowTarget = obj;
            _glowTarget.filters = [glow];
            _glowTarget.addEventListener(Event.ENTER_FRAME, pulse);
        }

        public function pulse($evt:Event):void {
            if (pulseDown) {
                filter.alpha -= 0.05;
            } else {
                filter.alpha += 0.05;
            }
            if (filter.alpha >= 1) {
                filter.alpha = 1;
                pulseDown = true;
            } else if (filter.alpha <= 0) {
                filter.alpha = 0;
                pulseDown = false;
            }
            _glowTarget.filters = [filter];
        }
    }
}

However, I wouldn't even do it that way. I would suggest using a library for doing this Tween, such as TweenLite/TweenMax. http://www.greensock.com/tweenmax/

The code to do it in one direction would look similar to this:

import com.greensock.*;
import com.greensock.plugins.*;
TweenPlugin.activate([TintPlugin]);

var glowEffect:TweenMax = new TweenMax(mc,0,{glowFilter:{color:0x330000,alpha:1,blurX:5,blurY:5,str ength:2,quality:2,overwrite:5}});

The you would just have to alternate doing the tween. You could even use the onComplete of the glowEffect Tween to trigger it in the opposite direction.

If you wanted more terse code, you could change the pulse function to this:

public function pulse($evt:Event):void {
    filter.alpha += pulseDown ? -0.05 : 0.05;
    if (filter.alpha >= 1 || filter.alpha <= 0) {
        filter.alpha = Math.round(filter.alpha);
        pulseDown = !pulseDown;
    }
    _glowTarget.filters = [filter];
}

Upvotes: 2

Related Questions