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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM