1.21 gigawatts
1.21 gigawatts

Reputation: 17760

How to have a glow filter in Spark

In Flex 3 you could do a glow effect like so:

    <mx:Glow id="glowImage" duration="250"
             alphaFrom="0" alphaTo="1"
             blurXFrom="0.0" blurXTo="3.0"
             blurYFrom="0.0" blurYTo="3.0" strength="2"
             color="0xcc0000" target="{this}"/>

    <mx:Glow id="unglowImage" duration="250"
             alphaFrom="1" alphaTo="0"
             blurXFrom="3.0" blurXTo="0.0"
             blurYFrom="3.0" blurYTo="0.0" strength="2"
             color="0xaaaaaa" target="{this}"/>

And the MXML:

<mx:Image rollOverEffect="{glowImage}" rollOutEffect="{unglowImage}"/>

In Flex 4 we are supposed to use the AnimateFilter with a GlowFilter (recommended by Adobe). Here's what I've come up with:

    <s:AnimateFilter id="glowAnimation" 
                     target="{this}"
                     duration="250"
                     >

        <s:bitmapFilter>
            <s:GlowFilter color="#ff0000" strength="3" quality="3" />
        </s:bitmapFilter>

        <s:motionPaths>
            <s:SimpleMotionPath valueFrom="0" valueTo="4" property="blurX"/>
            <s:SimpleMotionPath valueFrom="0" valueTo="4" property="blurY"/>
        </s:motionPaths>

    </s:AnimateFilter>

And the MXML:

<mx:Image rollOverEffect="{glowAnimation}" rollOutEffect="{unglowImage}"/>

The problem is that this animates once and then the effect is removed where as the mx effect applies the filter and keeps it applied.

~~~ UPDATE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RIAStar's answer is right and I want to add the reason why from this video I just stumbled upon [1]. It describes the differences between Animate and AnimateFilter. AnimateFilter is transient. It applies the filter and when it's done it removes it. Animate applies the values to the target permanently.

We also should be aware that in Flex 4 not all effects support triggers.

From the AnimateInstance class:

override public function startEffect():void
{  
    // This override removes EffectManager.effectStarted() to avoid use of
    // mx_internal. New effects are not currently triggerable, so
    // this should not matter
}  

What this means is that we cannot rely on rollOverEffect to trigger the effect bound to it. We must call effect.play() on the rollOver event.

So that means when we use the Animate class we also need to change this:

<s:Image rollOverEffect="{glowImage}" rollOutEffect="{unglowImage}"/>

to this:

<s:Image rollOver="glowImage.play()" rollOut="unglowImage.play()"/>

Note when using multiple related effects it is best practice to call end() on a playing effect before calling play() on it's related effect.

Also, note when using a single effect, as in the answer, reverse it rather than end it like so glowAnimation.play(null, true).

<s:Image rollOver="rollOverAnimation.play()" rollOut="rollOverAnimation.play(null, true)"/>

Upvotes: 1

Views: 2363

Answers (2)

Dmitriy Klimov
Dmitriy Klimov

Reputation: 1

I use transitions for effect switching within SparkSkin. For bluring a skinned item under cursor:

<!-- states -->
<s:states>
    <s:State name="up" />
    <s:State name="over" />
    <s:State name="down" />
    <s:State name="disabled" />
</s:states> 

<fx:Declarations>       
    <s:BlurFilter id="aBlurFilter" blurX="0" blurY="0" blurX.over="10" blurY.over="10" quality="{BitmapFilterQuality.HIGH}"  />     
</fx:Declarations>

<s:transitions>  
    <s:Transition fromState="*" toState="over">

            <s:Animate id="BlurFilterTo" 
                target="{aBlurFilter}"
                repeatCount="1"
                duration="500"
                repeatBehavior="reverse"
                >
                <s:SimpleMotionPath property="blurX" valueFrom="0" valueTo="10"/>
                <s:SimpleMotionPath property="blurY" valueFrom="0" valueTo="10"/>
            </s:Animate>

    </s:Transition> 

    <s:Transition fromState="over" toState="*">

            <s:Animate id="BlurFilterFrom" 
                target="{aBlurFilter}"
                repeatCount="1"
                duration="500"
                repeatBehavior="reverse"
                >
                <s:SimpleMotionPath property="blurX" valueFrom="10" valueTo="0"/>
                <s:SimpleMotionPath property="blurY" valueFrom="10" valueTo="0"/>
            </s:Animate>

    </s:Transition> 

</s:transitions> 

<s:BitmapImage id="iconDisplay" filters="{[aBlurFilter]}" />

Upvotes: 0

RIAstar
RIAstar

Reputation: 11912

I don't know about AnimateFilter, but this solution using a simple Animate effect should work nicely:

<s:Animate id="glowAnimation" target="{glow}" duration="250">
    <s:motionPaths>
        <s:SimpleMotionPath valueFrom="0" valueTo="10" property="blurX"/>
        <s:SimpleMotionPath valueFrom="0" valueTo="10" property="blurY"/>
    </s:motionPaths>
</s:Animate>

<s:Image rollOver="glowAnimation.play()" 
         rollOut="glowAnimation.play(null, true)">

    <s:filters>
        <s:GlowFilter id="glow" blurX="0" blurY="0" />
    </s:filters>
</s:Image>

Note that I set the initial values of blurX and blurY to 0. This is necessary because otherwise it will display the default 4 as long as you don't roll over the image.

Upvotes: 4

Related Questions