反射表現できるクラスを作ってみました

reflection.jpg

3D変形ができるカスタムクラス、Sandyの練習として、FlashでiTunesのCover Flow表現を再現してみようかと思いました。今夜は準備段階として、反射(反映)表現を簡単に設定できるクラス、Reflection.asを作ってみました。ステージ上にムービークリップを置いて、コード1行で反射します。反射の度合いも調節できます。このクラスはすぐにできたのですが、まだ課題が1個残っています。(詳細は文末で。)

BitmapData処理の勉強にお役に立てるかもしれませんので、ソースファイルとクラスをダウンロードできるようにしておきますが、どんどん手直ししていく予感なので、本気で使っていただける方は、全部できてからでも良いかと思います。

追記:反射はアルファで表現してはいけないということに気づきました。この記事のソースには不備がありますのでご注意ください。

reflection.zip(85KB): flash8形式

CAUTION! My idea about a reflection had made a mistake. Because of this reason, this source is not correct.

今回は動きはありませんが、一応swfも掲載しておきます。

reflection.swf

クラスファイルのReflection.asは次のようになります。一丁前にcom.trick7.effectsディレクトリを作ってカスタムクラス化してます。

内容としてはコンストラクタのパラメーターとして受け取ったムービークリップインスタンスを、BitmapDataとしてキャプチャ、別途グラデーションを作り、それを使ってcopyChannelでじわじわ薄れていくビットマップを合成。できたビットマップを反射用の空ムービークリップreflectionに貼り付けます。reflection全体の透明度は冒頭のreflectionAlphaで設定します。(←これは外に出した方がいいかな?)



01| import flash.display.BitmapData;
02| import flash.geom.Matrix;
03| import flash.geom.Point;
04| import flash.geom.Rectangle;
05| class com.trick7.effects.Reflection {
06|     //SETTINGS--------------------------------
07|     var reflectionAlpha:Number = 50;
08|     //PROPERTIES------------------------------
09|     var reflection:MovieClip;
10|     public var orgHeight:Number;
11|     //CONSTRUCTOR-----------------------------
12|     function Reflection(target:MovieClip, strength:Number) {
13|         orgHeight = target._height; //preserve as a getter for Sandy transform.
14|         if (strength<1) {
15|             trace("2nd parameter should be 1 or higher.");
16|         }
17|         reflection = target.createEmptyMovieClip("reflection", 1);
18|         var refMax:Number = target._height/strength;
19|         //make a base bitmap.
20|         var m:Matrix = new Matrix();
21|         m.scale(1, -1);
22|         m.translate(0, target._height);
23|         var reflectionBitmap = new BitmapData(target._width, refMax, true, 0x000000);
24|         reflectionBitmap.draw(target, m);
25|         //set mask
26|         var maskMc:MovieClip = reflection.createEmptyMovieClip("maskMc", 1);
27|         var colors = [0x000000, 0xFFFFFF];
28|         var alphas = [100, 0];
29|         var ratios = [0, 0xff/strength];
30|         var matrix = {matrixType:"box", x:0, y:0, w:target._width, h:refMax, r:(90/180)*Math.PI};
31|         maskMc.beginGradientFill("linear", colors, alphas, ratios, matrix);
32|         maskMc.moveTo(0, 0);
33|         maskMc.lineTo(target._width, 0);
34|         maskMc.lineTo(target._width, refMax);
35|         maskMc.lineTo(0, refMax);
36|         maskMc.lineTo(0, 0);
37|         maskMc.endFill();
38|         var maskBitmap = new BitmapData(target._width, refMax, true, 0x000000);
39|         maskBitmap.draw(maskMc);
40|         /////CAUTION! This part needs "reflectionBitmap*maskBitmap's alphaImage" as a sourceBitmap! maybe..
41|         reflectionBitmap.copyChannel(maskBitmap, reflectionBitmap.rectanglenew Point(), 8, 8);
42|         maskBitmap.dispose();
43|         //attach final bitmap and replace "maskMc"
44|         reflection.attachBitmap(reflectionBitmap, 1);
45|         reflection._alpha = reflectionAlpha;
46|         reflection._y = target._height;
47|     }
48| }
49| 

fla側は、反射させたいムービークリップ(ここではインスタンス名image)を置き、フレームスクリプトに次のように記述します。

import com.trick7.effects.Reflection;
var ref = new Reflection(image, 1.5);

第2パラメーターで、反射の度合いを設定できます。1以上から4ぐらいまでで設定可能で1の時に反射は最大で、4ぐらいだとほとんど見えないぐらいです。再描画領域のことも考えると1.5~2.5ぐらいがおすすめです。複数個のMCにも対応してます。

とまぁここまで書いておいてなんですが、ひとつ問題が残っておりまして、現状だとムービークリップが矩形(長方形)の時にしか使えないんです。興味のある方は、ステージ上で太目のブラシで適当に描画したものをMCにしてReflectionしてみて下さい。アルファで抜けるべき場所が抜けてません。対応策はおそらく、クラスファイルの41行目のcopyChannelでマスクのソースビットマップとして、reflectionBitmapとmaskBitmapの論理積を渡せば良さそうなのですが、求め方が見つかりませんでした。何かメソッドがあったような気がしたのですが。

あまり資料を見ずに作った上、結構ビットマップとかアルファマスクを使ってますが、パフォーマンスの検証はしてません。パッと見のご意見でもいいので、disposeとかcacheAsBitmapとか、その他の簡略化とかで、もっと軽くなったりする方法をご存知の方がおられましたら、ヒントだけでも教えていただければ幸せです。

Comments:2

ktd 06-12-31 (日) 19:38

はじめまして。
最近Flash関連の勉強の記録としてBlogを作成しまいた、ktdと申します。このたびtrick7様のReflection.asを参考に記事を書かせていただきました。何か問題ありましたら、削除・修正等致しますのでよろしくお願いします。

http://www.ktdktd.com/blog/2006/12/apple_front_row.html

tera 06-12-31 (日) 23:15

>>ktd様
はじめまして。当ブログをご覧頂きありがとうございます。
当方の公開中のReflection.asですが、アプローチが間違えていたので現在修正中ですが、現状のでもよろしければ、ご自由にお使い下さいませ。
今後ともよろしくお願い致します。

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://www.trick7.com/blog/2006/12/19-221801.php/trackback
Listed below are links to weblogs that reference
反射表現できるクラスを作ってみました from trick7
AS3習得本
AS3の全容を学習できる本。この中でどれか1冊自分に合ったものを。
Adobe Flash CS4 詳細!ActionScript3.0入門ノート ActionScript3.0 プロフェッショナルガイド 初めてのActionScript 3.0 Flashユーザーのためのステップアップガイド 詳説 ActionScript 3.0 Actionscript 3.0 Cookbook
AS3発展本
ASでアニメーションさせる面白さを知るための本。
Flash Math & Physics Design:ActionScript 3.0による数学・物理学表現[入門編] ActionScript 3.0 アニメーション AdvancED ActionScript 3.0 Animation (Advanced)
AS2
"Flash"ではなく"ActionScript2.0"学習のための良著。他にもいろいろ読んだけど、この4冊を読んだ後、自分が成長できた感じがしました。
FLASH ActionScript 2.0入門完全ガイド+実践サンプル集 [CD-ROM付] Essential Actionscript 2.0 Flash 8 Essentials Foundation Actionscript Animation: Making Things Move (Foundation)

あわせて読みたいブログパーツ

相互リンク

hi-posiさん
携帯Flashといえばhi-posiの岡田昇三さん。FlashLiteの有益な記事もたくさん書かれていていつもお世話になってます。ついにご挨拶させていただきました。面白すぎる人でしたw。

Return to page top