Math and (Quasi) Physics in Action Script 3

Thumbnail roll - DisplacementMapFilter

This is a demonstration of how to use displacementMapFilter object to distort a DisplayObject. Here, the filter is applied to the thumbnails to create 3D effect that makes them look like rotating around the viewer.

See ‘DisplacementMapFilter - Flash CS4 Professional ActionScript 3.0 Language Reference’ for more about DisplacementMapFilter.

Main.as

package {
  import flash.display.*;
  import flash.filters.*;
  import flash.geom.*;
  public class Main extends Sprite {
    private var sW:uint = 600, sH:uint = 300;
    private var radius:Number = 300;
    private var _fl = 100;
    private var sp:Sprite;
    public function Main() {
      with(graphics) {
        beginFill(0x000000);
        drawRect(0,0,stage.stageWidth, stage.stageHeight);
        endFill();
      }
      var i:uint,j:uint;
      addChild(sp = new Thumbs());
      sp.x = -40;
      sp.y = 115;
      
      var maxRad:Number = Math.acos(_fl / radius );
      var sMapW:Number = Math.sin(maxRad);
      var cx:Number = sW / 2, cy:Number = sH / 2;
      var pz:Number, sx:Number, sy:Number, dx:Number, dy:Number;
      var radian:Number;
      var fi:BitmapData = new BitmapData(sW,sH);
      for (j = 0; j < sH; j ++) {
        for (i = 0; i < sW; i ++) {
          radian  = (i - cx) / sW * maxRad * 2;
          pz = Math.cos(radian) * radius;
          sx = Math.sin(radian) / sMapW * cx;
          sy = (j  + 10- cy) / (_fl / ( _fl + pz)) / 2;
          dx = constrain(Math.floor(sx -( i - cx) + 128), 0, 255);
          dy = constrain(Math.floor(sy -( j - cy) + 128), 0, 255);
          fi.setPixel(i,j,dy << 8 | dx);
        }
      }

      var f = new DisplacementMapFilter(fi,new Point(0,0), 
                                   BitmapDataChannel.BLUE,
                                   BitmapDataChannel.GREEN,
                                128,
                                128,
                                DisplacementMapFilterMode.COLOR,
                                0x00000000,0);
      sp.filters = [f];
    }
    
    private function constrain(val:Number, min:Number, max:Number):Number {
      val = Math.max(val, min);
      val = Math.min(val, max);
      return val;
    }
  }
}

Thumbs.as

package {
  import flash.display.*;
  import flash.geom.Matrix;
  import flash.events.Event;
  public class Thumbs extends Sprite {
    private var bmpds:Array = [RIMG0349,RIMG0350, RIMG0351, RIMG0353, RIMG0354];
    private var bmps:Array;
    private var thumbsSp:Sprite, maskSp:Sprite,gradientSp:Sprite;
    private var thumbW:Number = 200, thumbH:Number = 150;
    public function Thumbs() {
      addChild(thumbsSp = new Sprite());
      addChild(gradientSp = new Sprite());
      addChild(maskSp = new Sprite());
      
      // mask
      maskSp.graphics.beginFill(0xFF0000);
      maskSp.graphics.drawRect(0,0,600,300);
      thumbsSp.mask = maskSp;
      
      // gradient
      var mtx = new Matrix();
      mtx.createGradientBox(600,600,Math.PI / 2,0,0)  ;
      gradientSp.graphics.beginGradientFill(GradientType.LINEAR,
                  [0x00000, 0x000000],
                  [0.3,1],
                  [0,120],
                  mtx
                  );
      gradientSp.graphics.drawRect(0,150,600,150);
      gradientSp.graphics.endFill();
      
      //attach Bitmaps
      bmps = new Array();
      for (var i:uint = 0; i < bmpds.length; i ++) {
        bmps.push(new Bitmap(new bmpds[i ](0,0)));
        bmps.push(new Bitmap(new bmpds[i](0,0)));
        bmps[i * 2 + 1].y = thumbH * 2;
        bmps[i * 2 + 1].scaleY = -1;
        thumbsSp.addChild(bmps[i * 2]);
        thumbsSp.addChild(bmps[i * 2 + 1]);
        bmps[i * 2].x = thumbW * i ;
        bmps[i * 2 + 1].x = thumbW * i ;
      
      }
      addEventListener(Event.ENTER_FRAME, h_enterFrame);
    }
    
    private function h_enterFrame(evt:Event):void {
      for (var i:uint = 0; i < bmpds.length * 2; i ++) {
        bmps[i].x -= 10;
        if (bmps[i].x < -thumbW) {
          bmps[i].x += thumbW * bmps.length / 2;
        }
      }
    }
  }
}