vue.js 3.2.20:拖动创建div及移动、缩放、删除等操作

一,演示项目的代码地址:

https://gitee.com/liuhongdi/move

说明:刘宏缔的架构森林是一个专注架构的博客,

网站:https://blog.imgtouch.com
本文: https://blog.imgtouch.com/index.php/2023/05/28/vue-js-3-2-20-tuo-dong-chuang-jian-div-ji-yi-dong%e3%80%81-suo/

         对应的源码可以访问这里获取: https://github.com/liuhongdi/
         或: https://gitee.com/liuhongdi

说明:作者:刘宏缔 邮箱: 371125307@qq.com

 

二,编写代码:

Home.vue

<template>
<div class="main" >
  <div id="preview" style="float:left;background:url(/static/img/mao.jpeg);background-size:640px;width: 640px; height: 1290px; position: relative;background-color:#FF0004;"
  @mousedown="drawBegin($event)" @mousemove="drawMove($event)" @mouseup="drawEnd($event)">
  </div>
</div>
</template>

<script>
export default {
  name: "Home",
  setup() {
    //let objX
    let objX=null;
    let objY=null;
    let setid=100;

    let isCDown = false;

    let curSetId = 0;

    function getOffsetTop(obj){
      var tmp = obj.offsetTop;
      var val = obj.offsetParent;
      while(val != null){
        tmp += val.offsetTop;
        val = val.offsetParent;
      }
      return tmp;
    }

    function getOffsetLeft(obj){
      var tmp = obj.offsetLeft;
      var val = obj.offsetParent;
      while(val != null){
        tmp += val.offsetLeft;
        val = val.offsetParent;
      }
      return tmp;
    }

    //创建div,开始按下鼠标
    const drawBegin = (event) => {
      let id = event.srcElement.id;
      //console.log('id:'+id);
      if (id !== 'preview') {
          return;
      }

      var objTop = getOffsetTop(document.getElementById("preview"));//对象x位置
      var objLeft = getOffsetLeft(document.getElementById("preview"));//对象y位置
      var scrollTop = window.pageYOffset || document.documentElement.scrollTop ||document.body.scrollTop || 0;
      var mouseX = event.clientX+document.body.scrollLeft;//鼠标x位置
      var mouseY = event.clientY+scrollTop;//鼠标y位置
     //计算点击的相对位置
      objX = mouseX-objLeft;
      objY = mouseY-objTop;
      //生成div
      var oDiv = document.createElement('div');
      oDiv.style.position='absolute';
      oDiv.style.top=objY+'px';
      oDiv.style.left=objX+'px';
      oDiv.style.border='2px solid #000000';
      oDiv.style.background='#ffffff';
      oDiv.style.opacity=0.7;
      oDiv.style.pointerEvents='none';
      oDiv.dataset.origin_l = 0;
      oDiv.dataset.origin_t = 0;
      oDiv.dataset.origin_w = 0;
      oDiv.dataset.origin_h = 0;
      oDiv.id=setid;
      oDiv.style.zIndex=setid;
      document.getElementById("preview").appendChild(oDiv);
    }

    //创建div,移动中
    const drawMove = (event) => {
      //如果在缩放div
      if (isCDown == true){
        //var e = window.event || arguments.callee.caller.arguments[0];
        let e = window.event;
        let nx = e.clientX;
        let ny = e.clientY;
        //console.log('nx:'+nx+";ny:"+ny);
        let nl = nx - cx;
        let nt = ny - cy;
        //console.log('nl:'+nl+";nt:"+nt);

        let destw = parseInt(origin_w)+nl;
        let desth = parseInt(origin_h)+nt;
        //console.log('destw:'+destw+";desth:"+desth);
        document.getElementById(curSetId).style.width = destw+"px";
        document.getElementById(curSetId).style.height = desth+"px";
        return;
      }

      //如果在移动div
      if (isDown == true){
        let e = window.event;
        let nx = e.clientX;
        let ny = e.clientY;
        //计算移动后的左偏移量和顶部的偏移量
        let nl = nx - (x - l);
        let nt = ny - (y - t);
        document.getElementById(curSetId).style.left = nl + 'px';
        document.getElementById(curSetId).style.top = nt + 'px';
        return;
      }

      //如果是在创建div时
      if(objX!=null){

        var objTop = getOffsetTop(document.getElementById("preview"));//对象x位置
        var objLeft = getOffsetLeft(document.getElementById("preview"));//对象y位置

        var scrollTop = window.pageYOffset || document.documentElement.scrollTop ||document.body.scrollTop || 0;

        var mouseX = event.clientX+document.body.scrollLeft;//鼠标x位置
        var mouseY = event.clientY+scrollTop;//鼠标y位置

        //计算点击的相对位置
        let movingX = mouseX-objLeft;
        let movingY = mouseY-objTop;
        if(movingX>=objX){
          document.getElementById(setid).style.width=movingX-objX+'px';
        }else{
          document.getElementById(setid).style.left=movingX+'px';
          document.getElementById(setid).style.width=objX-movingX+'px';
        }
        if(movingY>=objY){
          document.getElementById(setid).style.height=movingY-objY+'px';
        }else{
          document.getElementById(setid).style.top=movingY+'px';
          document.getElementById(setid).style.height=objY-movingY+'px';
        }
      }
    }

    //创建div,停止移动,完成
    const drawEnd = (event) => {
      console.log(event);
      objX=objY=null;
      if (isCDown == true){
        return;
      }

      if (document.getElementById(setid) == null){
        return;
      }

      if ('' == document.getElementById(setid).style.width || ''==document.getElementById(setid).style.height || '0px'==document.getElementById(setid).style.width || '0px'==document.getElementById(setid).style.height) {
        document.getElementById(setid).parentElement.removeChild(document.getElementById(setid));
        return;
      }

      document.getElementById(setid).innerHTML = "<div id='inner"+setid+"' style='pointer-events:auto;width:100%;height:100%;' onMouseDown='divmousedown("+setid+")' onMouseUp='divmouseup("+setid+",0)'  onMouseMove='divmousemoving("+setid+")' ></div>";
      document.getElementById(setid).innerHTML += '<div id="coor'+setid+'" class="coor" onMouseDown="coormousedown('+setid+')" onMouseMove="coormousemoving('+setid+')" onMouseUp="coormouseup('+setid+',0)"></div>';
      document.getElementById(setid).innerHTML += '<div id="edit'+setid+'" class="edit" onclick="edit('+setid+',0)">E</div>';
      document.getElementById(setid).innerHTML += '<div id="del'+setid+'"  class="del" onclick="del('+setid+')">X</div>';
      setid++;
    }

    //coor module for div resize---------------------------------------------------------

    //移动div
    let cx = 0;
    let cy = 0;

    let origin_w ;
    let origin_h ;
    //缩放div,coor按下鼠标,开始
    const coormousedown = (setid) => {
      if (isCDown == true) {
        return false;
      }
      //计算点击的相对位置
      var e = window.event ;
      //获取x坐标和y坐标
      cx = e.clientX;
      cy = e.clientY;

      //获取左部和顶部的偏移量

      origin_w = document.getElementById(setid).style.width;
      origin_h = document.getElementById(setid).style.height;

      isCDown = true;
      curSetId = setid;
    }
    //缩放div,coor松开
    const coormouseup = (setid,content_id) => {
      console.log('===============coormouseup');
      isCDown = false;

      var width = parseInt(document.getElementById(setid).style.width);
      var height = parseInt(document.getElementById(setid).style.height);

      if (content_id>0){
        console.log("width:"+width+";origin_w:"+document.getElementById(setid).dataset.origin_w+";height:"+height+";origin_h:"+document.getElementById(setid).dataset.origin_h);
        if (width == document.getElementById(setid).dataset.origin_w && height == document.getElementById(setid).dataset.origin_h){
          //未修改大小,do nothing
        } else {
          document.getElementById(setid).dataset.origin_w = width;
          document.getElementById(setid).dataset.origin_h = height;
        }

      }
    }

    //缩放div,coor移动中
    const coormousemoving = (setid) => {
      if (isCDown == false){
        return;
      }
      var e = window.event ;
      var nx = e.clientX;
      var ny = e.clientY;
      //计算移动后的左偏移量和顶部的偏移量
      console.log('nx:'+nx+";ny:"+ny);
      var nl = nx - cx;
      var nt = ny - cy;

      var destw = parseInt(origin_w)+nl;
      var desth = parseInt(origin_h)+nt;
      //console.log('destw:'+destw+";desth:"+desth);
      document.getElementById(setid).style.width = destw+"px";
      document.getElementById(setid).style.height = desth+"px";
    }

    window.coormousedown = coormousedown;
    window.coormousemoving = coormousemoving;
    window.coormouseup = coormouseup;

    //移动div   -----------------------------移动手动创建的div
    let x = 0;
    let y = 0;
    let l = 0;
    let t = 0;
    let isDown = false;
    let curDivId = 0;

    //移动div,按下鼠标,开始
    const divmousedown = (id) => {
      if (isDown == true) {
        return false;
      }
      var e = window.event;
      //获取x坐标和y坐标
      x = e.clientX;
      y = e.clientY;

      //获取左部和顶部的偏移量
      l = document.getElementById(id).offsetLeft;
      t = document.getElementById(id).offsetTop;
      //开关打开
      isDown = true;
      curSetId = id;
      curDivId = id;
    }

    //移动div,正在移动时
    const divmousemoving = (id) => {
      if (id!=curDivId) {
        return;
      }
      var e = window.event ;

      if (isCDown == true){
        let nx = e.clientX;
        let ny = e.clientY;
        console.log('nx:'+nx+";ny:"+ny);
        let nl = nx - cx;
        let nt = ny - cy;
        console.log('nl:'+nl+";nt:"+nt);

        var destw = parseInt(origin_w)+nl;
        var desth = parseInt(origin_h)+nt;
        console.log('destw:'+destw+";desth:"+desth);
        document.getElementById(curSetId).style.width = destw+"px";
        document.getElementById(curSetId).style.height = desth+"px";
        return;
      }

      if (isDown == false) {
        return;
      }

//获取x和y
      let nx = e.clientX;
      let ny = e.clientY;
      //计算移动后的左偏移量和顶部的偏移量
      let nl = nx - (x - l);
      let nt = ny - (y - t);
      document.getElementById(id).style.left = nl + 'px';
      document.getElementById(id).style.top = nt + 'px';
    }

    //移动div结束
    const divmouseup = (setid,content_id) => {
      isDown = false;
      //得到它的位置:
      var left = parseInt(document.getElementById(setid).style.left);
      var top = parseInt(document.getElementById(setid).style.top);

      if (content_id>0) {
        if (left == document.getElementById(setid).dataset.origin_l && top == document.getElementById(setid).dataset.origin_t){
          //未修改位置,do nothing
        } else {
          document.getElementById(setid).dataset.origin_l = left;
          document.getElementById(setid).dataset.origin_t = top;
        }
      }
    }

    window.divmousedown = divmousedown;
    window.divmousemoving = divmousemoving;
    window.divmouseup = divmouseup;

    //div的删除功能,加了一个淡出效果
    const del = (idNumber) => {
      if (confirm("确认要删除当前div吗?"+idNumber)) {
        let delDom = document.getElementById(idNumber);
        delDom.style.opacity = 0;
        delDom.style.transition = "all 0.5s";
        setTimeout(function () {
          document.getElementById("preview").removeChild(delDom);
        }, 520);
      }
    }
    window.del = del;
    //div的编辑功能,只写了一个alert
    const edit = (idNumber,contentId) => {
      alert("edit:"+idNumber+":content:"+contentId);
    }
    window.edit = edit;

    return {
      drawBegin,
      drawMove,
      drawEnd,
      coormousemoving,
      coormouseup,
      coormousedown,
      del,
      edit,
    }
  }
}
</script>

<style scoped>
.main {
  width:100vw;
  height:100vh;
  background: #ff0000;
}

/deep/ .coor {pointer-events:auto; width: 10px; height: 10px; overflow: hidden; cursor: se-resize; position: absolute; right: 0; bottom: 0; background-color: #00FFFF; z-index: 5000;}

/deep/ .edit {pointer-events:auto; width: 18px; height: 18px;line-height: 18px; overflow: hidden; cursor: se-resize; position: absolute; left: 0px; bottom: -18px; text-align: center;background-color: #ADFF2F; }
/deep/ .del  {pointer-events:auto; width: 18px; height: 18px;line-height: 18px; overflow: hidden; cursor: se-resize; position: absolute; left: 18px; bottom: -18px;text-align: center; background-color: #09C; }
/deep/ .number  {pointer-events:auto; width: 18px; height: 18px;line-height: 18px; overflow: hidden; cursor: se-resize; position: absolute; left: 0px; top: -18px;text-align: center; background-color: #09C; }

</style>

三,测试效果

四,查看vue的版本:

liuhongdi@lhdpc:/data/vue/move$ npm list vue
move@0.1.0 /data/vue/move
├─┬ @vue/cli-plugin-babel@4.5.14
│ └─┬ @vue/babel-preset-app@4.5.14
│   └── vue@3.2.20 deduped
└─┬ vue@3.2.20
  └─┬ @vue/server-renderer@3.2.20
    └── vue@3.2.20 deduped

 

posted @ 2021-10-29 17:28  刘宏缔的架构森林  阅读(1098)  评论(0编辑  收藏  举报