2009年09月07日
AS3.0 で光るテキスト効果を作ってみた
TVCM とか映画予告編などでよく見かける「文字が左から右に光るエフェクト」を ActionScript 3.0 で作ってみた。
完成品はこんな具合。
文字を編集することもできる。編集後の文字ですぐに光り始める!
やってること
- TextField を表示
- TextField を BitmapData に表示して、GlowFitler で光らせる (
bmpGlow
) - 円形のマスク Sprite を用意 (
msk
)。周りに行くに従って透明になるようにしておく。 - 2. で作った
bmpGlow
に 3. のマスクmsk
を適用する。マスクを徐々に右に移動していけば、光ってるところが移動しているように見える。
苦労したのはグラデーションのマスクを適用させるところ。マスクとマスクされる DisplayObject
の両方の cacheAsBitmap
プロパティを true
に設定しておく必要がある。
当初、それに気付かずに、copyPixel()
を使って泥臭く実装していたんだけど、cacheAsBitmap すればアルファの Sprite で透明度を利用したマスクを作れることを教えてもらった。cacheAsBitmap
を使って 書き直したら、10行短くなって、ソースコードも素直になって万歳。
ソースコードは以下に(73行)。
// Glowing Hellow World revised. (lines: 83 -> 73) //------------------------------------------------------- // An experiment on creating a dynamic glow text effect. // You can edit the text!!! package{ import flash.display.*; import flash.events.Event; import flash.filters.GlowFilter; import flash.geom.*; import flash.text.*; [SWF(backgroundColor="#000000", width="450", height="80")] public class GlowingHelloWorld extends Sprite{ public function GlowingHelloWorld(){ stage.scaleMode = "noScale"; var ptZero:Point = new Point(); // initialize canvas. var bmpGlow:Bitmap = addChild(new Bitmap()) as Bitmap; // Show original text (input) var text:TextField = new TextField(); text.autoSize = "left"; text.type = "input"; text.htmlText = <font size="50" color="#ffffff">HELLO WORLD</font>.toXMLString(); addChild(text); text.addEventListener("change", function(event:Event):void{ updateGlow() }); // Create a glow BitmapData. var bmdGlow:BitmapData, bmdCanvas:BitmapData; var updateGlow:Function = function():void{ // dispose existing BitmapData. if (bmdGlow) bmdGlow.dispose(); // Glow it. bmdGlow = new BitmapData(text.textWidth + 10, text.textHeight + 10, true, 0);; bmdGlow.draw(text); var glow:GlowFilter = new GlowFilter(0xffffff, .9, 8, 8, 4); bmdGlow.applyFilter(bmdGlow, bmdGlow.rect, ptZero, glow); // Update canvas BitmapData. bmpGlow.bitmapData = bmdGlow; } updateGlow(); // Create a mask sprite. var msk:Sprite = new Sprite(); msk.graphics.beginGradientFill("radial", [0xffffff, 0xffffff], [1, 0], [64, 255]); msk.graphics.drawCircle(0, 0, 100); msk.graphics.endFill(); addChild(msk); // Set mask. msk.y = 50 - text.textHeight / 2; bmpGlow.cacheAsBitmap = msk.cacheAsBitmap = true; bmpGlow.mask = msk; // Start animation loop. var counter:int = 0; addEventListener("enterFrame", function(event:Event):void{ // move the mask msk.x = counter; // update counter... counter += 14; if (counter > 800){ counter = -10; } }); } } }