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


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

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

        

      思考一

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

     1 //添加事件方法
     2 function addEvents(obj, type, func) {
     3    if (obj.addEventListener) {
     4           obj.addEventListener(type, func, false);
     5    } else if (obj.attachEvent) {
     6           obj.attachEvent('on' + type, func);
     7    } else {
     8           obj['on' + type] = func;
     9    }
    10 }
    11 //删除事件方法
    12 function delEvents(obj, type, func) {
    13    if (obj.removeEventListener) {
    14          obj.removeEventListener(type, func, false);
    15    } else if (obj.detachEvent) {
    16          obj.detachEvent('on' + type, func);
    17    } else {
    18          obj['on' + type] = func;
    19    }
    20 }

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

      贴下部分代码:

     1 /********工具组的 ‘橡皮擦’按钮操作函数组  Begin ******/
     2 addEvents(oEraser, 'click', beginEraseFun);
     3 function beginEraseFun(evt) {
     4     var e = window.event || evt;
     5     addEvents(mycanvas, 'mousedown', triggerEraser);
     6     addEvents(mycanvas, 'mouseup', EndTriggerEraser);
     7     addEvents(mycanvas, 'mousemove', clearArea);
     8     //删除其他按钮的三个事件
     9     delEventListLine();
    10     .......
    11 }
    12 /*  删除给按钮'线'添加的事件  */
    13 function delEventListLine() {
    14     delEvents(mycanvas, 'mousedown', triggerDrawLine);
    15     .......
    16 }

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

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

     1 /*  画直线的函数  */
     2 function line() {
     3     mycanvas.onmousedown = function(evt) {
     4        // 代码
          flag = 1;
    5 } 6 mycanvas.onmouseup = function(evt) { 7 // 代码
          flag = 0;
    8 } 9 mycanvas.onmousemove = function(evt) { 10 // 代码
          if (flag) {}
    11 } 12 mycanvas.onmouseout = null; 13 }

      利用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. 但是对我说却是意义非凡,因为万丈高楼平地起。

  • 相关阅读:
    Hyper-V中的VM如何使用Pass-through Disk
    LDF文件丢失, 如何仅用MDF文件恢复数据库呢?
    PowerShell中的一个switch的例子
    NetBiosDomainNamesEnabled与SharePoint User Profile Service Application
    在Windows Server 2008 R2上安装Exchange 2013过程中遇到的一些问题
    C语言位域精解(转)
    uniq命令 (转)
    sort命令
    curl命令(测试连接命令)
    C10K——千万级并发实现的秘密:内核不是解决方案,而是问题所在!(转)
  • 原文地址:https://www.cnblogs.com/cleaverlove/p/6287185.html
Copyright © 2020-2023  润新知