forked from: webcam photosnap

by Kio forked from webcam photosnap (diff: 660)
JPEGCam v1.0.9 
Webcam library for capturing JPEG images and submitting to a server 
Copyright (c) 2008 - 2009 Joseph Huckaby  
Licensed under the GNU Lesser Public License 
http://www.gnu.org/licenses/lgpl.html
♥0 | Line 638 | Modified 2012-02-08 23:46:13 | GPLv3 License
play

ActionScript3 source code

/**
 * Copyright Kio ( http://wonderfl.net/user/Kio )
 * GNU General Public License, v3 ( http://www.gnu.org/licenses/quick-guide-gplv3.html )
 * Downloaded from: http://wonderfl.net/c/8wtf
 */

// forked from Kio's webcam photosnap
package {
    /* JPEGCam v1.0.9 */    
    /* Webcam library for capturing JPEG images and submitting to a server */    
    /* Copyright (c) 2008 - 2009 Joseph Huckaby <jhuckaby@goldcartridge.com> */    
    /* Licensed under the GNU Lesser Public License */    
    /* http://www.gnu.org/licenses/lgpl.html */
    /*                                 */
    


    import flash.display.*;
     import flash.display.Sprite;
   import flash.filters.GlowFilter;
    import flash.geom.Matrix;
    import flash.utils.*;    
    import flash.media.Camera;    
    import flash.media.Video;

    import flash.external.ExternalInterface;    

    import flash.net.*;
        
    import flash.system.Security;    
    import flash.system.SecurityPanel;
      
    import flash.media.Sound;    
    import flash.media.SoundChannel;
    
    import flash.geom.Matrix;
    import flash.geom.Rectangle;
    import flash.geom.Point
    
    import com.adobe.images.JPGEncoder;
    
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.text.TextFieldAutoSize;
    import flash.events.*;

    import com.demonsters.debugger.MonsterDebugger;
 //   import com.adobe.serialization.json.JSON; 

    import flash.utils.*;

    [SWF(backgroundColor=0x000000, width = '800', height = '460', frameRate = '45')]
    public class Webcam extends Sprite {        
     //   internal var video:Video;   
        private var thumbsLayer:Sprite;
        private var effectLayer:Sprite;
        private var videosLayer:Sprite;
        private var video_preview:Video;
        private var video_snapshot:Video;
        private var encoder:JPGEncoder;
        private var shuttersnd:Sound = null;
        private var beepsnd:Sound = null;
        private var sound:Boolean = false;
        private var channel:SoundChannel = new SoundChannel();        
        private var jpeg_quality:int = 90;
        private var video_width:int= 640;
        private var video_height:int = 480;
        private var server_width:int = 640;   
        private var server_height:int = 480;
        private var thumbs_width:int = 160;
        private var thumbs_height:int = 120;
        private var thumbs_offset:int = 0;
        private var camera:Camera;
        private var bmp:Bitmap;
        private var bmpdata:BitmapData;        
        private var baseurl:String ='http://www.snapfoto.nl/';
        private var url:String ='http://www.snapfoto.nl/savesnapfoto.php';
        private var phpscript:String ='http://www.snapfoto.nl/getfilelisting.php';
        private var thumbslist:Array = [];
        private var effectlist:Array = [];
                
        private var tf:TextField;
        private var spriteThumb:Sprite;
      
      //keycodes
        private var hotkeysnap:uint = 32;
        private var hotkeyctrl:uint = 17;
        private var hotkeyesc:uint = 27;
        private var hotkeyaup:uint = 38;  //arrow up
        private var hotkeyadown:uint = 40;  //arrow down
        private var hotkeyaleft:uint = 37;  //arrow left
        private var hotkeyaright:uint = 39;  //arrow right
        private var hotkeypagup:uint = 33;  //page up
        private var hotkeypagdown:uint = 34;  //page down
        private var hotkeyplus:uint = 187;  //plus or =
        private var hotkeyminus:uint = 189;  //minus
        private var hotkeywindows:uint = 91;  //left windows
        private var hotkeyzero:uint = 48;  //zero
        private var hotkeyF12:uint = 123;  // next effect
        private var hotkeyF11:uint = 122;  // prev effect
        private var hotkeyF10:uint = 121;  //magnify more
        private var hotkeyF9:uint = 120;  //magnify less
        private var hotkeyF8:uint = 119;  //reset magnification and position
        private var hotkeyF7:uint = 118;  //
        private var hotkeyF6:uint = 117;  //
        private var hotkeyF5:uint = 116;  //
        private var hotkeyF4:uint = 115;  //
        private var hotkeyF3:uint = 114;  //
        private var hotkeyF2:uint = 113;  //
        private var hotkeyF1:uint = 112;  //

        
        //effect applying
        private var frameNum    : uint = 0;
        private var frameBmp    : BitmapData;
        private var frameImg    : Bitmap;
        private var frameSBmp    : BitmapData;
        private var frameSImg    : Bitmap;  
        
        //image loading    
        private var modelBmp    : BitmapData;
        private var alphaBmp    : BitmapData;
        private var loadedimage : Bitmap;
        private var imageQueue  : Array = [];
        
        private var debugging    : Boolean = false;
        private var mousedown    : Boolean = false;
        private var snapbusy    : Boolean = false;
        private var waitfordclick : Boolean = false;
        private var awaitID      : Number = 0;
        private var parsedJSONData:Object;
                  
    // class constructor    
    public function Webcam() {
        MonsterDebugger.initialize(this);
        MonsterDebugger.trace(this, "Monster debugger init");
      
        Security.loadPolicyFile('http://www.snapfoto.nl/crossdomain.xml');
        flash.system.Security.allowDomain("*");



        if (this.loaderInfo.parameters.api_url != undefined) {  
            var flashvars:Object = LoaderInfo(this.root.loaderInfo).parameters;
            MonsterDebugger.trace(this, "flashvar settings");
            server_width = Math.floor( flashvars.server_width );
            thumbs_offset = Math.floor( flashvars.thumbs_offset );
            server_height = Math.floor( flashvars.server_height );
            url = flashvars.api_url;
            if (flashvars.shutter_enabled == 1) {
                sound = true;           
                init_sound(flashvars.shutter_url, flashvars.beep_url);
            }
        }
        else {
            MonsterDebugger.trace(this, "debug settings");
            thumbs_offset = 0;
            
        }
MonsterDebugger.trace(this, "video="+video_width + "  server="+server_width + "  api1="+url   );
MonsterDebugger.trace(this, "video="+video_height + "  server="+server_height + "  api2="+phpscript   );
MonsterDebugger.trace(this, "thumbpos="+thumbs_offset);
        stage.scaleMode = StageScaleMode.NO_SCALE;
        stage.align = StageAlign.TOP_LEFT;
        stage.stageWidth = video_width + thumbs_width;
        stage.stageHeight = video_height;
             
        thumbslist = new Array();

        thumbsLayer = new Sprite();
        videosLayer = new Sprite();
        effectLayer = new Sprite();
        videosLayer.x = 0;
        effectLayer.x = 0;
       
        
        graphics.beginFill(0x000000, 1);
        graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
        graphics.endFill();
        thumbsLayer.x = thumbs_offset;
        addChild(videosLayer);            
        addChild(effectLayer);            
        addChild(thumbsLayer);            
            
 
  
            // Hack to auto-select iSight camera on Mac (JPEGCam Issue #5, submitted by manuel.gonzalez.noriega)            
            // From: http://www.squidder.com/2009/03/09/trick-auto-select-mac-isight-in-flash/            
            var cameraIdx:int = -1;            
            for (var idx:int = 0, len:int = Camera.names.length; idx < len; idx++) {                
                if (Camera.names[idx] == "USB Video Class Video") {                    
                    cameraIdx = idx;                    
                    idx = len;                
                    }            
            }
            
            if (cameraIdx > -1) camera = Camera.getCamera( String(cameraIdx) );            
            else camera = Camera.getCamera();                                                
                
            if (camera != null) {
                //init webcam
                init_camera();  //set camera and display on stage
                stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownListener); //init key listeners               
                stage.addEventListener(MouseEvent.MOUSE_WHEEL,MouseWheelHandler);
                stage.addEventListener(MouseEvent.MOUSE_DOWN,MouseDownHandler);                     
                stage.addEventListener(MouseEvent.MOUSE_UP,MouseUpHandler);
                stage.addEventListener(MouseEvent.MOUSE_MOVE,MouseMoveHandler);
                     
                // load images to load, and when ready finish final inits
                if (stage) load_images();
                else addEventListener(Event.ADDED_TO_STAGE, load_images);
                
MonsterDebugger.trace(this, "end of inits");
        
                }   
                else {
                    MonsterDebugger.trace(this, "You need a camera.");                
                    ExternalInterface.call('webcam.flash_notify', "error", "No camera was detected.");            
                    }
    }

       

    private function init_callbacks(e:Event = null):void {
                    // set key event listener
  MonsterDebugger.trace(this, "callback to do.");
                    ExternalInterface.addCallback('_snap', snap);                
                    ExternalInterface.addCallback('_configure', configure);                
                    ExternalInterface.addCallback('_upload', upload);                
                    ExternalInterface.addCallback('_reset', reset);

                    ExternalInterface.call('webcam.flash_notify', 'flashLoadComplete', true);
MonsterDebugger.trace(this, "init ready, flash loaded");
                    }

         //initialize variables for loading images
         //first get all files form the overlay folder in an (json) array
         //then one by one load the files
        private function load_images(e:Event = null):void 
        {
            //ask the php script for all the png files in the overlay directory
            //Create a json URLLoader object
            var json:URLLoader;
            json = new URLLoader();
            json.addEventListener(Event.COMPLETE, parseJSON);
            json.load(new URLRequest(phpscript));
        }
        private function parseJSON(evt:Event):void {
            parsedJSONData = JSON.parse(evt.target.data);
            for(var i:uint =0; i<parsedJSONData.length; i++) {
                imageQueue[i] = baseurl + parsedJSONData[i];
            }
            loadAsset( imageQueue[0] );
        }

     private function loadAsset(target:String):void
        { 
        MonsterDebugger.trace(this, "To load:" + target);
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
            loader.load(new URLRequest(target));
        }

        private function ioErrorHandler(event:IOErrorEvent):void {
            MonsterDebugger.trace(this, "Unable to load image: " + imageQueue[0]);
        }

        
        private function loadComplete(event:Event):void 
        {
            var loader:Loader = Loader(event.target.loader);
            loadedimage = Bitmap(loader.content);
 //           var bitmap:BitmapData = new BitmapData(loadedimage.width, loadedimage.height, true, 0x0);
 //           bitmap.draw(loadedimage, new Matrix());
            
            effectlist.push( new effectlayer(imageQueue[0], loadedimage, video_width, video_height));

             
            loader.unload();
            imageQueue.splice( 0, 1); //remove the first index

            if (imageQueue.length > 0){
                loadAsset(imageQueue[0]);
            }else{
                
                init_callbacks();  // when all images are loaded finish the inits
            }
        }
        


        // init sound
        private function init_sound(shutter_url:String, beep_url:String):void {
                shuttersnd = new Sound();                    
                shuttersnd.load( new URLRequest( shutter_url ) ); 
                beepsnd = new Sound();  
                beepsnd.load( new URLRequest( beep_url ) );
        }
                
        //init the webcamera           
        private function init_camera():void {
                    video_preview = new Video( video_width,video_height );                
                    video_snapshot = new Video( server_width,server_height );
                    video_preview.attachCamera(camera);       
                    videosLayer.addChild(video_preview);   
                    video_preview.scaleX = -1;
                    video_preview.x = video_width;                        
                    
                    if ((video_width < server_width) && (video_height < server_height)) {                    
                        video_snapshot.scaleX = (video_width / server_width);                    
                        video_snapshot.scaleY = (video_height / server_height);
                    }
                    else video_snapshot.scaleX = -1;
                    video_snapshot.x = server_width;
                    
                    camera.setQuality(0, 100);                
                    camera.setKeyFrameInterval(10);                
                    camera.setMode( video_width,video_height , 25);
                    // do not detect motion (may help reduce CPU usage)                
                    camera.setMotionLevel( 100 );
                
                    jpeg_quality = 90;        
                    
                    camera.addEventListener(ActivityEvent.ACTIVITY, activityHandler);                
                } 
                public function set_quality(new_quality:int):void {            
                    // set JPEG image quality            
                    if (new_quality < 0) new_quality = 0;            
                    if (new_quality > 100) new_quality = 100;            
                    jpeg_quality = new_quality;        
                }
                public function configure(panel:String = SecurityPanel.CAMERA):void {            
                    // show configure dialog inside flash movie            
                    Security.showSettings(panel);        
                }
                private function activityHandler(event:ActivityEvent):void {            
                    MonsterDebugger.trace(this, "activityHandler: " + event);        
                }
                 private function backgroundColor( color:uint ):void  {
                   with( this.graphics )
                   {
                    clear();
                    beginFill( color );
                    drawRect( 0 , 0 , Capabilities.screenResolutionX, Capabilities.screenResolutionY);
                    endFill();
                   }
                 }

  
    //called after key press to snapfoto                            
    public function snap(new_url:String, new_quality:int, shutter:Boolean, new_stealth:int = 0, timer:int=0, new_flash:int = 0):void {            
     snapbusy = true;
                   // take snapshot from camera, and upload if URL was provided            
                    if (timer>0) {
                        CountDown(String(timer));  
                        timer--;
                        if (shutter) channel = beepsnd.play(); 
                        if (timer<1) setTimeout( snap, 10, new_url, new_quality, shutter, new_stealth, timer, new_flash);
                        else  setTimeout( snap, 800, new_url, new_quality, shutter, new_stealth, timer, new_flash);
                       }
                    else {
                    
                    
                    // detach preview video
                  video_preview.attachCamera( null );  
      
                      // change to full capture settings
                    camera.setMode( server_width,server_height , 15);
                    video_snapshot.attachCamera(camera);
                    
                    if (new_flash>0) doFlash(0xAAAAAA, new_flash);  //add a flash

                    if (new_quality) set_quality(new_quality);
           
                    if (shutter) {                
                        channel = shuttersnd.play();                
                        setTimeout( snap2, 900, new_url );            
                    }            
                    else setTimeout( snap2, 900, new_url );
                }   
       }
  
     
             
       private function snap2(new_url:String):void {            
                    CountDown(null);  //clear the inscreen counter, if present
                    // take snapshot, convert to jpeg, submit to server 
                    bmpdata = new BitmapData( server_width, server_height );   
                    var _matrixs:Matrix = new Matrix();
                   _matrixs.tx = server_width;
                   _matrixs.a = -1;
                         
                    bmpdata.draw( video_snapshot, _matrixs);
                    var _matrix:Matrix = new Matrix();
                    var _xratio:Number = server_width / video_width;
                    var _yratio:Number = server_height/ video_height;
                    _matrix.translate((  (effectlist[frameNum].Pos_x+(video_width - effectlist[frameNum].Scaledwidth)/2)/effectlist[frameNum].Scale_x)+0  , 
                        (effectlist[frameNum].Pos_y+(video_height- effectlist[frameNum].Scaledheight)/2)/effectlist[frameNum].Scale_y);
                    _matrix.scale(  (effectlist[frameNum].Scale_x*_xratio), effectlist[frameNum].Scale_y*_yratio);

                    frameSBmp = new BitmapData(server_width, server_height, true, 0x0);
                    frameSBmp.draw(effectlist[frameNum].Bitmapdata, _matrix, null, null, null, true);
                    var rect:Rectangle = new Rectangle(0, 0, server_width, server_height);
                    var pt:Point = new Point(0, 0);

                    drawBorder(frameSBmp, 2); //draw a border around the snapshot

                    bmpdata.copyPixels(frameSBmp,rect,pt, frameSBmp, pt, true);
    
                    showThumb(bmpdata);
        
                // if URL was provided, upload now            
                if (new_url) upload( new_url );
                reset();
          }        


      private function drawBorder(target: BitmapData, thickness: uint) :void {
            var borderBmp: BitmapData = new BitmapData(target.width, target.height, true, 0x0);
            var square:Shape = new Shape;
            var rect:Rectangle = new Rectangle(0, 0, server_width, server_height);
            var pt:Point = new Point(0, 0);
            square.graphics.lineStyle(9,0x000000);
            square.graphics.drawRect(0+thickness, 0+thickness, server_width-thickness, server_height-thickness);
            borderBmp.draw(square);
            target.copyPixels(borderBmp,rect,pt, borderBmp, pt, true);
      }


      private function showThumb(bmpdata:BitmapData):void {
                // resize image downward before submitting                    
                var tmpdata:BitmapData = new BitmapData(thumbs_width, thumbs_height);
                var mat:Matrix = new Matrix();
                mat.scale( tmpdata.width / bmpdata.width, tmpdata.height / bmpdata.height );
                tmpdata.draw( bmpdata, mat, null, null, null, true );  // smoothing
                var image:Bitmap = new Bitmap(tmpdata);
                var c:uint = thumbslist.length;
                thumbsLayer.addChild(thumbslist[c] = new thumbsnap(image));
                thumbslist[c].x = 0;
                thumbslist[c].z = 1;
                thumbslist[c].y = -image.height ;
                            
               thumbslist[c].setFloor( video_height-(c*image.height)-image.height );
                 thumbslist[c].setGround( video_height);
                 
                thumbslist[c].addEventListener("down", stopThumb);
                thumbslist[c].addEventListener("ground", removeThumb);
                thumbslist[c]._id=c;  
                
                   if (c>3) {
                       for(var i:uint =0; i<thumbslist.length; i++) {
                        thumbslist[i].incFloor(image.height); //increase all floors
                        MonsterDebugger.trace(this, "thumb#"+thumbslist[i]._id + "floor="+thumbslist[i].fl);
                        }
                   }
      }
      private function stopThumb(e:Event):void{
            e.target.removeEventListener("down", stopThumb);
            e.target.yVel = e.target.yVel/5;  // decrease velocity
            MonsterDebugger.trace(this, "thumb down" + e.target._id);  
      }
      private function removeThumb(e:Event):void{
            e.target.removeEventListener("ground", removeThumb);
            thumbsLayer.removeChild(Sprite(e.target));
            MonsterDebugger.trace(this, "thumb ground" + e.target._id);
             thumbslist.splice( 0, 1); //remove the first index  
      }




        public function upload(new_url:String):void {            
            if (bmpdata) {                
                if ((video_width > server_width) && (video_height > server_height)) {                    
                    // resize image downward before submitting                    
                    var tmpdata:BitmapData = new BitmapData(server_width, server_height);                                        
        
                    var matrix:Matrix = new Matrix();                    
                    matrix.scale( server_width / video_width, server_height / video_height );                                        
            
                    tmpdata.draw( bmpdata, matrix, null, null, null, true );  // smoothing                    
                    bmpdata = tmpdata;                
                 }  // no need resize                                
        
                 MonsterDebugger.trace(this, "converting to jpeg");                            
        
                var ba:ByteArray;                
        
                encoder = new JPGEncoder( jpeg_quality );                
                ba = encoder.encode( bmpdata );                            
        
        MonsterDebugger.trace(this, "jpeg length: " + ba.length);                            
       
                var head:URLRequestHeader = new URLRequestHeader("Accept","text/*");                
                var req:URLRequest = new URLRequest( new_url );                
                req.requestHeaders.push(head);                            
        
                 req.data = ba;                
                 req.method = URLRequestMethod.POST;                
                 req.contentType = "image/jpeg";                            
        
                 var loader:URLLoader = new URLLoader();                
                 loader.addEventListener(Event.COMPLETE, onLoaded);                            
     MonsterDebugger.trace(this, "webcam.flash_notify success");  
        MonsterDebugger.trace(this, "sending post to: " + new_url);                            
        
                try {                    
                    loader.load(req);                
                    }          
                catch (error:Error) {                    
        MonsterDebugger.trace(this, "Unable to load requested document.");                    
                    ExternalInterface.call('webcam.flash_notify', "error", "Unable to post data: " + error);                
                }            
            }  //(!bmpdata)
        else {                
            ExternalInterface.call('webcam.flash_notify', "error", "Nothing to upload, must capture an image first.");            
        }        
    }                
        
    public function onLoaded(evt:Event):void {            
            // image upload complete            
            var msg:String = "unknown";      
            if (evt && evt.target && evt.target.data) msg = evt.target.data;            
            ExternalInterface.call('webcam.flash_notify', "success", msg);        
    }                
        
    public function reset():void {            
            if (bmpdata) bmpdata = null;
            camera.setMode( video_width,video_height , 30);
            video_preview.attachCamera(camera);
            videosLayer.addChild(video_preview);
            snapbusy = false;              
     }        
     
     
     // handle the key presses  
     private function keyDownListener(e:KeyboardEvent):void {
         switch (e.keyCode) {
             case hotkeysnap:
             case hotkeywindows:
             case hotkeyesc:
             case hotkeyF1:
                 if (!snapbusy) snap(url, jpeg_quality, sound, 0, 2, 325);
                 break;
             case hotkeypagup: //change overlay effect
             case hotkeyF10:
                 setOverlayEffect(-1);
                 break;
             case hotkeypagdown: //change overlay effect
             case hotkeyF12:
                 setOverlayEffect(1);
                 break;
             case hotkeyminus:    //decrease effect scale -10%
             case hotkeyF6:
                 effectlist[frameNum].downScale(0.1);
                 setOverlayEffect(0);
                 break;
             case hotkeyplus:    //decrease effect scale +10%
             case hotkeyF7:
                 effectlist[frameNum].upScale(0.1);
                 setOverlayEffect(0);
                 break;
             case hotkeyaright:   //reposition effect
                 effectlist[frameNum].move(+2,0);
                 setOverlayEffect(0);
                 break;
             case hotkeyaleft:   //reposition effect
                 effectlist[frameNum].move(-2,0);
                 setOverlayEffect(0);
                 break;
             case hotkeyaup:   //reposition effect
                 effectlist[frameNum].move(0,-2);
                 setOverlayEffect(0);
                 break;
             case hotkeyadown:   //reposition effect
                 effectlist[frameNum].move(0,+2);
                 setOverlayEffect(0);
                 break;
             case hotkeyzero:    //reset scale and popsition of current effect
             case hotkeyF8:
                 effectlist[frameNum].resetScale(video_width, video_height);
                 setOverlayEffect(0);
                 break;
             default:   
         }
    }
       // handle the mouse events 
   
    private function MouseMoveHandler(event:MouseEvent):void {
        if (mousedown) {
            effectlist[frameNum].setpos(mouseX, mouseY, video_width, video_height);
            setOverlayEffect(0);
        }        
    }
 
     private function MouseDownHandler(event:MouseEvent):void {
        mousedown = true;
    }   
     private function MouseUpHandler(event:MouseEvent):void {
        mousedown = false;

        if (awaitID==0)
            awaitID = setTimeout( timoutdoubleclick, 500);
        else {
                clearTimeout(awaitID);
                awaitID = 0;
                doDoubleClick();
        }
    }

    private function timoutdoubleclick():void {
        awaitID = 0;
        //doSingleClick();
    }

    
    private function doSingleClick():void {
        MonsterDebugger.trace(this, "doSingleClick"); 
        effectlist[frameNum].setpos(mouseX, mouseY, video_width, video_height);
        setOverlayEffect(0);
    }
   private function doDoubleClick():void {
        MonsterDebugger.trace(this, "doDoubleClick");
        if (!snapbusy) snap(url, jpeg_quality, sound, 0, 2, 325); 
    }

    
    private function MouseWheelHandler(event:MouseEvent):void {
        MonsterDebugger.trace(this, "mouseWheelHandler delta: " + event.delta);
        if (event.delta > 0) 
            if (mousedown) effectlist[frameNum].downScale(0.1);
            else setOverlayEffect(-1);
        if (event.delta < 0) 
            if (mousedown) effectlist[frameNum].upScale(0.1);
            else setOverlayEffect(1);
        setOverlayEffect(0);
    }



    private function CountDown(msg:String):void {
              if (tf) effectLayer.removeChild(tf);
              tf = null;
              if (msg) {
               tf = new TextField();
               tf.autoSize = TextFieldAutoSize.CENTER;
               tf.text = " "+msg+" ";
               tf.background = true;
               tf.backgroundColor = 0x000000;
               tf.selectable = false;
               tf.border = true;
               tf.autoSize = TextFieldAutoSize.CENTER;
               
               
             //  tf.scaleY =10;
               tf.alpha = .2;
               tf.width = 300;
              
               var myFormat:TextFormat = new TextFormat(); 
               myFormat.color = 0xffffff;
               myFormat.size = 80; 
               tf.setTextFormat(myFormat);  
               
               tf.x = video_width/2-(tf.width/2);
               tf.y = video_height/2-(tf.height/2);
              // tf.blendMode = BlendMode.INVERT;
               effectLayer.addChild(tf);
              }
    }
   
    private function doFlash(fillcol:int, duration:int):void {
            var flashing:Shape = new Shape; // initializing the variable shape
            flashing.graphics.beginFill(fillcol); // choosing the colour for the fill
            flashing.graphics.drawRect(0, 0, video_width,video_height); // (x spacing, y spacing, width, height)
            flashing.graphics.endFill(); // not always needed but I like to put it in to end the fill
            flashing.blendMode = BlendMode.ADD;
            videosLayer.addChild(flashing); // adds the rectangle to the stage
            setTimeout( videosLayer.removeChild, duration, flashing);  //remove the shape with a delay
    }


        // display the current/next/previous Frame effect, 
    private function setOverlayEffect(cnt:int = 0):void {
            frameNum = (frameNum + cnt) % effectlist.length;
         MonsterDebugger.trace(this, "effect:"+cnt);
            if (frameNum >effectlist.length) frameNum=0; 
            if (frameImg) effectLayer.removeChild(frameImg);        //remove current frame from stage
            frameBmp = new BitmapData(effectlist[frameNum].Width, effectlist[frameNum].Height, true, 0x0);
            var _matrix:Matrix = new Matrix();
            _matrix.translate((effectlist[frameNum].Pos_x+(video_width - effectlist[frameNum].Scaledwidth)/2)/effectlist[frameNum].Scale_x, 
                        (effectlist[frameNum].Pos_y+(video_height- effectlist[frameNum].Scaledheight)/2)/effectlist[frameNum].Scale_y);
            _matrix.scale(effectlist[frameNum].Scale_x, effectlist[frameNum].Scale_y);
MonsterDebugger.trace(this, "w:" + effectlist[frameNum].Scale_x + "name:" + effectlist[frameNum].Name );
                frameBmp.draw(effectlist[frameNum].Bitmapdata, _matrix, null, null, null, true);
                frameImg = new Bitmap(frameBmp);
                effectLayer.addChild(frameImg);
        }

            
               
 }
    

    
}
import flash.display.BitmapData;
import flash.geom.Matrix;
import com.demonsters.debugger.MonsterDebugger;

 class effectlayer {
    internal var Name:String;
    internal var Bitmapdata:BitmapData;
    internal var Width:uint;                //original width of effect image
    internal var Height:uint;                
    internal var Scale_x:Number;            //current scale of effect
    internal var Scale_y:Number;
    internal var Scaledwidth:uint;
    internal var Scaledheight:uint;
    internal var Pos_x:int;                //current position of effect, where 0,0 is center of area
    internal var Pos_y:int;
    internal var onStage:Boolean = false;
    
    
    //constructor
    public function effectlayer(_name:String, loadedimage : Bitmap, _width:uint = 640, _height:uint = 480) {
        Name = _name;
        Width = loadedimage.width;
        Height = loadedimage.height;
        var _matrix:Matrix = new Matrix();
        if (Width < _width) Width = _width;        //if width of source overlay smaller than screen then do an upscale
        if (Height < _height) Height = _height;    //if height of source overlay smaller than screen then do an upscale
        _matrix.scale(Width/loadedimage.width, Height/loadedimage.height); //upscaling if necessary
        
        Bitmapdata = new BitmapData(Width, Height, true, 0x0);
        Bitmapdata.draw(loadedimage, _matrix);
        resetScale(_width, _height);        
    }
    public function resetScale(_width:uint, _height:uint) : void {
        Scale_x = _width/Width;;
        Scale_y = _height/Height;
      Scaledwidth = Scale_x * Width;
        Scaledheight = Scale_y * Height;
        Pos_x = 0;
        Pos_y = 0;
    }
    public function downScale(value:Number) : void {
        Scale_x = (1-0.1) * Scale_x;
        Scale_y = (1-0.1) * Scale_y;
        Scaledwidth = Scale_x * Width;
        Scaledheight = Scale_y * Height;
    }
    public function upScale(value:Number) : void {
        Scale_x = Scale_x/  (1-0.1);
        Scale_y = Scale_y/  (1-0.1);              
        Scaledwidth = Scale_x * Width;
        Scaledheight = Scale_y * Height;
    }
    public function move(_x:int, _y:int) : void {
        Pos_x += _x;
        Pos_y += _y;
    }

    public function setpos(_x:int, _y:int, _width:uint = 640, _height:uint = 480) : void {
        Pos_x = _x - (_width/2);
        Pos_y = _y - (_height/2);
    }
 }
    



import flash.display.Sprite;
import flash.display.Bitmap;
import flash.events.Event;
import flash.geom.Matrix;
import flash.display.GradientType;
import com.demonsters.debugger.MonsterDebugger;

 class thumbsnap extends Sprite{
    internal var image:Bitmap;
    internal var onStage:Boolean = false;        
    internal var yVel:Number= .1;
    internal var fl:int;
    internal var gr:int;
    internal var _id:Number;

    public function thumbsnap(image: Bitmap) { 
        addEventListener(Event.ADDED_TO_STAGE, added);
        addEventListener(Event.REMOVED_FROM_STAGE, dispose);            
        addChild(image);
    }
    public function setGround(val:int):void {
        gr = val;
    }
    public function setFloor(val:int):void {
        fl = val;
    }
    public function incFloor(val:int):void {
        fl = fl+ val;
    }
    internal function added(e:Event):void{        
        addEventListener(Event.ENTER_FRAME, loop)
        onStage=true;
        cacheAsBitmap = true;
    }
        
     internal function loop(e:Event):void{
        if(y < (fl) ){
            y+=(yVel );  
            yVel+= 0.5*  Math.cos( (y/gr  )   *Math.PI/2 );
        }else{
            if(y > (gr))
             dispatchEvent(new Event("ground"));
            else {
                dispatchEvent(new Event("down"));
                y = fl;                
            }

        }   
    }        
        
    internal function dispose(e:Event):void{
            onStage=false;
            removeEventListener(Event.ENTER_FRAME, loop)
            removeEventListener(Event.ADDED_TO_STAGE, added);
            removeEventListener(Event.REMOVED_FROM_STAGE, dispose);
    }
}