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; } } }