- 2009-04-15 (Wed) 00:25
- Flash/Flex
Adobeのドキュメントで MaskEffect の仕様を調べる。
MaskEffect - ActionScript 3.0 言語およびコンポーネントリファレンス
どうやらターゲットコンポーネントに対して、文字通りマスクとなる矩形を表示して部分的に隠し、そのマスクを時間の経過とともに移動したり拡大/縮小したりして様々なエフェクトを実現する、というものだった。
後日、いろいろ格闘して↑は少し違うことに気づいた。「矩形で隠す」のではなく、「矩形以外を隠す」なのだ。 つまり、のぞき穴からのぞき込んでいる状態だ。
実装するのは大きくわけると以下の3つになるようだ。
- マスクとして使用される Sape オブジェクトを作成するメソッド
- マスクの拡大/縮小率の From, To の指定
- マスクの移動元/移動先の指定
読んでみたがよく分からない。 こういうときは似たサンプルを探す。
ってことでほぼ同じ処理(というかもっと高級な処理)を実現している mx.effects.WipeDown クラスのソースコードを見て作った。
MaskSample1Effect
package
{
import mx.effects.IEffectInstance;
import mx.effects.MaskEffect;
public class MaskSample1Effect extends MaskEffect
{
public function MaskSample1Effect(target:Object=null)
{
super(target);
instanceClass = MaskSample1EffectInstance;
}
override protected function initInstance(inst:IEffectInstance):void{
super.initInstance(inst);
MaskSample1EffectInstance(inst).createMaskFunction = MaskSample1EffectInstance(inst).createMask;
}
}
}
MaskSample1EffectInstance
package
{
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.Shape;
import flash.geom.Rectangle;
import mx.core.FlexShape;
import mx.effects.effectClasses.MaskEffectInstance;
public class MaskSample1EffectInstance extends MaskEffectInstance
{
private var sx:Number;
private var sy:Number;
public function MaskSample1EffectInstance(target:Object)
{
super(target);
}
override protected function initMaskEffect():void{
super.initMaskEffect();
xFrom = this.sx;
yFrom = this.sy;
xTo = -this.sx;
yTo = -this.sy;
}
public function createMask(targ:Object, bounds:Rectangle):Shape{
var newMask:Shape = new FlexShape();
var angle:Number = Math.atan2(bounds.height, bounds.width);
var cos:Number = Math.cos(angle);
var sin:Number = Math.sin(angle);
var targetWidth:Number = bounds.width / cos;
var targetHeight:Number = cos * bounds.height + sin * bounds.width;
var g:Graphics = newMask.graphics;
g.beginFill(0xFFFF00);
g.drawRect(0, 0, targetWidth, targetHeight);
g.endFill();
newMask.rotation = angle * 180 / Math.PI;
sx = sin * sin * bounds.width;
sy = - sin * cos * bounds.width;
return newMask;
}
override public function finishEffect():void{
super.finishEffect();
DisplayObject(target).visible = false;
}
}
}
ほとんど WipeDown クラスからコード持ってきて、余計な部分や今の理解に必要のない部分を消去した。 そして、矩形を斜めにして右上から消えていくようにした。
MaskSample1Effect クラスは何もしていない。作っただけ。
MaskSample1EffectInstance クラスでは以下の2つのことをしている。
- initMaskEffect メソッドでマスクの移動元と移動先の (x, y) 座標をセットする。
- finishEffect メソッドでエフェクト終了後にオブジェクトを見えなくする。
ポイントは以下の部分だけ。
xFrom = (マスク移動元のx座標)
yFrom = (マスク移動元のy座標)
xTo = (マスク移動先のx座標)
yTo = (マスク移動先のy座標)
マスクの移動元と、移動先の (x, y) 座標を指定するだけで勝手に動いてくれる。 その他はマスクを斜めに向けたり、斜めのマスクが全体をスッポリと覆えるように大きさを調整したりしただけ。
できた。
文字の消え方がおかしいことを除けば今はこれくらいでいい。 厳密には消える対象のオブジェクトが回転とか拡大・縮小されてもちゃんと動作するようにしなければならない。 (WipeDown はそうなってた。) けど、今はそこまでやる段階ではないからいいっしょ。
関連するエントリー [Flex] カスタムエフェクトの作成 #5
トラックバック:No Trackbacks
- トラックバック URL
- http://blog.garden-place.jp/action.php?action=plugin&name=TrackBack&tb_id=247
- Listed below are links to weblogs that reference
- [Flex]カスタムエフェクトの作成 #5 - MaskEffectの継承1 from Web 酒 肴