拖拽之网格吸附+放大缩小

上面三个icon分别表示隐藏显示放大
最近项目中有这样一个需求:要求网格中每个块拖拽的时候吸附网格,并且放大缩小相对位置不变,传给后台的坐标信息也一致;

拖拽大家都会,特别简单,但是吸附网格+放大缩小相对信息不变可能会加大一点难度,我自己技术有限,写了一个下午终于算是写出来了,写篇博客记录一下!
附上代码以及稍微一点解释:

//自定义拖拽指令
Vue.directive("drag", {
  update: function(e, value, vNode) {
    var ex, ey;
    var id = value.value.id;
    e.onmousedown = function(e) {
      var ev = e || event;
      //小块-》父级元素的距离
      ex = this.offsetLeft;
      ey = this.offsetTop;
      //鼠标在父元素外相对屏幕的距离 //不固定
      var h = ev.clientX - ex;
      var t = ev.clientY - ey;
      //获取父元素宽高
      var ph = elWrap.clientHeight;
      var pw = elWrap.clientWidth;
      //获取子元素宽高
      var ch = this.clientHeight;
      var cw = this.clientWidth;
      //网格宽度
      var ge = value.value.movelen;
      document.onmousemove = function(e) {
        var evv = e || event;
        //value.value.frameBig=true 放大状态 反之。。
        if (value.value.frameBig == 1) {
          this.style.left =
            ex + Math.round((evv.clientX - h - ex) / 0.4 / ge) * ge + "px";
          this.style.top =
            ey + Math.round((evv.clientY - t - ey) / 0.4 / ge) * ge + "px";
          // 限制可拖拽区域
          if (evv.clientX - (ev.clientX - ex * 0.4) <= 0) {
            this.style.left = "0px";
          } else if (evv.clientX - (ev.clientX - ex * 0.4) >= (pw - cw) * 0.4) {
            this.style.left = pw - cw + "px";
          }
          if (evv.clientY - (ev.clientY - ey * 0.4) <= 0) {
            this.style.top = "0px";
          } else if (evv.clientY - (ev.clientY - ey * 0.4) >= (ph - ch) * 0.4) {
            this.style.top = ph - ch + "px";
          }
        } else if (value.value.frameBig == 2) {
          this.style.left =
            ex + Math.round((evv.clientX - h - ex) / ge) * ge + "px";
          this.style.top =
            ey + Math.round((evv.clientY - t - ey) / ge) * ge + "px";
          // 限制可拖拽区域
          if (evv.clientX - h <= 0) {
            this.style.left = "0px";
          } else if (evv.clientX - h >= pw - cw) {
            this.style.left = pw - cw + "px";
          }
          if (evv.clientY - t <= 0) {
            this.style.top = "0px";
          } else if (evv.clientY - t >= ph - ch) {
            this.style.top = ph - ch + "px";
          }
        }
      }.bind(this);
      document.onmouseup = function(e) {
        let lastX = this.style.left.replace("px", "");
        let lastY = this.style.top.replace("px", "");
        var ev = e || event;
        var upx = ev.clientX - this.offsetLeft;
        var upy = ev.clientY - this.offsetTop;
        var moveL = Math.sqrt((h - upx) * (h - upx) + (t - upy) * (t - upy)); //求斜边移动距离
        document.onmouseup = document.onmousemove = null;
        // console.log(moveL);
        if (moveL > 5) {
          console.log(lastX, lastY); //拖动之后的坐标
          let params = {
            cabinetX: parseFloat(lastX),
            cabinetY: parseFloat(lastY),
            cabinetId: id
          };
          let prom = equipment.updateCabinetXY(params);
          prom.then(
            ret => {},
            err => {}
          );
          value.value.ifClick(false);
        }
        setTimeout(() => {
          value.value.ifClick(true);
        }, 300);
      }.bind(this);
    };
  }
});

1、因为这个网格背景中需要不断添加不同大小的方块并摆放位置,所以我用vue的自定义指令写,指令传了4个参数,分别为当前移动的方块id、每次移动的距离(也就是一个网格的宽度)、当前是拖拽还是单机(因为每个方块同时绑定了单机、双击、拖拽事件,所以为单机和拖拽做区分)、当前的放大缩小情况(与上面icon对应)
只需要看红框中部分
2、在data中给了数据
测试了几种方格宽度为30的时候在页面呈现效果最好
3、吸附网格很简单,思路:方格的定位值=移动了的距离/网格的宽度得到的整数部分*格子的宽度
4、刚开始没有相同怎么去做放大缩小能相对保持不变,不想设置两个尺寸再让里面的方块根据相对位置移动,后来想到了css3的scale,可以在保持占用位置和真实大小不变的情况下等比放大缩小
5、但是鼠标用scale在鼠标拖拽的时候也得乘以或者除以相对应的比例,否则物体不会紧跟着鼠标走
6、目前只是实现功能,代码略显冗杂,后期会优化更新

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值