辉光滤镜 alpha 不循环

发布于 2024-12-02 15:51:10 字数 579 浏览 1 评论 0原文

    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];
        });
    }

辉光滤镜 Alpha 循环一次到一半(从 1 下降到 0),但永远不会恢复。我知道这与中间值(0 和 1 之间)有关,但我想不出一个优雅的解决方案。即使使用两个 while(一个用于高于零,另一个用于低于零),它仍然只循环一半。我该如何解决这个问题。

    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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南城旧梦 2024-12-09 15:51:10

想想这里发生了什么......

第一次发光时,我假设 alpha 为 1。如果不是,我的解释有点偏离,但非常接近。

  1. 因此,alpha 为 1。您的第一个 if 语句 if(glow.alpha >= 1) 为 true。因此,减去 0.05,应用过滤器并重复。
  2. 阿尔法现在为 0.95。这不是 >= 1,也不是 <= 0。因此最后的 else 运行,glow.alpha -= 0.5。并且循环重复。
  3. 阿尔法现在为 0.45。与上面第 2 条的情况相同。因此,glow.alpha -= 0.5 再次运行。并重复。
  4. 阿尔法现在是-0.05。现在您的 else if 运行,添加 0.05。所以 alpha 现在为 0。重复。
  5. 与数字 4 中发生的情况相同。现在 alpha 为 0.05。
  6. 现在我们回到else。减去0.5。剩下-0.45。
  7. 循环现在处于这样的状态:将继续添加 0.05,直到达到 +0.05,然后返回到 -0.45。

按照你的方式去做,我会采取稍微不同的方法。

创建一个新的 .fla,将其设为 DocumentClass 并运行它。

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];
        }
    }
}

然而,我什至不会那样做。我建议使用一个库来执行此 Tween,例如 TweenLite/TweenMax。 http://www.greensock.com/tweenmax/

在一个方向上执行此操作的代码看起来像与此类似:

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}});

您只需交替进行补间即可。您甚至可以使用glowEffect Tween 的onComplete 在相反方向触发它。

如果您想要更简洁的代码,您可以将脉冲函数更改为:

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];
}

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];
}
森林迷了鹿 2024-12-09 15:51:10

当 alpha 大于(或等于)1 时,您会从 alpha 上减少 0.05。当它在 0 和 1 之间时,您仍然会减少(最后的 else)。当它小于(或等于)0 时,增加 0.05。但是,你看,当它再次为0时,你会减少,然后它会小于0,所以你会增加。此时您将不再看到该元素。 :P

尝试使用 TweenMax 库。您可以通过一行或两行代码获得此效果。如果您仍然想这样做,请使用布尔变量,当它为 0 时,将该布尔值转换为 true。由于该布尔值为 true,因此您可以增加 alpha 值。当 alpha 值为 1 时,您将布尔值设置为 false,并减少 alpha,因为它是 false。 :)

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. :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文