Flexのカスタムエフェクト

Flexでカスタムエフェクトを作成する場合、お約束があります。


カスタムエフェクトの作成について


いろいろ書いてありますが要するに以下の2つ、ファクトリクラスとインスタンスクラスを用意します。

カスタムエフェクトを定義するには、ファクトリクラスとインスタンスクラスの 2 つのクラスを作成します。

ファクトリクラスは、インスタンスクラスのオブジェクトを作成し、そのターゲット上でエフェクトを実行します。アプリケーション内でファクトリクラスインスタンスを作成し、ズームサイズやエフェクトの持続時間など、エフェクトを制御するために必要なプロパティをそのインスタンスに設定します。その後、次の例に示すように、ファクトリクラスインスタンスを、対象のコンポーネントのエフェクトトリガに割り当てます。慣例では、ファクトリクラスの名前は Zoom または Fade などのエフェクトの名前になります。

インスタンスクラスは、エフェクトロジックを実装します。エフェクトトリガが実行されるか、ユーザーが play() メソッドを呼び出してエフェクトを起動すると、ファクトリクラスによりインスタンスクラスのオブジェクトが作成され、そのターゲット上でエフェクトが実行されます。エフェクトの再生が終了すると、Flex によりインスタンスオブジェクトが破棄されます。エフェクトの対象となるコンポーネントが複数ある場合には、ファクトリクラスは対象ごとに 1 つずつ複数のインスタンスオブジェクトを作成します。

この2つ、どうやって使うというと、基本的にエフェクトをかけたいコンポーネントに対してファクトリクラスを指定し、ファクトリクラスは指定されたインスタンスクラスを参照する、という流れになります。なので乱暴に言えば

  • ファクトリクラス
    • プロパティの設定などを受け持つクラス
  • インスタンスクラス
    • 実処理を実装するクラス

となるのかな。サンプルを見てみましょう。

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

  public class MyEffect extends TweenEffect
  {
    public var angleFrom:Number;
    public var angleTo:Number;

    public function MyEffect(target:Object=null)
    {
      super(target);
      instanceClass = MyEffectInstance; // (1)
    }

    override protected function initInstance(instance:IEffectInstance):void // (2)
    {
      super.initInstance(instance);
      MyEffectInstance(instance).angleFrom = this.angleFrom;
      MyEffectInstance(instance).angleTo = this.angleTo;
      MyEffectInstance(instance).duration = this.duration;
    }	
  }
}

まずファクトリクラスです。ここにエフェクトに対するプロパティを設定できるようにpublicな変数を宣言したりします。(1)でこのファクトリクラスを受け持つインスタンスクラスを登録します。initInstanceはoverrideしてsuper.initInstance(instance)を実行しておきます。その上で設定されたプロパティを渡したりします。

次にインスタンスクラスです。

package
{
  import mx.effects.effectClasses.TweenEffectInstance;

  public class MyEffectInstance extends TweenEffectInstance
  {
    public var angleFrom:Number;
    public var angleTo:Number;

    public function MyEffectInstance(target:Object)
    {
      super(target);
    }

    override public function play():void
    {
      super.play();
      createTween(this, angleFrom, angleTo, duration);
    }

    override public function onTweenUpdate(value:Object):void
    {
      target.rotation = value;
    }

    override public function onTweenEnd(value:Object):void
    {
      super.onTweenEnd(value);
    }
  }
}

インスタンスクラスでは以下の3つのメソッドをoverrideします。

  • play()
  • onTweenUpdate()
  • onTweenEnd()

play()の中でcreateTweenしてプロパティの値を設定してます。非常に簡単ですがカスタムエフェクトの一番簡単な例はこれで動いてしまいます。


さて、実際にこのエフェクトをどうやって使うか?ということになりますがMXML上で使う場合は簡単です。まずファクトリクラスのコンポーネントを登録して、それをエフェクトをかけたいコンポーネントのmouseDownEffectトリガに作成したファクトリクラスを指定してやればOKです。

<local:MyEffect id="test01" angleFrom="0" angleTo="360" duration="10000"/>
<mx:Button label="Click Me" width="100" height="100" mouseDownEffect="{test01}"/>

実際にはActionscript上でコンポーネントのトリガにエフェクトを登録することも可能です。

var _effect:MyEffect = new MyEffect();
var _button:Button = new Button();

_button.setStyle('mouseDownEffect', _effect);