js 鼠标拖动画矩形

业务需要扫描一些图形点

目录结构

main.html |--  
      img |- main.png
      js  |- jquery.js
           - main.js

效果图
js_rect

居中

首先居中,直接margin:0 auto,没有居中,查看了一下box模型,发现margin都是没有值的。所以给它加了个display: block

<canvas width="900px" height="300px" style="display:block;margin:0 auto">  
     您的浏览器不支持canvas标签。
</canvas>  

canvas点击事件

引用:"由于事件只能达到Canvas元素这一层,所以,如果想进一步深入,识别点击发生在Canvas内部的哪一个图形上,就需要增加代码来进行处理。"

let can = document.getElementById('mycanvas');  
can.addEventListener('click', function(e){  
  //...
}, false);

注意第三个参数false,涉及到冒泡和捕获
下图解释比较清楚,具体看结尾参考
事件模型

接下来获取点击事件在canvas里面的位置

function getEventPosition(ev){  
  var x, y;
  if (ev.layerX || ev.layerX == 0) {
    x = ev.layerX;
    y = ev.layerY;
    //兼容一些浏览器,不支持直接获取鼠标在canvas的相对位置(layer)
  } else if (ev.offsetX || ev.offsetX == 0) { // Opera
    x = ev.offsetX;
    y = ev.offsetY;
  }
  return {x: x, y: y};
}

canvas MouseDown事件

上叙的click其实是不满足题意的,准确的是操作是鼠标 点击按下不放->移动->松开 所以我加了几个状态,分别代表

let ctr = {  
    //NODRAW  点击前,初始状态
    //HASDRAWONE 已经点击过一次状态,正在移动
    //FINISHED  完成状态,目前没用到
    curstatus : "NODRAW",

    curHasTableIndex : [],   //已经有的矩阵点
    curDrawOnePoint : null,  //已经点击过的那个点,即起始点
    curMovePoint : null    //当前正在滑动的鼠标点
}

//mousedown代码如下,其他事件类似

cvs.addEventListener('mousedown', (e) => {  
    let obj = getEventPosition(e);
    if("NODRAW" == ctr.curstatus) {
        ctr.curDrawOnePoint = obj;
        ctr.curstatus = "HASDRAWONE";
    }
    reDraw();
}, false);

添加按钮

  • 添加删除按钮,只要把curDrawOnePoint这个数组pop,重绘即可
  • 添加上传input按钮,其中input控件一直是"选择文件",无法改成其他名称 利用隐藏input的方式

//html
<input id="openInput" type="file" style="display:none">  
<button id="openButton">打开</button>  
//js
$("#openButton").on("click", () => {
    $("#openInput").click();
});

监听载入图片事件

这样写,直接监听

$("#openInput").click("change", () => {
    let reader = new FileReader();
    let file = document.getElementById("openInput").files[0];
    console.log(file);
    if(file) {
        reader.readAsDataURL(document.getElementById("openInput").files[0]);
    }
});

或者下面这样就可以了

//html
<input id="openInput" type="file" value="打开" style="display:none" onchange="triInput(this.id)" >  
//js
function triInput(id) {  
    console.log(document.getElementById(id).files[0]);
}

顺便提一下,当input作为输入框的时候,发生改变的事件应该写成

    $("#openInput").bind("input propertychange", () => {
    });
保存数据
var obj_target = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');  
  if(obj_target)//非ie
{
   obj_target.href = ‘13231内容’;
   obj_target.download = ‘a.txt’;     
   var event = document.createEvent('MouseEvents');
   event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
   obj_target.dispatchEvent(event); 
}
else  
{
    var w = window.open('about:blank');
    w.document.write('1232323内容');  
    w.document.execCommand('Saveas',false,'a.txt');
    w.close();
} 

细节

  1. 比如说,如果按下和放下的是同一个点,就没有必要放在table中
  2. 现在的矩阵没有先后顺序,可以加个索引的按钮
  3. table push点的时候,如果用户是右下角往左上面滑动,那么end点的x,y值是比start点的x,y小

未经同意,禁止转载
本文地址 http://blog.hacking.pub/2016/11/10/js-shu-biao-tuo-dong-hua-ju-xing/

参考