<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta
    name="viewport"
    content="width=device-width, initial-scale=1.0"
  >
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }


    .box {
      position: relative;
      width: 300px;
      height: 300px;
      margin: 40px 0 0 40px;
      user-select: none;

      img {
        width: inherit;
        height: inherit;
      }

      .mask {
        position: absolute;
        z-index: 3;
        width: 100px;
        height: 100px;
        background-color: rgba(255, 255, 0, .6);
        top: 0;
        left: 0;
        opacity: 0;
        transition: opacity .28s;
      }

      .view {
        position: fixed;
        width: 840px;
        height: 840px;
        top: 40px;
        left: 500px;
        z-index: 1;
        overflow: hidden;
        opacity: 0;
        transition: opacity .28s;

        img {
          position: absolute;
          left: 0;
          top: 0;
          width: 2520px;
          height: 2520px;
        }
      }
    }

    .box:hover {

      .mask,
      .view {
        opacity: 1;
      }
    }
  </style>
</head>

<body>
  <div class="box">
    <img src="./1v1.jpg" />
    <div class="mask"></div>

    <div class="view">
      <img src="./1v1.jpg" />
    </div>
  </div>

  <script>
    const box = document.querySelector('.box')
    const view = document.querySelector('.view')
    const mask = document.querySelector('.mask')
    const img = document.querySelector('.view img')

    // 初始鼠标位置
    let x1 = 0
    let y1 = 0
    // 初始偏移量
    let offsetX = 0
    let offsetY = 0
    // 这里有个限制条件是
    // -- >左边mask和显示的图比例是1:3
    // --> 右边view 和 最大的 img 的比例也是1: 3
    // mask最大移动距离
    const maxX = box.clientWidth - mask.clientWidth
    const maxY = box.clientHeight - mask.clientHeight
    // 右边的大图最大移动距离
    const imgX = img.clientWidth - view.clientWidth
    const imgY = img.clientHeight - view.clientHeight
    function handleMove(ev) {
      // 拿到新的坐标
      const x2 = ev.pageX
      const y2 = ev.pageY
      let nx = x2 - x1 + offsetX
      let ny = y2 - y1 + offsetY
      // 边界控制
      nx = nx < 0 ? 0 : nx
      nx = nx > maxX ? maxX : nx
      ny = ny < 0 ? 0 : ny
      ny = ny > maxY ? maxY : ny
      mask.style = `top: ${ny}px;left: ${nx}px;`
      // 赋值右边的大图
      // 计算小图移动占比
      const proportionX = -nx / maxX * imgX
      const proportionY = -ny / maxY * imgX
      img.style = `top: ${proportionY}px; left: ${proportionX}px`
    }

    mask.addEventListener('mousedown', ev => {
      x1 = ev.pageX
      y1 = ev.pageY
      offsetX = mask.offsetLeft
      offsetY = mask.offsetTop
      // 监听鼠标移动事件
      mask.addEventListener('mousemove', handleMove)
    })

    // 这里一定是document,如果是mask,渲染不及时会出现事件移除不掉的情况
    document.addEventListener('mouseup', () => {
      mask.removeEventListener('mousemove', handleMove)
    })

  </script>
</body>

</html>

 

 

原图奉上

 

posted on 2024-03-29 15:49  深海里的星星i  阅读(6)  评论(0编辑  收藏  举报