html+js实现拖动并等比例修改尺寸的modal弹窗

最近做前端,有个需求,点击列表之中的图片(原图片大小全部为1920x1080),会出现一个弹窗,显示图片,同时这个弹窗可以被鼠标拖动,鼠标指针移到弹窗右下角,会改变指针样式,此时可以拖动并等比例修改弹窗尺寸。

效果图:

代码如下:

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8" />
    <style>
      body,
      html {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        background-color: gainsboro;
      }

      #container {
        /* container内显示图片,原图片为固定比例 1920x1080 等比缩小为768x432 */
        width: 768px;
        height: 432px;
        padding: 3px;
        border: #00cdcd 2px solid;
        box-sizing: content-box;
        position: fixed;
        top: 30%;
        left: 30%;
        background-color: white;
      }

      #img {
        cursor: default;
        width: 100%;
        height: 100%;
        background: #757575;
        z-index: 1;
      }
    </style>
  </head>
  <body>
    <div id="container">
      <!-- 使用div 设置背景图片自适应 -->
      <div
        id="img"
        style="
          background-image: url('img/bg.png');
          background-repeat: no-repeat;
          background-size: contain;
        "
      ></div>
      <!-- 也可以使用img,需要设置无法选中,否则拖动时会误选出现闪烁,而且注意要加上draggable="false" 以免触发图片拖动 -->
      <!-- <img
        id="img"
        src="img/bg.png"
        alt=""
        draggable="false"
        style="user-select: none"
      /> -->
    </div>

    <script>
      let container = document.getElementById("container");
      let img = document.getElementById("img");

      //以下为拖动事件处理代码
      var isDragging = false;
      var startX, startY, modalLeft, modalTop;
      //判断是否拖动窗口
      document.addEventListener("mousemove", detect_dragging);
      function detect_dragging(e) {
        if (isDragging) {
          let deltaX = e.clientX - startX;
          let deltaY = e.clientY - startY;
          container.style.left = modalLeft + deltaX + "px";
          container.style.top = modalTop + deltaY + "px";
        }
      }
      document.addEventListener("mouseup", stop_dragging);
      function stop_dragging(e) {
        isDragging = false;
      }
      //点击图片触发拖动事件
      img.addEventListener("mousedown", start_dragging);
      function start_dragging(e) {
        console.log("startDragging");
        isDragging = true;
        startX = e.clientX;
        startY = e.clientY;
        modalLeft = container.offsetLeft;
        modalTop = container.offsetTop;
      }

      //以下为缩放事件处理代码,也可以将event触发的函数与上面合并,这里为了方便阅读,分开写
      // body监听移动事件
      document.addEventListener("mousemove", detect_resize);
      // 鼠标按下事件
      container.addEventListener("mousedown", start_resize);
      // 鼠标松开事件
      document.addEventListener("mouseup", stop_resize);
      // 是否开启尺寸修改
      let resizeable = false;
      // 鼠标按下时的坐标,并在修改尺寸时保存上一个鼠标的位置
      let clientX, clientY;
      // div可修改的最小宽高
      let minW = 768,
        minH = 432;

      // 鼠标松开时结束尺寸修改
      function stop_resize() {
        resizeable = false;
        document.querySelector("body").style.cursor = "default";
        img.style.cursor = "default";
        console.log("Stop resize");
      }

      // 鼠标按下时开启尺寸修改
      function start_resize(e) {
        let d = getDirection(e);
        //设置为只对右下角的生效
        if (d == "se") {
          console.log("resizeable");
          resizeable = true;
          clientX = e.clientX;
          clientY = e.clientY;
        }
      }

      // 鼠标移动事件 判断是否需要调整大小
      function detect_resize(e) {
        let d = getDirection(e);
        let cursor;

        if (resizeable) {
          //开启拖动鼠标改变大小的之后,无论鼠标移动到哪里,指针样式都不会改变
          container.style.cursor = "se-resize";
          document.querySelector("body").style.cursor = "se-resize";
          img.style.cursor = "se-resize";
          let t = container.offsetWidth + (e.clientX - clientX);
          // 当开启尺寸修改时,鼠标移动会修改div尺寸
          //计算长宽   宽度乘以0.5625即为高度    长宽比为 192:108
          let tmpW = e.clientX - container.offsetLeft;
          let tmpH = Math.round(tmpW * 0.5625);
          let isCountHeight = 0;
          //如果鼠标Y坐标大于计算之后的height,说明以Y坐标为计算标准
          if (tmpH < e.clientY - container.offsetTop) {
            isCountHeight = 1;
          }

          if (isCountHeight == 1) {
            if (e.clientY - container.offsetTop <= minH) {
              container.style.width = minW;
              container.style.height = minH;
            } else {
              tmpH = e.clientY - container.offsetTop;
              tmpW = Math.round(tmpH * 1.7777);
              container.style.width = tmpW + "px";
              container.style.height = tmpH + "px";
            }
          } else {
            if (e.clientX - container.offsetLeft <= minW) {
              container.style.width = minW;
              container.style.height = minH;
            } else {
              container.style.width = tmpW + "px";
              container.style.height = tmpH + "px";
            }
          }
        } else {
          if (d == "se") {
            cursor = "se-resize";
            // 修改鼠标显示效果
            container.style.cursor = cursor;
          } else {
            cursor = "default";
            container.style.cursor = cursor;
          }
        }
      }

      // 获取鼠标所在div的位置
      function getDirection(ev) {
        let xP, yP, offset;

        xP = ev.clientX;
        yP = ev.clientY;
        offset = 30;

        if (
          yP > container.offsetTop + container.offsetHeight - offset &&
          xP > container.offsetLeft + container.offsetWidth - offset
        ) {
          return "se";
        }

        return "";
      }
    </script>
  </body>
</html>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值