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

[ActionScript 3.0] AS3.0 涂鸦及擦除功能,撤销重做步骤记录实例的更多相关文章

  1. [ActionScript 3.0] AS3.0和AS2.0的相互通信

    AS3和AS2之间的通信,最好的方式可能就是LocalConnection了. AS2向AS3发送数据,即AS2调用AS3的函数: as2.0代码(按钮上写的发送信息代码): on (release) ...

  2. [ActionScript 3.0] AS3.0 让一个视频无缝循环播放的一个偏方

    一个视频要循环播放,通常的办法都是播放完后再重新播放,但是不可避免的播放结束和重新开始播放这个时间点上会有停顿,如何解决这个问题,说个偏方吧! package com.views { import f ...

  3. [ActionScript 3.0] AS3.0 下雨及涟漪效果

    帧代码: stage.frameRate = 80; function init(x1:Number,y1:Number) { var mc:MovieClip=new MovieClip(); ad ...

  4. [ActionScript] AS3 涂鸦的擦除和撤销功能

    package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BlendMo ...

  5. [ActionScript 3.0] AS3.0 本机鼠标指针

    Flash Player 10.2添加了内置的本机鼠标指针(native mouse cursor)支持,虽然在之前的版本里我们可以侦听MouseEvent事件来模拟鼠标指针,但是在有了原生的本机鼠标 ...

  6. [ActionScript 3.0] AS3.0 动态加载显示内容

    可以将下列任何外部显示资源加载到 ActionScript 3.0 应用程序中: 在 ActionScript 3.0 中创作的 SWF 文件 — 此文件可以是 Sprite.MovieClip 或扩 ...

  7. [ActionScript 3.0] AS3.0 简单封装Socket的通信

    Socket服务器 package com.controls.socket { import com.models.events.AppEvent; import com.models.events. ...

  8. [ActionScript 3.0] AS3.0 Socket通信实例

    以下类是充当Socket服务器的例子 package { import flash.display.Sprite; import flash.events.Event; import flash.ev ...

  9. [ActionScript 3.0] AS3.0 对象在矩形范围随机运动

    package com.views { import flash.display.Bitmap; import flash.display.MovieClip; import flash.displa ...

随机推荐

  1. java_easyui体系之DataGrid(2)[转]

    一:简介 在1的基础上添加layout组件.实现通过条件动态的从后台查询数据到前台展示.使用的方式是将查询单独作为一个layout中的一个面板. 二:关键之处 1.效果图: 2.左侧的折叠组件: 折叠 ...

  2. WinRT知识积累1之读xml数据

    前述:这个知识是在Windows8.1或WP8.1中运用Linq to xml获取一个xml文件里的数据.(网上也很多类似的知识,可以借鉴参考) 平台:windows8.1 metro 或者WP8.1 ...

  3. Google加强版权保护

    在版权保护方面,我们一直是反面教材,而在场面上Google早已退出我们的世界,所以Google的加强版权保护对国内的互联网不会有太多的影响,即便无法在Google搜索到我们需要的XXX软件破解版,百度 ...

  4. SecureCRT清屏

    Ctrl + l:清屏Ctrl + c:终止命令Ctrl + z:挂起命令

  5. Java与数据库之间时间的处理

    Java与数据库之间时间的处理 在数据库中建表: DROP TABLE IF EXISTS `times`; CREATE TABLE `times` ( `id` int(11) NOT NULL ...

  6. Hibernate原生SQL查询多表关联,SQL语句要注意的问题

    Hibernate原生SQL查询多表关联,SQL语句要注意的问题 @for&ever 2009-9-4 系统环境: MySQL5.1 Hibernate3.3 有如下的假定: 实体类 Ques ...

  7. MVC 3.0 Tree

    页面分左右两部分,左边是一个导航树,右边是局部页,点击树节点,异步刷新右边的内容.加颜色部分是知识点. @using VideoWeb.Models@model VideoWeb.Models.Cat ...

  8. PHP中常用的函数

    1.php 字符串截取函数 2.php取得当前时间函数 3.php 字符串长度函数 4.几种php 删除数组元素方法 5.php中var_dump()函数的详解说明 6.PHP preg_match正 ...

  9. C++中的复制构造函数

    与C++中的构造函数相同,复制构造函数在对象生成过程中同样进行插入对应的Vtable虚表,但在成员变量赋值时,除具有复制构造函数的成员对象外,编译器合成复制构造函数其余均采用”Bitwise copy ...

  10. viewPager动态加载listview数据

    废话不多说,先上效果图.(代码见附件) 代码是修改自某大神的,我做了很多修改,之前只能向右滑动,现在可以左右无限滑动,只要数据没加载完就可以一直滑动.过程不算复杂,代码主要的地方都有注释. 附件dem ...