Javscript 放大镜效果在边缘“失败”

问题描述 投票:0回答:1

我正在尝试构建放大镜效果。当您将光标移动到图像上时,会显示光标下方图像的放大(即更大)部分。我已经接近我的编码了。我所拥有的一个例子是这样的:

    let zoom = 2;

    window.addEventListener('load', () => {
      const image = document.querySelector('.image'),
        { width, height } = image.getBoundingClientRect(),
        glass = document.createElement('div');

      document.querySelector('.image-wrapper').append(glass);
      glass.classList.add('glass');
      glass.style.backgroundSize = `${zoom * width}px ${zoom * height}px`;
      glass.style.backgroundImage = `url(${image.src})`;

      image.addEventListener('mousemove', (e) => {
        const { offsetX, offsetY } = e,
          glassX = offsetX - glass.offsetWidth / 2,
          glassY = offsetY - glass.offsetHeight / 2;

        glass.style.left = `${glassX}px`;
        glass.style.top = `${glassY}px`;

        glass.style.backgroundPosition = `-${offsetX * zoom}px -${offsetY * zoom}px`;
      });
    });
   body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #f0f0f0;
    }

    .image-wrapper {
      position: relative;
      box-sizing: border-box;
      border: 1px dashed gray;
    }

    .image {
      width: 300px;
      height: auto;
      cursor: none;
    }

    .image-wrapper .glass {
      opacity: 0;
    }

    .image-wrapper:hover .glass {
      opacity: 1;
    }

    .glass {
      position: absolute;
      width: 100px;
      height: 100px;
      border-radius: 50%;
      cursor: none;
      background-repeat: no-repeat;
      pointer-events: none;
      transition: opacity 0.2s;
      border: 1px solid black;
    }
  <div class="image-wrapper">
    <img src="https://i.sstatic.net/JzS3fR2C.jpg" alt="Sample Image" style="opacity: 0.1;" class="image">
  </div>

源图是这样的 Fish

虽然放大镜大部分都可以工作,但它的边缘却“失效”了。当光标到达图像边缘时,我希望玻璃显示图像的“半圆”,另一个半圆是白色的。那就是我想要这个: good

但是我明白了 bad

如何解决这个问题,使其在所有 4 个边缘处都能正常工作?

javascript magnify
1个回答
0
投票

在咬牙切齿之后,我将 mousemove 事件的代码更改为:

    const { offsetX, offsetY } = e,
          gw = glass.offsetWidth / 2,
          gh = glass.offsetHeight / 2;

    glass.style.left = `${offsetX - gw}px`;
    glass.style.top  = `${offsetY - gh}px`;

    const x = -Math.floor((offsetX / width)  * (width * zoom)  - gw),
          y = -Math.floor((offsetY / height) * (height * zoom) - gh);
    
    glass.style.backgroundPosition = `${x}px ${y}px`;
© www.soinside.com 2019 - 2024. All rights reserved.