Quality Glow and Blur Flex effects
The Glow and Blur effects are useful tweens that can be used to animate flash filters in Flex, the only problem is they don’t implement the quality property. It’s hard coded at a value of 1. In most cases this isn’t an issue, and where performance is concerned it’s best left unchanged. But having the extra control doesn’t hurt, especially considering a quality of even 2 or 4 can dramatically increase the smoothness a filter.
This shows the difference between a Glow effect with a quality of 4 and 1. As you can see the quality glow is far smoother. Adding the quality property onto Flex effects is quite simple, although it does require overriding two of the effect classes and duplicating a small amount of code.
Effect and EffectInstance
All Flex effects consist of subclasses of Effect and an EffectInstance. In the case of glow this is Glow and GlowInstance. Glow contains the properties and targets of the effect, and GlowInstance applies the actual filter. You need to subclass these and add the quality property to both:
{
import mx.effects.Glow;
import mx.effects.IEffectInstance;
public class QualityGlow extends Glow
{
// Add the quality property
[Inspectable(category=“General”, defaultValue=“1″)]
public var quality:Number;
public function QualityGlow(target:Object=null)
{
super(target);
// Our new class that applies the filter
instanceClass = QualityGlowInstance;
}
override protected function initInstance(instance:IEffectInstance):void
{
super.initInstance(instance);
QualityGlowInstance(instance).quality = quality;
}
}
}
Here I’ve added the ‘quality’ property and tagged it with Inspectable metadata, which ensures it’s available in MXML. Also, instanceClass is set to our new version of QualityGlowInstance, a new class which makes sure the underlying GlowFilter uses the property ‘quality’ in it’s constructor.
{
import flash.filters.GlowFilter;
import mx.effects.effectClasses.GlowInstance;
public class QualityGlowInstance extends GlowInstance
{
public var quality:Number;
public function QualityGlowInstance(target:Object)
{
super(target);
}
override public function onTweenUpdate(value:Object):void
{
setQualityGlowFilter(value[0], value[1], value[2], value[3]);
}
override public function onTweenEnd(value:Object):void
{
setQualityGlowFilter(value[0], value[1], value[2], value[3]);
super.onTweenEnd(value);
}
// setGlowFilter() is private in the superclass
// so we duplicate it’s functionality here:
protected function setQualityGlowFilter(color:uint, alpha:Number, blurX:Number, blurY:Number):void
{
var filters:Array = target.filters;
// Remove any existing Glow filters
var n:int = filters.length;
for (var i:int = 0; i < n; i++)
{
if (filters[i] is GlowFilter)
filters.splice(i, 1);
}
// Add quality property to GlowFilter:
if (blurX || blurY || alpha)
filters.push(new GlowFilter(color, alpha, blurX, blurY, strength, quality, inner, knockout));
target.filters = filters;
}
}
}
Apologies for the length of this class, but some code needed to be duplicated from the superclass. A common problem with the Flex framework is private methods, which means you cannot override them in a subclass. In this case setGlowFilter was the culprit, and in order change it’s functionality I had to duplicate the contents and change any references made elsewhere. This explains why the two onTween* methods are overridden.
Identical changes can be made to the Blur effect to get the quality property working, or simply download all the classes below.
Download source code here: qualityflexeffects.zip
Posted: November 4th, 2008 under Flex.