Skip to main content

[Flex] Custom TweenEffect with Pixel Bender Filter


續前篇。
如果每一次 apply pixel bender 到轉場 effect 都要寫一長串的話實在有點堅強過頭... 要符合懶人精神將常用的 pixel bender filter 效果實作成 TweenEffect 才是明智的選擇。參考了 Flex help 與其他 TweenEffects,以下是簡單客製 TweenEffect 並加上 pixel bender filter 的作法:

每一組 TweenEffect 都由兩個 class 組成: TweenEffectInstance 與 TweenEffect ; 各自有幾個重點 functuon 需要被 override。別忘了先將上篇提到的 CrystallizeShader.as 放到 effects/ 下。

1. 製作 effects/CrystalEffectInstance.as:( 顧名思義就是被作用的實體 )
package effects
{
import flash.display.Shader;
import flash.filters.ShaderFilter;
import mx.effects.Tween;
import mx.effects.effectClasses.TweenEffectInstance;

public class CrystalEffectInstance extends TweenEffectInstance
{
public var sizeTo:Number;
public var sizeFrom:Number;

private var shader:CrystallizeShader = CrystallizeShader.getInstance();

public function CrystalEffectInstance(target:Object)
{
super(target);
}
// Override play() method class.
override public function play():void {
// 一定要有 super.play().
super.play();
sizeFrom = isNaN(sizeFrom) ? 50 : sizeFrom;
sizeTo = isNaN(sizeTo) ? 0 : sizeTo;
var tween:Tween = createTween(this, sizeFrom, sizeTo, duration);
}

// Override onTweenUpdate() method.
override public function onTweenUpdate(val:Object):void {
shader.size = Number(val);
applyFilter();
}
// Override onTweenEnd() method.
override public function onTweenEnd(val:Object):void
{
applyFilter();
super.onTweenEnd(val);
}

private function applyFilter():void{
var filters:Array = target.filters;
for (var i:int = filters.length; i-->0;)
{
if (filters[i] is ShaderFilter)
filters.splice(i, 1);
}
if(shader.size)
filters.push( new ShaderFilter( shader ) );

target.filters = filters;
}
}
}

主要 override play(), onTweenEnd(), onTweenUpdate(),並加上一個 applyFilter 保障其他附加在實體上的 filters 不會被刪掉...=P

2. effects/CrystalEffect.as

package effects
{
import mx.effects.TweenEffect;
import mx.effects.IEffectInstance;

public class CrystalEffect extends TweenEffect
{
public var sizeTo:Number;
public var sizeFrom:Number;

public function CrystalEffect(targetObj:* = null) {
super(targetObj);
instanceClass= CrystalEffectInstance;
}
//override getAffectedProperties()
override public function getAffectedProperties():Array
{
return [ "filters" ];
}
// Override initInstance() method.
override protected function initInstance(inst:IEffectInstance):void {
super.initInstance(inst);
CrystalEffectInstance(inst).sizeFrom = sizeFrom;
CrystalEffectInstance(inst).sizeTo = sizeTo;
}

}
}

繼承 TweenEffect 的寫法有點固定,改寫 initInstance() and getAffectedProperties()

測試:main.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:effect = "effects.*"
layout="horizontal" >
<effect:CrystalEffect sizeFrom="200" duration="500" id="crystal" />
<effect:CrystalEffect sizeFrom="500" sizeTo="10" duration="800" id="crystal1" />
<mx:Panel width="250" height="200" title="Pixel Bender Test"
backgroundColor="#F8F8F8" creationCompleteEffect="crystal" />
<mx:Panel width="250" height="200" title="Pixel Bender Test"
backgroundColor="#F8F8F8" creationCompleteEffect="crystal1" />
</mx:Application>

Comments

Popular posts from this blog

[書評] 拖延心理學:為什麼我老是愛拖延?是與生俱來的壞習慣,還是身不由己?

作者: Jane B. Burka & Lenora M . Yuen 推薦指數 ★★★★★ 有時候,只是想了解事情發生原因而不是尋求解法 在這邊不是要講這本書的內容,而是想聊它對我的影響。