スポンサーサイト

-------- | --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[ActionScript 3.0] DisplacementMapFilterで立体効果

2007-12-07 | 22:26

↓のウィンドウでマウスを動かすと文字が球面上を動きます。

package {
        import flash.display.*;
        import flash.filters.*;
        import flash.events.*;
        import flash.geom.*;
        
        [SWF(width='400',height='400',backgroundColor='0xffffff')]
        public class Sphere extends Sprite {
                [Embed(source="abc.png")]
                private var myImage:Class;
                private var bm:Bitmap;
                private var filter:BitmapData;
                private var maskBitmap:BitmapData;
                private var fbd:Bitmap=null;
                private var bmd:BitmapData;
                private var radius:int;
                
                private var WIDTH:int = 400;
                private var HEIGHT:int = 400;
                
                public function Sphere( ) {
                        bm = new myImage();
                        addChild(bm);
                        
                        radius = WIDTH/3*1;
                        
                        // DisplacementMapFilter用のビットマップデータ作成
                        filter = createMap(radius*2);
                        maskBitmap = createMask(radius*2);
                        
                        var maskBm:Bitmap = new Bitmap(maskBitmap);
                        maskBm.blendMode = BlendMode.NORMAL;
                        addChild(maskBm);
                        
                        stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
                }
                
                private function onMouseMove(e:MouseEvent):void{
                        bm.x = stage.mouseX - bm.width/2;
                        bm.y = stage.mouseY - bm.height/2;
                        
                        // DisplacementMapFilterを作成
                        var pd:Point = new Point(WIDTH/2 - bm.x - radius,
                                                 HEIGHT/2 - bm.y - radius);
                        var f:DisplacementMapFilter = new DisplacementMapFilter(filter, pd,
                                                                                BitmapDataChannel.RED,BitmapDataChannel.BLUE, 200,200,"color",0x0);
                        // フィルタを適用
                        bm.filters = [f];
                }
                
                private function createMask(d:int):BitmapData{
                        var bmp:BitmapData = new BitmapData(WIDTH, HEIGHT, true, 0xffffff);
                        var r:Number = d/2; // radius
                        for(var j:int = 0; j < HEIGHT; j++){
                                for(var i:int = 0; i < WIDTH; i++){
                                        var ii:int = i - WIDTH/2;
                                        var jj:int = j - HEIGHT/2;
                                        var distance:Number = Math.sqrt(ii*ii+jj*jj);
                                        if(distance > r-1)
                                        bmp.setPixel32 (i,j,0xffffffff);
                                }
                        }
                        return bmp;
                }
                
                private function createMap(d:int):BitmapData{
                        var bmp:BitmapData = new BitmapData(d, d, false, 0xffffff);
                        var r:Number = d/2; // radius
                        for(var j:int = 0; j < d; j++){
                                for(var i:int = 0; i < d; i++){
                                        var ii:int = i - r;
                                        var jj:int = j - r;
                                        var distance:Number = Math.sqrt(ii*ii+jj*jj);
                                        if(distance > r)
                                        bmp.setPixel(i,j,0);
                                        else{
                                                var v:Number = r* Math.asin(distance/r);
                                                var theta:Number = Math.abs(Math.atan((j-r)/(i-r)));
                                                var offsetR:int = (i > r)
                                                ? (v-distance)*Math.cos (theta)
                                                : -1*(v-distance)*Math.cos(theta);
                                                var offsetB:int = (j > r)
                                                ? (v-distance)*Math.sin(theta)
                                                : -1*(v-distance)* Math.sin(theta);
                                                var colR:int = 128 + offsetR;
                                                var colB:int = 128 + offsetB;
                                                bmp.setPixel(i, j, (colR << 16) + colB);
                                        }
                                }
                        }
                        return bmp;
                }
        }
}
スポンサーサイト
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。