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

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

Return to page top