• vue.js:拖动四个角及四个边来改变选区大小并移动(vue@3.2.36)


    一,js代码:

    <template>
      <div style="background: #ffffff;" id="root" @mousemove="onMove" @mouseup="onEnd">
        <div id="wrapper" style="position: relative;300px;overflow: hidden;margin-left:100px;margin-top:30px;" >
          <img id="img" src="static/image/back@2x.jpg" style="300px;display: block;" />
    
          <div id="mask" class="mask" @mousedown="maskDown" >
    
            <div id="coor_tl" class="coor_tl" @mousedown="coormousedown_tl"  ></div>
            <div id="coor_tm" class="coor_tm" @mousedown="coormousedown_tm"   ></div>
            <div id="coor_tr" class="coor_tr" @mousedown="coormousedown_tr"   ></div>
    
            <div id="coor_ml" class="coor_ml" @mousedown="coormousedown_ml"  ></div>
            <div id="coor_mr" class="coor_mr" @mousedown="coormousedown_mr"  ></div>
    
            <div id="coor_bl" class="coor_bl" @mousedown="coormousedown_bl"  ></div>
            <div id="coor_bm" class="coor_bm" @mousedown="coormousedown_bm"   ></div>
            <div id="coor_br" class="coor_br" @mousedown="coormousedown_br"   ></div>
          </div>
    
        </div>
      </div>
    </template>
    
    <script>
    import {onMounted, ref} from "vue"
    export default {
      name: "DragImg",
      setup() {
        // 当前操作的类型,标记当前要拖动的区域
        const operateType = ref("");
    
        //记录点击时的x位置
        const clickX = ref(0);
        //记录点击时的y位置
        const clickY = ref(0);
    
        //从event中得到位置
        const getLocation = (e) => {
          return {
            x: e.x || e.clientX,
            y: e.y || e.clientY
          }
        }
    
        //容器的位置x
        const wrapper_x = ref(0);
        //容器的位置y
        const wrapper_y = ref(0);
        //容器的宽度
        const wrapper_w = ref(0);
        //容器的高度
        const wrapper_h = ref(0);
    
        //鼠标在coor上面按下时的处理函数
        const onDragDown = (e, type) => {
          e.stopPropagation();
          console.log("begin onDragDown");
    
          origin_w.value = document.getElementById('mask').getBoundingClientRect().width;
          origin_h.value = document.getElementById('mask').getBoundingClientRect().height;
    
          origin_x.value = document.getElementById('mask').getBoundingClientRect().left;
          origin_y.value = document.getElementById('mask').getBoundingClientRect().top;
    
          wrapper_x.value = document.getElementById('wrapper').getBoundingClientRect().left;
          wrapper_y.value = document.getElementById('wrapper').getBoundingClientRect().top;
    
          wrapper_w.value = document.getElementById('wrapper').getBoundingClientRect().width;
          wrapper_h.value = document.getElementById('wrapper').getBoundingClientRect().height;
    
          var location = getLocation(e);
          clickY.value = location.y;
          clickX.value = location.x;
          operateType.value = type;
          return false;
        };
    
        //鼠标松开时的事件
        const onDragUp = () => {
          document.body.style.cursor = "auto";
          operateType.value = null;
        };
        //coor鼠标按下:底部左侧
        const coormousedown_bl = (e) => {
          onDragDown(e, "bl");
        };
        //coor鼠标按下:底部中间
        const coormousedown_bm = (e) => {
          onDragDown(e, "b");
        };
        //coor鼠标按下:底部右侧
        const coormousedown_br = (e) => {
          onDragDown(e, "br");
        };
        //coor鼠标按下:顶部左侧
        const coormousedown_tl = (e) => {
          onDragDown(e, "tl");
        };
        //coor鼠标按下:顶部中间
        const coormousedown_tm = (e) => {
          onDragDown(e, "t");
        };
        //coor鼠标按下:顶部右侧
        const coormousedown_tr = (e) => {
          onDragDown(e, "tr");
        };
        //coor鼠标按下:中部左侧
        const coormousedown_ml = (e) => {
          onDragDown(e, "l");
        };
        //coor鼠标按下:中部右侧
        const coormousedown_mr = (e) => {
          onDragDown(e, "r");
        };
    
        //coor,向右侧拖动
        const setMoveR = (location) => {
          let mask = document.getElementById('mask');
          var disHe = location.x - clickX.value;
          //console.log("disHe:"+disHe);
          var widthe = origin_w.value+disHe;
          //console.log("origin_x:"+origin_x.value+";wrapper_w:"+wrapper_w.value);
          if (((origin_x.value-wrapper_x.value)+widthe) > wrapper_w.value) {
            widthe = wrapper_w.value-(origin_x.value-wrapper_x.value);
          }
    
          mask.style.width =  widthe+ 'px';
        }
        //coor,向底部拖动
        const setMoveB = (location) => {
          let mask = document.getElementById('mask');
          var disVs = location.y - clickY.value;
          //console.log("disVs:"+disVs);
          var heights = (origin_h.value+disVs);
          if (((origin_y.value-wrapper_y.value)+heights) > wrapper_h.value) {
            heights = wrapper_h.value-(origin_y.value-wrapper_y.value);
          }
    
          mask.style.height = heights + 'px';
        }
        //coor,向左侧拖动
        const setMoveL = (location,disX) => {
          let mask = document.getElementById('mask');
          //console.log("disX:"+disX);
          if (disX >= 0) {
            var disH = location.x - clickX.value;
            //console.log("disH:"+disH);
            var widthw = origin_w.value-disH;
            //console.log("location.x:"+location.x+";clickX.value:"+clickX.value+";origin_w.value:"+origin_w.value+";widthw:"+widthw);
            mask.style.width =  widthw+ 'px';
          }
    
          if (disX >= 0) {
            mask.style.left = disX + 'px';
          } else {
            mask.style.left =  '0px';
          }
        }
    
        //coor,向顶部拖动
        const setMoveT = (location,disY) => {
          let mask = document.getElementById('mask');
          //console.log("disY:"+disY);
          if (disY >= 0) {
            var disV = location.y - clickY.value;
            var heightn = origin_h.value - disV;
            //console.log("location.y:" + location.y + ";clickY.value:" + clickY.value + ";origin_h.value:" + origin_h.value + ";heightn:" + heightn);
            mask.style.height = heightn + 'px';
          }
          if (disY >= 0) {
            mask.style.top = disY + 'px';
          } else {
            mask.style.top =  '0px';
          }
        }
    
        //mask可以移动到的最右位置
        const rightMax = ref(0);
        //mask可以移动到的最下位置
        const bottomMax = ref(0);
    
        //移动mask的方法
        const setMoveMask = (location) => {
    
          var nx = location.x;
          var ny = location.y;
          //计算移动后的左偏移量和顶部的偏移量
          var nl = nx - (clickX.value - origin_x.value) - wrapper_x.value;
          var nt = ny - (clickY.value - origin_y.value) - wrapper_y.value;
    
          if (nl < 0) {
            nl = 0;
          }
          if (nl > rightMax.value) {
            nl = rightMax.value;
          }
          if (nt < 0) {
            nt = 0;
          }
          if (nt > bottomMax.value) {
            nt = bottomMax.value;
          }
    
          document.getElementById("mask").style.left = nl + 'px';
          document.getElementById("mask").style.top = nt + 'px';
        }
    
        //鼠标移动的通用处理方法
        const move = (operateType, location) => {
          let disY = (origin_y.value + (location.y - clickY.value))-wrapper_y.value;
          let disX = (origin_x.value + (location.x - clickX.value))-wrapper_x.value;
    
          switch (operateType) {
            case "r":
              setMoveR(location);
              break;
            case "b":
              setMoveB(location);
              break;
            case "l":
              setMoveL(location,disX);
              break;
            case "t":
              setMoveT(location,disY);
              break;
            case "br":
              setMoveB(location);
              setMoveR(location);
              break;
            case "tr":
              setMoveT(location,disY);
              setMoveR(location);
              break;
            case "tl":
              setMoveT(location,disY);
              setMoveL(location,disX);
              break;
            case "bl":
              setMoveB(location);
              setMoveL(location,disX);
              break;
            case "mask":
              setMoveMask(location);
              break;
          }
        };
    
        //当页面中鼠标移动时触发
        const onDragMove = (e) => {
            var location = getLocation(e);
            switch (operateType.value) {
              case "t":
                move("t", location);
                break;
              case "b":
                move("b", location);
                break;
              case "l":
                move("l", location);
                break;
              case "r":
                move("r", location);
                break;
              case "tl":
                move("tl", location);
                break;
              case "tr":
                move("tr", location);
                break;
              case "bl":
                move("bl", location);
                break;
              case "br":
                move("br", location);
                break;
              case "mask":
                move("mask", location);
                break;
            }
          return false;
        };
    
        //mask的宽度
        const origin_w = ref(0);
        //mask的高度
        const origin_h = ref(0);
        //mask的x
        const origin_x = ref(0);
        //mask的y
        const origin_y = ref(0);
    
        // mounted,页面加载成功的生命周期
        onMounted(()=>{
          document.onmousemove = onDragMove;
          document.onmouseup = onDragUp;
        })
    
        //当鼠标在mask区域中按下时触发
        const maskDown = (e) => {
          console.log("-------------------maskdown begin");
          var location = getLocation(e);
          clickY.value = location.y;
          clickX.value = location.x;
    
          operateType.value = 'mask';
    
          origin_w.value = document.getElementById('mask').getBoundingClientRect().width;
          origin_h.value = document.getElementById('mask').getBoundingClientRect().height;
    
          origin_x.value = document.getElementById('mask').getBoundingClientRect().left;
          origin_y.value = document.getElementById('mask').getBoundingClientRect().top;
    
          wrapper_x.value = document.getElementById('wrapper').getBoundingClientRect().left;
          wrapper_y.value = document.getElementById('wrapper').getBoundingClientRect().top;
    
          wrapper_w.value = document.getElementById('wrapper').getBoundingClientRect().width;
          wrapper_h.value = document.getElementById('wrapper').getBoundingClientRect().height;
    
          rightMax.value = wrapper_w.value-origin_w.value;
          bottomMax.value = wrapper_h.value-origin_h.value;
        }
    
        return {
          coormousedown_bl,
          coormousedown_bm,
          coormousedown_br,
    
          coormousedown_tl,
          coormousedown_tm,
          coormousedown_tr,
    
          coormousedown_ml,
          coormousedown_mr,
          onDragUp,
    
          maskDown,
        }
      }
    }
    </script>
    
    <style scoped>
    
    .coor_ml {
      width: 10px;
      height: 10px;
      overflow: hidden;
      position: absolute;
      left: 0; top: calc(50% - 5px);
      background-color: #ffFFFF;
      opacity: 0.2;
      z-index: 5000;
      cursor:w-resize;
    }
    
    .coor_mr {
      width: 10px;
      height: 10px;
      overflow: hidden;
      position: absolute;
      right: 0; top: calc(50% - 5px);
      background-color: #ffFFFF;
      opacity: 0.2;
      z-index: 5000;
      cursor:e-resize;
    }
    
    .coor_tl {
      width: 10px;
      height: 10px;
      overflow: hidden;
      position: absolute;
      left: 0; top: 0;
      background-color: #ffFFFF;
      opacity: 0.2;
      z-index: 5000;
      cursor:nw-resize;
    }
    
    .coor_tm {
      width: 10px;
      height: 10px;
      overflow: hidden;
      position: absolute;
      left: calc(50% - 5px); top: 0;
      background-color: #ffFFFF;
      opacity: 0.2;
      z-index: 5000;
      cursor:n-resize;
    }
    
    .coor_tr {
      width: 10px;
      height: 10px;
      overflow: hidden;
      position: absolute;
      right: 0; top: 0;
      background-color: #ffFFFF;
      opacity: 0.2;
      z-index: 5000;
      cursor:ne-resize;
    }
    
    .coor_bl {
      width: 10px;
      height: 10px;
      overflow: hidden;
      position: absolute;
      left: 0; bottom: 0;
      background-color: #ffFFFF;
      opacity: 0.2;
      z-index: 5000;
      cursor:sw-resize;
    }
    
    .coor_bm {
      width: 10px;
      height: 10px;
      overflow: hidden;
      position: absolute;
      left: calc(50% - 5px); bottom: 0;
      background-color: #ffFFFF;
      opacity: 0.2;
      z-index: 5000;
      cursor:s-resize;
    }
    
    .coor_br {
      width: 10px;
      height: 10px;
      overflow: hidden;
      position: absolute;
      right: 0; bottom: 0;
      background-color: #ffFFFF;
      opacity: 0.2;
      z-index: 5000;
      cursor:se-resize;
    }
    
    .mask {
      position: absolute;
      width:100px;
      height:100px;
      left:50px;
      top:250px;
      box-shadow: 0 0 0 999vw rgba(0, 0, 0, .5);
    }
    </style>

    说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

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

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

    二,测试效果

    三,查看vue.js的版本:

    liuhongdi@lhdpc:/data/vue/imgtouch$ npm list vue
    imgtouch@0.1.0 /data/vue/imgtouch
    ├─┬ @vue/cli-plugin-babel@5.0.4
    │ └─┬ @vue/babel-preset-app@5.0.4
    │   └── vue@3.2.36 deduped
    ├─┬ element-plus@2.2.2
    │ ├─┬ @element-plus/icons-vue@1.1.4
    │ │ └── vue@3.2.36 deduped
    │ ├─┬ @vueuse/core@8.6.0
    │ │ ├─┬ @vueuse/shared@8.6.0
    │ │ │ └── vue@3.2.36 deduped
    │ │ ├─┬ vue-demi@0.13.1
    │ │ │ └── vue@3.2.36 deduped
    │ │ └── vue@3.2.36 deduped
    │ └── vue@3.2.36 deduped
    └─┬ vue@3.2.36
      └─┬ @vue/server-renderer@3.2.36
        └── vue@3.2.36 deduped
  • 相关阅读:
    IDA断点和搜索
    shell grep正则匹配汉字
    吐槽一下jsoup
    mysql函数
    hutools之批量更新
    Hutools之http工具类
    Java通过腾讯邮箱发送邮件
    访问网络资源的方式--application/json和x-www-form-urlencoded
    HttpClient获取数据
    URLConnection类的使用
  • 原文地址:https://www.cnblogs.com/architectforest/p/16355214.html
Copyright © 2020-2023  润新知