In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: Transition Sketcher

author Jesse Freeman aka @theFlashBum | http://jessefreeman.com

This is the Doc Class to run my SketchArea. This class adds keyboard support
to help control features of the SketchArea. Here is a list of all the keys
I have set up.

Keyboard Short Cuts

Space Bar - flips between src a and src b. Source A is always the bottom
layer and Source B is the paint layer.

r - Redraw last animation.

c - Clear SketchArea

s - Quick save. The SketchArea will take the last set of recorded points
along with what mode it is in and save it to a number key. For example if
nothing has been saved and you hit save it will register at key 1. Next
save will be key 2, etc.

1 - 0 Plays back a saved animation.

d - Activates the draw tool. Once in draw mode you will see a representation
of the brush that follows the mouse. When you are done you can hit d to
exit draw mode. Hitting replay automatically exits you from draw mode.

+ - Increases the size of the brush.

- - Decreases the size of the brush.

The
/**
 * Copyright leonardo.sgoulart ( http://wonderfl.net/user/leonardo.sgoulart )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/kvfJ
 */

// forked from FlashBum's Transition Sketcher
package {
    import flash.text.TextFieldAutoSize;
    import flash.text.TextField;
    import flash.display.Shape;

    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;

    /**
     * author Jesse Freeman aka @theFlashBum | http://jessefreeman.com
     * 
     * This is the Doc Class to run my SketchArea. This class adds keyboard support
     * to help control features of the SketchArea. Here is a list of all the keys
     * I have set up.
     * 
     * Keyboard Short Cuts
     * 
     * Space Bar - flips between src a and src b. Source A is always the bottom
     * layer and Source B is the paint layer.
     * 
     * r - Redraw last animation.
     * 
     * c - Clear SketchArea
     * 
     * s - Quick save. The SketchArea will take the last set of recorded points
     * along with what mode it is in and save it to a number key. For example if
     * nothing has been saved and you hit save it will register at key 1. Next
     * save will be key 2, etc.
     * 
     * 1 - 0 Plays back a saved animation.
     * 
     * d - Activates the draw tool. Once in draw mode you will see a representation
     * of the brush that follows the mouse. When you are done you can hit d to
     * exit draw mode. Hitting replay automatically exits you from draw mode.
     * 
     * + - Increases the size of the brush.
     * 
     * - - Decreases the size of the brush.
     * 
     * The main goal of this demo is to illustrate how custom wipe on/off transitions
     * can be built dynamically in flash based on user generated array of points.
     * 
     * Important - this is a proof of concept, there is still a lot of work and 
     * optimizations I need to do to get this clas production ready.
     * 
     */
    public class FlashTest extends Sprite {

        protected var sketchArea : SketchArea;
        protected var loader : Loader;
        private var label : TextField;

        public function FlashTest() {
            
            configureStage();
            init();
        }

        protected function configureStage() : void {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
        }

        /**
         * 
         * Create a loader to get a background image.
         * 
         */
        protected function init() : void {
            loader = new Loader();
            loader.load(new URLRequest("http://demos.flashartofwar.com/RandomImageComposite/images/skin3/photo.jpg"), new LoaderContext(true));
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoad);
        }

        /**
         * 
         * Once image is loaded we can create our SketchArea class. Here we are
         * passing in a bitmap of the image we just loaded (will go into sourceA)
         * then create a white layer and pass it in to represent sourceB (our 
         * paint layer/color).
         * 
         */
        protected function onImageLoad(event : Event) : void {
            var bmd : BitmapData = Bitmap(loader.content).bitmapData.clone();
            var sourceA : Bitmap = new Bitmap(bmd); // This is the background layer

            var sourceB : Shape = new Shape();
            sourceB.graphics.beginFill(0xffffff);
            sourceB.graphics.drawRect(0, 0, sourceA.width, sourceA.height);
            sourceB.graphics.endFill();
            
            sketchArea = new SketchArea(loader.width + loader.x, loader.height + loader.y, sourceA, sourceB);
            addChild(sketchArea);
            
            loader = null;

            stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            
            label = new TextField();
            label.autoSize = TextFieldAutoSize.LEFT;
            label.multiline = true;
            label.wordWrap = true;
            label.width = 400;
            label.htmlText = "<b>Keyboard Short Cuts</b>: <br><b>Space Bar</b> - flips between src a and src b <br> <b>R</b> - Redraw last animation <br> <b>C</b> - Clear SketchArea <br> <b>S</b> - Quick save | <b>1</b> - <b>0</b> Plays back a saved animation <br> <b>D</b> - Activates the draw tool | <b>+</b>/<b>-</b> - Increases/Decrease brush size";
            label.y = sketchArea.height;
            
            addChild(label);
            
            sketchArea.toggleDrawMode();
        }

        protected function keyDownHandler(event : KeyboardEvent) : void {
            switch(event.keyCode) {
                case(32):
                    trace("Spacebar");
                    sketchArea.toggleDrawMode();
                    break;
                case(82):
                    trace("r");
                    sketchArea.redraw();
                    break;
                case(67):
                    trace("c");
                    sketchArea.clear();
                    break;
                case(83):
                    sketchArea.quickSave();
                    break;
                case(49): 
                case(50): 
                case(51): 
                case(52): 
                case(53): 
                case(54): 
                case(55): 
                case(56): 
                case(57):
                    var saveID : Number = event.keyCode - 49;
                    sketchArea.quickPlayBack(saveID);
                    break;
                case(68):
                    sketchArea.activateDraw();
                    break;
                case(187):
                    sketchArea.increaseThickness();
                    break;
                case(189):
                    sketchArea.decreaseThickness();
                    break; 
            }
           
            //trace("keyDownHandler: " + event.keyCode);
        }
    }
}

import flash.geom.Rectangle;
import flash.geom.Matrix;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.utils.Dictionary;
import flash.utils.Timer;

/**
 * @author jessefreeman
 */
class SketchArea extends Sprite {

    private static const SOURCE_A : String = "sourceA";
    private static const SOURCE_B : String = "sourceB";
    private static const BORDER : String = "border";
    private static const SKETCH_LAYER : String = "sketchArea";
    private static const BRUSH_PREVIEW : String = "brushPreview";
    protected var _width : Number;
    protected var _height : Number;
    protected var sketchCoords : Array = new Array;
    protected var currentVectorID : Number = 0;
    protected var currentPoint : Object;
    protected var thickness : Number = 150 ;
    protected var photoContainer : Sprite;
    protected var lineColor : uint = 0xffffff;
    protected var redrawSpeed : Number = 10;
    protected var redrawTimer : Timer;
    protected var eraseMode : Boolean = false;
    protected var savedSketches : Array = new Array();
    protected var active : Boolean;
    protected var display : Bitmap;
    protected var layers : Dictionary = new Dictionary(true);
    protected var brushPreviewMatrix : Matrix = new Matrix();
    protected var sampleRect : Rectangle;
    protected var samplePoint : Point;
    protected var sourceBitmapData : BitmapData;
    protected var sketchBitmapData : BitmapData;

    /**
     * The SketchArea represents a canvass where a use can draw on, play back
     * the drawing's animation, and save it temporarily.
     * 
     * At it's core the SketchArea has 2 layers, sourceA (the background) and
     * sourceB (the paint fill).
     * 
     * My swapping sourceA and sourceB you can easily create reveal and remove
     * animations for images.
     * 
     * @param width - width of the canvas
     * @param height - height of the canvas
     * @param sourceA - represents the background image used by the canvas
     * @param sourceB - represents the fill image for the brush
     * 
     */
    public function SketchArea(width : Number = 600, height : Number = 400, sourceA : DisplayObject = null, sourceB : DisplayObject = null) {
        _width = width;
        _height = height;
            
        if(sourceA)
                this.sourceA = sourceA;
            
        if(sourceB)
                this.sourceB = sourceB;    
            
        init();
    }

    public function get sourceA() : DisplayObject {
        return layers[SOURCE_A];
    }

    /**
     * Sets the background image for the SketchArea
     * @param source - DisplayObject to be used as sourceA.
     */
    public function set sourceA(source : DisplayObject) : void {
        layers[SOURCE_A] = source;
    }

    public function get sourceB() : DisplayObject {
        return layers[SOURCE_B];
    }

    /**
     * Sets the fill for the brush in the SketchArea
     * @param source - DisplayObject to be used as sourceB.
     */
    public function set sourceB(source : DisplayObject) : void {
        layers[SOURCE_B] = source;
    }

    /**
     * This makes the line thickness of the brush smaller. Decreases by 10px
     * as long as the thickness is greater then 0.
     */
    public function decreaseThickness() : void {
        thickness -= 10;
        if(thickness < 0 ) thickness = 0;
        drawBrushPreview(thickness);
    }

    /**
     * This makes the line thickness of the brush larger. Increase by 10px
     * with a 300 px max.
     */
    public function increaseThickness() : void {
        thickness += 10;
        if(thickness > 300 ) thickness = 300;            
        drawBrushPreview(thickness);
    }

    /**
     * Turns on the Drawing listeners so a use can begin recording their 
     * sketch.
     */
    public function activateDraw() : void {
        active = !active;
            
        if(active) {
            addMousePressEventListeners();
        } else {
            removeMousePressEventListeners();
        }
            
        toggleBrushPreview();
        compositeImage();
    }

    /**
     * Drawing mode represents what source is used as the background. This
     * method simply swaps out the instance of source a with the instance
     * of source b.
     * 
     * This lets gives you the effect of revialing or removing an image.
     */
    public function toggleDrawMode() : void {
            
        var aSrc : DisplayObject = layers[SOURCE_A];
        var bSrc : DisplayObject = layers[SOURCE_B];
            
        layers[SOURCE_A] = bSrc;
        layers[SOURCE_B] = aSrc;
            
        clear();
            
        eraseMode = !eraseMode;
    }

    /**
     * Clears the SketchArea by removing any graphics drawn as well as resetting
     * the sketch coordinates array.
     */
    public function clear() : void {
        clearGraphics();
        sketchCoords = new Array;
        compositeImage();
    }

    /**
     * This simply clears the graphics layer of the SketchArea.
     */
    public function clearGraphics() : void {
        layers[SKETCH_LAYER].graphics.clear();
        compositeImage();
    }

    /**
     * This will playback the currently active sketch ie what ever the last
     * sketch that was created.
     */
    public function redraw() : void {
        if(active)
                activateDraw();
            
        if(redrawTimer && redrawTimer.running)
                redrawTimer.stop();
        clearGraphics();

        var total : Number = sketchCoords.length - 1;
        redrawTimer = new Timer(redrawSpeed, total);
        redrawTimer.addEventListener(TimerEvent.TIMER, onRedrawTick);
                        
        currentVectorID = 0;
        var startPoint : Object = sketchCoords[ currentVectorID ];
        moveLine(startPoint.x, startPoint.y);
        redrawTimer.start();
    }

    /**
     * This saves out the mode and sketchCoords into an object then pushes
     * it into a savedSketches array. The id of the newly created object can
     * be used with qucikPlayBack to view the results.
     */
    public function quickSave() : void {
        var savedState : Object = new Object();
        savedState.eraseMode = eraseMode;
        savedState.sketchCoords = sketchCoords.concat();
            
        savedSketches.push(savedState);
    }

    /**
     * Quick playback takes a saved sketch id (corresponds to an index in the
     * savedSketces array and redraws the sketch.
     * @param id - id repressing a valid index of the saved coords array.
     */
    public function quickPlayBack(id : Number) : void {
        if(id < savedSketches.length) {
            var state : Object = savedSketches[id];
            if(state.eraseMode != eraseMode)
                    toggleDrawMode();
            sketchCoords = state.sketchCoords.concat();
            redraw();
        }
    }

    protected function toggleBrushPreview() : void {
        if(active) {
            drawBrushPreview(thickness);            
        } else {
            layers[BRUSH_PREVIEW].graphics.clear();
        }
    }

    protected function createBorder() : void {
        var border : Shape = new Shape();
        border.graphics.lineStyle(1, 0x000000, .3);
            
        border.graphics.drawRect(0, 0, _width - 1, _height - 1);
        border.graphics.endFill();
            
        layers[BORDER] = border;
    }

    protected function init() : void {
        display = new Bitmap();
        display.bitmapData = new BitmapData(_width, _height, true, 0xffffff);
        addChild(display);
            
        layers[SKETCH_LAYER] = new Shape();
            
        if(!layers[SOURCE_B]) {
            var matt : Shape = new Shape();
            matt.graphics.beginFill(0xff0000);
            matt.graphics.drawRect(0, 0, _width, _height);
            matt.graphics.endFill();
            layers[SOURCE_B] = matt;
        }

        //            
        layers[BRUSH_PREVIEW] = new Shape();
        createBorder();
        //            
        //createMouseBrush( thickness );
        compositeImage();
        toggleDrawMode();
    }

    private function onEnterFrame(event : Event) : void {
        compositeImage();
    }

    protected function drawBrushPreview(size : Number) : void {
        layers[BRUSH_PREVIEW].graphics.clear();
        layers[BRUSH_PREVIEW].graphics.lineStyle(1, 0x000000, .3);
            
        var d : Number = size * .5;
            
        layers[BRUSH_PREVIEW].graphics.drawCircle(0, 0, d);
        layers[BRUSH_PREVIEW].graphics.endFill();
    }

    protected function addMousePressEventListeners() : void {
        addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
        addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
        addEventListener(Event.ENTER_FRAME, onEnterFrame);
    }

    protected function removeMousePressEventListeners() : void {
        removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
        removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
        removeEventListener(Event.ENTER_FRAME, onEnterFrame);
    }

    protected function onMouseUp(event : MouseEvent) : void {
        removeDrawListeners();
        sketchCoords.push({x:-1, y:-1});
        layers[SKETCH_LAYER].graphics.endFill();
    }

    protected function onMouseDown(event : MouseEvent) : void {
        layers[SKETCH_LAYER].graphics.moveTo(mouseX, mouseY);
        layers[SKETCH_LAYER].graphics.lineStyle(thickness, lineColor, 1);
                        
        addDrawListeners();
    }

    protected function addDrawListeners() : void {
        addEventListener(MouseEvent.MOUSE_MOVE, onDraw);
    }

    protected function removeDrawListeners() : void {
        removeEventListener(MouseEvent.MOUSE_MOVE, onDraw);
    }

    protected function onDraw(event : MouseEvent) : void {
        currentPoint = {x: mouseX, y: mouseY, thickness: thickness };
                        
        sketchCoords.push(currentPoint);
        draw(currentPoint);
    }

    protected function draw(point : Object) : void {
        layers[SKETCH_LAYER].graphics.lineTo(point.x, point.y);
    }

    protected function drawArea(width : Number, height : Number, alpha : Number = 1) : void {
        graphics.clear();
        graphics.beginFill(0xffffff, alpha);
        graphics.drawRect(0, 0, width, height);
        graphics.endFill();
    }

    protected function onRedrawTick(event : TimerEvent = null) : void {
        var currentPoint : Object = sketchCoords[ currentVectorID ];
                        
                        
        var nextPoint : Object = (currentVectorID == sketchCoords.length) ? {x:-1, y:-1} : sketchCoords[ currentVectorID + 1 ];
        var ink : Number = 1;
            
        if((currentPoint.x == -1) && (currentPoint.y == -1)) {
            moveLine(nextPoint.x, nextPoint.y);
        } else {
            layers[SKETCH_LAYER].graphics.lineStyle(thickness, lineColor, ink);
            drawLine(currentPoint.x, currentPoint.y);
        }
                        
        if(currentVectorID > sketchCoords.length) {
            redrawTimer.stop();
            layers[SKETCH_LAYER].graphics.endFill();
        } else {
            currentVectorID++;
        }
            
        compositeImage();     
    }

    protected function moveLine(x : Number, y : Number) : void {
        layers[SKETCH_LAYER].graphics.moveTo(x, y);
    }

    protected function drawLine(x : Number, y : Number) : void {
        layers[SKETCH_LAYER].graphics.lineTo(x, y);
    }

    protected function compositeImage() : void {
        // Create Bitmap data for final image
        var bmd : BitmapData = display.bitmapData;
            
        bmd.draw(layers[SOURCE_A]);
            
        brushPreviewMatrix = new Matrix();
        brushPreviewMatrix.translate(mouseX, mouseY);
            
        sampleRect = new Rectangle(0, 0, _width, _height);
        samplePoint = new Point(0, 0);
            
        sourceBitmapData = new BitmapData(_width, _height, true, 0x000000);
        sourceBitmapData.draw(layers[SOURCE_B]);
            
        sketchBitmapData = new BitmapData(_width, _height, true, 0x000000);
        sketchBitmapData.draw(layers[SKETCH_LAYER]);
            
        bmd.copyPixels(sourceBitmapData, sampleRect, samplePoint, sketchBitmapData, null, true);
            
        bmd.draw(layers[BORDER]);
            
        bmd.draw(layers[BRUSH_PREVIEW], brushPreviewMatrix);
    }
}