“canvas画布仿window系统自带画图软件"项目的思考

  首先贴上DEMO图,并没有美化效果。对UI有要求的,请自带补脑技术。

    

  思考一

    在做项目的过程中,我发现”工具栏“,"形状栏"中有些功能都需要对canvas元素同时使用onmousedown, onmousemove, onmouseup事件。然后我就使用兼容性添加事件的代码给每个功能添加这几个事件。兼容性代码如下:  

 //添加事件方法
function addEvents(obj, type, func) {
if (obj.addEventListener) {
obj.addEventListener(type, func, false);
} else if (obj.attachEvent) {
obj.attachEvent('on' + type, func);
} else {
obj['on' + type] = func;
}
}
//删除事件方法
function delEvents(obj, type, func) {
if (obj.removeEventListener) {
obj.removeEventListener(type, func, false);
} else if (obj.detachEvent) {
obj.detachEvent('on' + type, func);
} else {
obj['on' + type] = func;
}
}

  结果导致的问题是,我点击某一个功能按钮,其他功能按钮的事件处理程序也会执行。思考了一会,才发现原来使用DOM2级添加事件给元素添加的个数是没有限制的。因此我一触发onmousedown, onmousemove, onmouseup事件,全部代码都会执行。那有没有需要时添加事件,不需要时删除事件的方法呢? 正好有delEvents()方法(如上),所以点击某个按钮,我在事件处理的入口就使用delEvents()方法,就删除按钮具有添加的onmousedown, onmousemove, onmouseup事件,从而保证这三个的事件的处理程序各只有一个。

  贴下部分代码:

 /********工具组的 ‘橡皮擦’按钮操作函数组  Begin ******/
addEvents(oEraser, 'click', beginEraseFun);
function beginEraseFun(evt) {
var e = window.event || evt;
addEvents(mycanvas, 'mousedown', triggerEraser);
addEvents(mycanvas, 'mouseup', EndTriggerEraser);
addEvents(mycanvas, 'mousemove', clearArea);
//删除其他按钮的三个事件
delEventListLine();
.......
}
/* 删除给按钮'线'添加的事件 */
function delEventListLine() {
delEvents(mycanvas, 'mousedown', triggerDrawLine);
.......
}

  这样也就解决了一个事件触发多个处理程序的问题。但是这样写会有大量的冗余的代码。自己感觉也不好,或许会有更好的办法。

  多多看看别人的代码能学习到解题思路,解决方法等。我看了别人的代码是这么写的:

 /*  画直线的函数  */
function line() {
mycanvas.onmousedown = function(evt) {
// 代码
      flag = 1;
}
mycanvas.onmouseup = function(evt) {
// 代码
      flag = 0;
}
mycanvas.onmousemove = function(evt) {
// 代码
      if (flag) {}
}
mycanvas.onmouseout = null;
}

  利用DOM0级添加事件只能有一个事件处理程序的特点,点击不同功能的按钮就调用相应的函数,通过覆盖前面的onmousedown,onmouseup, onmousemove事件属性来添加事件。(如画线的功能,调用line()函数),这样会减少很多的冗余代码,不需要的事件属性可设为null,以备下次使用。

  思考二

     在实现画线功能的过程中,发现了一个问题。就是在onmousedown, 且onmousemove时,鼠标跑到了外面抬起了你按下的鼠标键,那么当你再次回到画布时,还是会接着画,算是一个小BUG。因为你只有在画布中抬起鼠标时,flag值才变为0. 所以解决的办法是在onmouseout()中将flag变为0就OK了。

     顺便提一下在制作“许愿墙”项目中也遇到类似的问题。元素鼠标抬起的时候代码是这样:

$(dragObj).mouseup(function() {  $(this).css('opacity', '1');  });

     导致的问题是当我拖着元素(愿望贴)移动,到达了愿望贴不允许出去的区域,但是鼠标是可接着移动的。鼠标离开了愿望贴,再抬起来。却并没有透明度变为1(如图),还是半透明状态。因此我做了改进:

$(dragObj).mouseup(function() {
$(this).css('opacity', '1');
}).mouseleave(function() {
$(this).css('opacity', '1');
move = false;
});

     增加了mouseleave()事件,一旦移出元素,就让透明度变为1且不允许拖动了。比较好的解决了提出的问题。

  总结

     虽然这些不算是很大的问题,但是在做的时候,确实还是遇到了坎,也花费了时间去思考,为什么会这样,以及如何可以做到更好。或许对于别人来说这简直就是This is a piece of cake. 但是对我说却是意义非凡,因为万丈高楼平地起。

“canvas画布仿window系统自带画图软件"项目的思考的更多相关文章

  1. 励志:98岁老爷爷用Windows系统自带画图软件制作的神作

    哈尔拉斯科,是一位很出名的老爷爷,他70岁才接触MS Paint(就是我们熟知的Windows自带的画图软件).他曾经是一名图形艺术家,但是之前他都是手工创作.他熟知怎么用双手进行艺术创作.但是后来, ...

  2. 仿window系统自带的日期差计算器类

    public class MonthSubstract { /// <summary> /// 日期差之月份 /// </summary> public int Months ...

  3. php调用window系统自带的命令,比如计算器

    1.在cmd命令行输入calc.exe 2.

  4. OSX10.11 删除系统自带的软件

    之前一直用sudo rm - rf 系统的浏览器名字 正常删除safari 升级到10.11后,完全没作用了 需要关闭系统的什么安全模式 csrutil disable 再进入系统使用此命令可正常删除 ...

  5. HTC T329手机如何删除系统自带的软件?HTC一键解锁、获取ROOT权限、豌豆荚删除系统软件

    手头一部HTC T329T手机,机上默认装载的软件实在太多了,居然占用了4页.用360手机卫士并不能删除系统软件(不能获取ROOT权限).查网上查询,总结要删除系统软件步骤如下(本人不刷机,只是想删除 ...

  6. 【读书笔记《Android游戏编程之从零开始》】12.游戏开发基础(Canvas 画布)

    1.Canvas 画布 画布类 Canvas 封装了图形和图片绘制等内容,此类常用的函数说明如下: drawColor(int color) 作用:绘制颜色覆盖画布,常用于刷屏 参数:颜色值,也可用十 ...

  7. 完全参照系统自带的DatePickerDialog、TimePickerDialog的源代码仿写的DateTimePickerDialog

    完全参照系统自带的DatePickerDialog.TimePickerDialog的源代码仿写的DateTimePickerDialog.具有同时选择日期.时间的功能.在2.2.2.3平台,显示的效 ...

  8. win10系统打开自带的画图软件的步骤

    1.win+R打开输入系统命令的输入框 2.输入mspaint即可打开电脑自带的画图软件.

  9. 【HTML5】canvas画布练习

    第一步:获取画布元素 var canvas = document.getElementById("myCanvas"); var context = canvas.getConte ...

随机推荐

  1. hadoop中联结不同来源数据

    装载自http://www.cnblogs.com/dandingyy/archive/2013/03/01/2938462.html 有时可能需要对来自不同源的数据进行综合分析: 如下例子: 有Cu ...

  2. Node.js学习 - CallBack Function

    Node.js异步编程的直接体现就是回调,Node使用了大量的回调函数,其所有的API都支持回调. 阻塞代码实例(同步) var fs = require("fs"); var d ...

  3. apache.commoms.digester3 解析xml文件

    Technorati 标签: java,xml,digester,xmlrule,FromXmlRulesModule 1 简介 java解析xml,就个人所知有3种方法DOM.SAX和Digeste ...

  4. 基于VirtualBox 安装和配置Fuel OpenStack(V6.1)

    1.环境准备 准备一台内存较大的主机,12G以上 下载安装VirtualBox及其匹配的扩展包 virtualbox: http://download.virtualbox.org/virtualbo ...

  5. 转:Selenium Grid+JAVA +Windows 配置(Selenium 2.0)

    Selenium-Grid 允许你在多台机器的多个浏览器上并行的进行测试,也就是说,你可以同时运行多个测试.本质上来说就是,Selenium-Grid 支持分布式的测试执行.它可以让你的测试在一个分布 ...

  6. Mysql笔记5之查询

    1查询所有的列 select *from student 2查询指定列 select name,age from student 3查询时候使用别名 select name as 别名,age as ...

  7. 忘了SA密码的SQL SERVER

    [暂时还未验证] SQL2008  如果 本地连接登录补上,也忘了Sa等管理账号的密码,可以通过单用户连接的方式登录 http://msdn.microsoft.com/zh-cn/library/m ...

  8. 使用MyBatis的Generator自动创建实体类和dao的接口与xml

    在实际的项目中其实建立数据库和设计数据库的时候特别重要,而等数据库设计完成之后,根据数据库创建实体类的工作就特别麻烦和繁琐了,不仅很麻烦,而且很浪费时间,不做又不行,这次就找到了一个简单的方法可以让m ...

  9. offsetXXX和scollXXX的一些操作

    <!doctype html><html><head><meta charset="utf-8"><title>offs ...

  10. python之lambda、filter、map、reduce的用法说明

    python中有一些非常有趣的函数,面试的时候可能会遇到.今天也来总结一下,不过该类的网上资料也相当多,也没多少干货,只是习惯性将一些容易遗忘的功能进行整理. lambda 为关键字.filter,m ...