摘要

贴吧社区上线了用户等级权限系统,“涂鸦”属于“等级权限”项目中的单项权限功能,有助于丰富完善等级权限体系,为高等级用户提供更强大的功能,帮助产出差异化内容。

“涂鸦”使用Actionscript3开发。本文主要介绍功能实现方式和开发过程中值得注意的地方。

TAG

Actionscript3 画图板

术语或简称

AS: Actionscript3.0;

DOOUM: AS的鼠标五个事件,MouseDown、MouseOver、MouseOut、MouseUp、MouseMove事件;

内容

1.分层设计 — 简化的MVC;

2.单例模式;

3.画笔、橡皮擦和背景的实现;

4.撤销、重做的实现;

分层设计

网络层

CheckJsReady:负责初始化时和JS互相确认初始化完毕;

SayToJs:负责ActionScript和JavaScript的交互工作;

ImageUpload: 负责ActionScript和Server的交互;

应用层

1) View & Model 因为View层的元素不会出现多例的情况,View和Model层已结合在一起。

ViewList: 保存所有主要View对象引用,单例;

Paper:涂鸦画板;

ToolPanel: 工具栏,放置涂鸦相关工具;

BackgroundPicture: 画板背景对象;

WaterMarker:涂鸦水印;

2) Control

ControlCore: 控制中心,单例;

分层模型图示(图1)

MVC模型图示(图2)

基本配置文件

BaseConf: 基本配置,包括Flash所有的默认配置;
FunctionalButtonImages: 加载所有的按钮上的Icon图片,默认编译在swf中;
MouseCursorImages: 加载所有的鼠标指针,默认编译在swf中;
MsgList: 消息文本列表,程序所有的提醒消息文本。

单例模式

单例模式可以不用在多个类中产生实例,而只是产生一个实例。单例模式可以实现在多个类中可以共享一个实例的数据。同时也可以避免在多个类中反复创建某个实例的工作,因为实际上我们并不需要也不想要每次都new一遍。

如前面所述,ControlCore和 ViewList均使用的是单例模式。

ControlCore作为控制中心,应该是以一个全局的对象存在。所以它不应该在每个类中都出现一个实例。

ViewList保存的是主要View层对象的引用,其实质是对象引用的List,也应该是一个全局的对象。

在单例模式中,使用单例模式的类应该是无法被实例化的。这样才能保证这个类的正确使用。一般将构造函数定义成私有的(private)即可达到这个目的。但是在AS中,构造函数是无法定义成私有的。所以在AS选择了另一种做法。

例: 以下是 A.as代码

  1. 01 Package {
  2. 02 public class A{
  3. 03 static private var _a:A;
  4. 04 //构造函数需要传入Class N的实例
  5. 05 public function A(n:N){}
  6. 06
  7. 07 public static function g():A{
  8. 08 if(A._a == null) {
  9. 09 A._a = new A(new N());
  10. 10 }
  11. 11 return A._a;
  12. 12 }
  13. 13
  14. 14 public function doSomething():void{}
  15. 15 }
  16. 16 }
  17. 17
  18. 18 //在package外再定义一个类N
  19. 19 Class N{}
说明:
类A的构造函数需要传入类N的实例,但是类N是在A.as中定义的,只有在这个文件才能被访问。这样就保证了,类A的构造函数在A.as以外是无法正常被调用的,类似于构造函数私有化了。
在类A中声明一个私有的属性-类A静态对象,该属性将会在g()方法第一次被调用的时候被定义。g()方法的返回是一个类A的实例化对象,他有类A的所有的属性和方法。所以类A的其他公共方法都可以通过g()的返回值来调用。
这种方式还有一种好处是在g()没有被调用之前,私有的_a是不会被定义的。这样可以不用一开始就占用资源。同样,不把类中A所有方法定义成静态方法也是这个原因。
如 doSomething方法 可以这样调用 A.g().dosomething()。
通过这种形式,在AS中也能很方便的使用单例模式。

画笔、橡皮擦和背景

涂鸦最主要的逻辑实现都集中在Paper上。

一是因为Paper是画纸,是用户主要操作区域;

二是因为当初设计时,没有再进行细分,一些附属的功能也加在Paper里。

画笔

其实实现画笔很简单,监听好鼠标的DOOUM五个事件即可。

在实现上,Paper只是一个容器,装载着已画好的图像和正在画图像。并提供给ControlCore一个提取图像数据的接口当做提交之用。

背景BackgroundPicture处于Paper之下。当用户选择加载本地的图片之后,显示该图片。

大致的层次关系如(图3)所示:

如图所示,在用户开始绘画的时候(触发Paper的MouseDown事件),Paper则会创建一个和自己一般大小的A。Paper通过监听用户鼠标事件获得的鼠标轨迹数据,A通过接口获得数据,并draw出。

由于一些原因,在鼠标快速移入移出Paper的时候会导致笔迹与画纸边界出现断裂的现象。通过监听Paper的MouseOver & MouseOut,在触发这两个事件的时候获取鼠标触发以上两个事件的坐标,在A中进行一些偏差容错的计算,使得笔迹连贯自然。(不过应该有更好的方式来实现)

用户画完后,触发Paper的MouseUp事件。在此时将A的数据与B的数据进行合并,同时将A移除。用户看到的就是最新画好的图像了。

橡皮擦

橡皮擦,可以看做是一种比较独特的画笔。记得以前有一种笔,笔迹是透明的,而且可以把笔迹经过的地方的其他的颜色抹去,很类似这里的橡皮擦。

其实橡皮擦只是在draw的模式上有所区别。

亦如上图。

默认情况下,A的blendMode为BlendMode.Normal,在两层数据合并时的模式也是一样。

用户选择橡皮擦之后, A的BlendMode则被定义为BlendMode.LAYER,在两层数据合并时的模式改为BlendMode. ERASE。

这样用户用橡皮擦“画笔”画过的地方就变成了透明的。

撤销、重做

在最开始设计的时候,思维形成了定式。从表面上看每次撤销和重做,都是回滚或者回退用户操作的某一笔。程序需要操作的是某一笔的信息—笔迹的坐标记录。

实际实现中发现,这样不靠谱。因为一笔可以无限长,这样就会导致撤销和重做会都抖需要遍历一个长度不可控的数组。即便是使用Vector,时间和空间的复杂度都是单位计量*N。

通过参考其他的绘画应用,使用了以下方式来实现撤销和重做,使得时间和空间都变得可控:

为撤销和重做自定义两个固定长度的“队列”。同时插入B的图像初始数据对象(BitmapData)入撤销队列。

在每次A与B的数据合并之后(参考图3),将B的数据对象的副本插入撤销队列。

当用户撤销时将队尾的数据对象弹出并插入重做队列中,再将此时的顶部数据对象显示在B中。

当用户重做时将重做队尾数据对象弹出并插入撤销队列中,并将对象显示在B中。

具体如图 4.1 – 4.3所示,

图4.1 画好的图像压入撤销栈

图4.2 撤销

4.3 重做

从图中可以看出,撤销队列中始终是需要有数据对象的,而且当前队尾的数据对象和当前显示的图像数据对象一致。当确定了撤销的步数为N的之后,那么撤销队列的最大值则为N+1,而重做队列的最大值则为N。
撤销队列满了时,将队头的数据对象弹出并销毁。

by lanbin

【本文首发于:搜索研发部官方博客】http://stblog.baidu-tech.com/?p=1312
【关注百度技术沙龙】
本文转自百度技术51CTO博客,原文链接:http://blog.51cto.com/baidutech/746637,如需转载请自行联系原作者

贴吧涂鸦–毕加索的画板相关推荐

  1. android 涂鸦 卡顿,你的手机里,需要一个好用的涂鸦板:Inkboard

    涂鸦工具还是很必要的 通常情况下,我和我的朋友聊天时会使用大量的表情包,表情包的密度随交流的激烈程度变化.然而表情包存量毕竟有限,无数次我都想扔下手机冲到对方面前直接用脸来表达心中的情感--这显然不是 ...

  2. 在线涂鸦画板小程序源码

    简介: 一款功能简单的在线涂鸦画板小程序源码,可以二次开发 网盘下载地址: http://kekewangLuo.net/VsCTzCLAOVM0 图片:

  3. iOS:quartz2D绘图小项目(涂鸦画板)

    介绍:学了quartz2D的绘图知识后,我根据它的一些功能制作了一个小项目:涂鸦画板. 功能:绘制各种图形,还可以选取相册上的照片做涂鸦,然后保存到相册中.其中,还包括功能有:颜色的选取.线宽的选取. ...

  4. Html5 canvas 简单画布画板涂鸦例子

    简单的Html5 canvas 画板涂鸦例子,巧妙的使用onmousemove 事件来实现画画, 可以实现指定颜色和宽度,如图: <!DOCTYPE HTML> <html>& ...

  5. 电脑PHP动画制作画板,涂鸦板简单实现 Html5编写属于自己的画画板

    这篇文章主要教大家如何使用Html5编写属于自己的画画板,进行绘画.调整颜色等操作,感兴趣的小伙伴们可以参考一下 最近了解到html5强大的绘图功能让我惊奇,于是,写了个小玩意---涂鸦板,能实现功能 ...

  6. iOS 画板 涂鸦 答题

    在开始之前,首先感谢画板(涂鸦)实现 - iOS和iOS 画板/涂鸦 你画我猜 demo (OC版)的作者,在下从他们的的博客中获得了很多启发.还要感谢外国友人提供的 曲线优化策略. 首先从确定实现方 ...

  7. DrawBoard 是一个自定义 View 实现的画板;方便对图片进行各种编辑或涂鸦相关操作

    DrawBoard 项目地址:jenly1314/DrawBoard 简介: :art: DrawBoard 是一个自定义 View 实现的画板:方便对图片进行各种编辑或涂鸦相关操作 更多:作者    ...

  8. 涂鸦画板,监听touch事件,手机端

    通过监听canvas上的touch事件,在canvas上作图 <!DOCTYPE html> <html><head><meta charset=" ...

  9. 自定义view实现涂鸦(画板)功能

    自定义view实现涂鸦功能,包括撤销.恢复.重做.保存以及橡皮擦(在风格中实现)功能,小模块包括画笔颜色调整.画笔尺寸调整.画笔类型(包括正常画笔以及橡皮擦功能),之后又陆续实现了画圆.画矩形以及画箭 ...

最新文章

  1. Shell 环境中的预定义变量
  2. C# 位域[flags]
  3. 从MySQL导入导出大量数据的程序实现方法
  4. iphone储存空间系统怎么清理_如何清理iPhone的缓存,释放更多存储空间,这些方法你知道吗...
  5. careercup-数学与概率 7.7
  6. 盘口的买一是卖股票还是买股票?
  7. POJ NOI MATH-7649 我家的门牌号
  8. java.sql.Date – Java SQL日期
  9. 黑群晖的网络录像机启用并直通互联网的几个关键点
  10. 套管式换热器原理、设计、仿真!附全套资料下载
  11. 统计 | 几种特殊随机变量的分布
  12. HEVC帧内预测学习(一)CTU、CU、PU、TU单元划分的理解
  13. 通俗解释什么是指令集
  14. 系统变慢,如何进行排查处理?
  15. 中国裸眼3D视频广告定制市场动态分析与发展策略研究报告2022-2028年
  16. php图片上传保留第一帧,七牛云上传视频怎么截取第一帧为图片
  17. 你值得安装的24个chrome插件!!!
  18. 小白学习MySQL - 聊聊数据备份的重要性
  19. 假面舞会狂欢节·朗瀚威 | 艺术品化的meme:以传播促进流通
  20. 学校计算机室上机记录,学生上机记录表

热门文章

  1. 速卖通装修html自定义代码,Shopify基础建站教程,独立站装修主题代码设置
  2. vue防抖注册全局_vue防抖节流函数---组件封装,防止按钮多次点击
  3. 2021考研数学真题试卷(数学一)
  4. Toronto Research Chemicals丨艾美捷 A因子分析
  5. 网络广播直播通告:Microsoft Project 2010项目管理概览
  6. 无人值守安装 linux 系统
  7. MVC之Identity身份验证
  8. 颅骨钢板系统的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  9. jquery基础框架
  10. 六度分离 (Floyd)