[ActionScript 3.0] AS3.0 涂鸦及擦除功能,撤销重做步骤记录实例

package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BlendMode;
    import flash.display.DisplayObject;
    import flash.display.DisplayObjectContainer;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Matrix;
    import flash.geom.Rectangle;
    import flash.net.dns.AAAARecord;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;

    /**
     * @author Frost.Yen
     * @email 871979853@qq.com
     * @build 2016-8-24 下午2:19:07
     */
    [SWF(width="800",height="600")]
    public class DrawToUndo extends Sprite
    {
        private var _undoBtn:Sprite;
        private var _redoBtn:Sprite;
        private var _eraseBtn:Sprite;
        private var _drawBtn:Sprite;
        private var _canvas:Sprite;
        private var _list:Sprite;
        private var _line:Shape;
        private var _thickness:Number=5;
        private var _dataArr:Array=[];
        private var _blendMode:String = BlendMode.NORMAL;
        private var _stepID:int=-1;
        public function DrawToUndo()
        {
            if(stage) init();
            else addEventListener(Event.ADDED_TO_STAGE,init);
        }
        /**
         * 初始化
         */
        private function init(e:Event=null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            _list = new Sprite();
            _canvas = new Sprite();
            _canvas.graphics.beginFill(0,0);
            _canvas.graphics.drawRect(0,0,700,600);
            _canvas.graphics.endFill();
            _undoBtn = creatButton(75,25,0xeeeeee,"撤销") as Sprite;
            _redoBtn = creatButton(75,25,0xeeeeee,"重做") as Sprite;
            _eraseBtn = creatButton(75,25,0xeeeeee,"擦除") as Sprite;
            _drawBtn = creatButton(75,25,0xeeeeee,"涂鸦") as Sprite;
            _line = new Shape();
            
            addToDisplay(_list,this);
            addToDisplay(_canvas,this);
            addToDisplay(_line,this,0,0,1,true);
            addToDisplay(_undoBtn,this,710,10);
            addToDisplay(_redoBtn,this,710,45);
            addToDisplay(_eraseBtn,this,710,80);
            addToDisplay(_drawBtn,this,710,115);
            
            initEventListener();
        }
        private function initEventListener():void
        {
            _undoBtn.addEventListener(MouseEvent.CLICK,onUndo);
            _redoBtn.addEventListener(MouseEvent.CLICK,onRedo);
            _eraseBtn.addEventListener(MouseEvent.CLICK,onErase);
            _drawBtn.addEventListener(MouseEvent.CLICK,onDraw);
            _canvas.addEventListener(MouseEvent.MOUSE_DOWN,onDown);
        }
        private function onDown(e:MouseEvent):void
        {
            stage.addEventListener(MouseEvent.MOUSE_UP,onUp);
            stage.addEventListener(MouseEvent.MOUSE_MOVE,onMove);
            _line.graphics.lineStyle(_thickness,0xff00ff);
            _line.graphics.moveTo(_canvas.mouseX,_canvas.mouseY);
            _blendMode == BlendMode.ERASE?_line.visible = false:_line.visible = true;
            if(_blendMode == BlendMode.ERASE){
                var matrix:Matrix = new Matrix();
                matrix.translate(-_dataArr[_stepID].rect.x,-_dataArr[_stepID].rect.y);
            }
            function onMove(e:MouseEvent):void
            {
                _line.graphics.lineTo(_canvas.mouseX,_canvas.mouseY);    
                if(_blendMode == BlendMode.ERASE){
                    (_list.getChildAt(0) as Bitmap).bitmapData.draw(_line,matrix,null,_blendMode);
                }
            }
            function onUp(e:MouseEvent):void
            {
                if(_blendMode == BlendMode.ERASE){
                    //记录擦除步骤
                    var data:Object = {"rect":_dataArr[_stepID].rect,"bmpd":(_list.getChildAt(0) as Bitmap).bitmapData.clone()};
                    _dataArr.push(data);
                    _stepID++;
                    _line.graphics.clear();
                    removeBitmap();
                    addBitmap(_stepID);
                }else{
                    while(_stepID<_dataArr.length-1){
                        _dataArr.pop();
                    }
                    //记录涂鸦步骤
                    var rect:Rectangle  = _line.getBounds(_line);trace(rect);
                    var bmpd:BitmapData = new BitmapData(rect.width,rect.height,true,0);
                    var bmp:Bitmap = new Bitmap();
                    var matrix:Matrix = new Matrix();
                    matrix.translate(-rect.x,-rect.y);
                    bmpd.draw(_line,matrix,null,_blendMode,null,true);
                    bmp.bitmapData = bmpd;
                    addToDisplay(bmp,_list,rect.x,rect.y);
                    getDrawData();
                }
                
                stage.removeEventListener(MouseEvent.MOUSE_UP,onUp);
                stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMove);
            }
        }
        /**
         * 将步骤数据记录到数组
         */
        private function getDrawData():void
        {
            var rect:Rectangle = _list.getBounds(_list);
            var bmpd:BitmapData = new BitmapData(rect.width,rect.height,true,0);
            var bmp:Bitmap = new Bitmap(bmpd);
            var matrix:Matrix = new Matrix();
            matrix.translate(-rect.x,-rect.y);
            bmpd.draw(_list,matrix,null,_blendMode,null,true);
            var data:Object = {"rect":rect,"bmpd":bmpd.clone()};
            _dataArr.push(data);
            _stepID++;
            
            _line.graphics.clear();
            removeBitmap();
            addToDisplay(bmp,_list,rect.x,rect.y);
        }
        /**
         * 撤销
         */
        private function onUndo(e:MouseEvent):void
        {
            if(_stepID>=0&&_stepID<=_dataArr.length-1){
                removeBitmap();
                _stepID--;
                if(_stepID < 0){
                    _stepID=-1;
                }else{
                    addBitmap(_stepID);
                }
                
            }
            trace("撤销step:",_stepID);
        }
        /**
         * 重做
         */
        private function onRedo(e:MouseEvent):void
        {
            if(_stepID<=_dataArr.length-1){
                removeBitmap();
                _stepID++;
                if(_stepID >_dataArr.length-1){
                    _stepID = _dataArr.length-1;
                }
                addBitmap(_stepID);
            }
            trace("重做step:",_stepID);
        }
        /**
         * 呈现步骤图像
         */
        private function addBitmap(step:int):void
        {
            var bmp:Bitmap = new Bitmap(_dataArr[_stepID].bmpd.clone());
            addToDisplay(bmp,_list, _dataArr[_stepID].rect.x,_dataArr[_stepID].rect.y);
        }
        /**
         * 移除列表内容
         */
        private function removeBitmap():void
        {
            while(_list.numChildren>0){
                if(_list.getChildAt(0) is Bitmap){
                    (_list.getChildAt(0) as Bitmap).bitmapData.dispose();
                    _list.removeChildAt(0);
                }
            }
        }
        private function onErase(e:MouseEvent):void
        {
            _blendMode = BlendMode.ERASE;
            _thickness = 10;//擦除的粗细
        }
        private function onDraw(e:MouseEvent):void
        {
            _blendMode = BlendMode.NORMAL;
            _thickness = 5;//涂鸦的粗细
        }
        private function creatButton(w:Number,h:Number,color:uint,text:String=""):Sprite
        {
            var button:Sprite = new Sprite();
            button.graphics.beginFill(color,1);
            button.graphics.drawRect(0,0,w,h);
            button.graphics.endFill();
            var t:TextField = new TextField();
            t.autoSize = TextFieldAutoSize.LEFT;
            t.selectable = false;
            t.text = text;
            button.addChild(t);
            t.x = (button.width-t.width)*.5;
            t.y = (button.height-t.height)*.5;
            return button;
        }
        private function addToDisplay(target:DisplayObject,parent:DisplayObjectContainer,x:Number=0,y:Number=0,alpha:Number=1,visible:Boolean = true,scaleX:Number=1,scaleY:Number=1):void
        {
            parent.addChild(target);
            target.x = x;
            target.y = y;
            target.alpha = alpha;
            target.visible = visible;
            target.scaleX = scaleX;
            target.scaleY = scaleY;
        }
    }
}
原文地址:https://www.cnblogs.com/frost-yen/p/5807378.html