原生JavaScript实现放大镜效果

84 阅读3分钟

1.编写HTML结构

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

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./index.css">
  <script src="./index.js"></script>
</head>

<body>
  <div class="preview_img">
    <img src="images/s3.png" alt="">
    <!-- 放大镜,黄色遮挡层 -->
    <div class="mask"></div>
    <!-- 出现放大镜效果的大盒子 -->
    <div class="big">
      <img src="images/big.jpg" alt="" class="bigImg">
    </div>
  </div>
</body>

</html>

2.写CSS样式

.preview_img {
  position: relative;
  height: 398px;
  width: 398px;
  border: 1px solid #ccc;
}
/* 放大镜里面的黄色遮挡层 */
.mask {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 300px;
  height: 300px;
  background: #FEDE4F;
  opacity: .5;
  border: 1px solid #ccc;
  cursor: move;
}
/* 出现放大镜效果的大盒子 */
.big {
  display: none;
  position: absolute;
  left: 410px;
  top: 0;
  width: 500px;
  height: 500px;
  background-color: pink;
  z-index: 999;
  border: 1px solid #ccc;
  overflow: hidden;
}

.big img {
  position: absolute;
  top: 0;
  left: 0;
}

3.写JS文件,控制mask盒子的移动,以及大盒子的移动

主要分为以下几步:

第一步:当鼠标经过perview_img盒子时,显示mask黄色盒子、以及有放大镜效果的big盒子,离开时则不显示。

第二步:计算mask盒子的 top、left 值,当鼠标移动的时候 让 mask 盒子跟着鼠标走。

注意,在这里要保证鼠标始终在 mask 盒子的中央,可以给 mask 盒子赋值 鼠标在 previex_img 中的距离 - mask 盒子自身宽度(高度)的一半;其次,还要判断 top 、left 值是否合理,mask 盒子始终应该在 previex_img 盒子内部移动。

第三步:计算大图片的移动距离。

利用公式:遮挡层移动距离 / 遮挡层最大移动距离 = 大盒子移动距离 / 大盒子最大移动距离计算。

window.addEventListener('load', function () {
  var preview_img = document.querySelector('.preview_img');
  var mask = document.querySelector('.mask'); // 在父盒子中定位(把鼠标在盒子内的坐标给mask)
  var big = document.querySelector('.big');
  // 1. 当鼠标经过 preview_img 就显示和隐藏 mask遮挡层和 big大盒子
  preview_img.addEventListener('mouseover', function (e) {
    mask.style.display = 'block';
    big.style.display = 'block';
  });
  preview_img.addEventListener('mouseout', function (e) {
    mask.style.display = 'none';
    big.style.display = 'none';
  });
  // 2. 鼠标移动的时候,让黄色盒子跟着鼠标走
  preview_img.addEventListener('mousemove', function (e) {
    // console.log(111);
    //(1)先计算鼠标在盒子内的坐标: 距离页面中的距离 pageX   - 盒子距离页面的 距离 offsetLeft
    var x = e.pageX - preview_img.offsetLeft;
    var y = e.pageY - preview_img.offsetTop;
    //(2)让黄色盒子跟着鼠标走(计算黄色mask盒子应该移动的距离): 鼠标坐标 - mask盒子的一半 (mask盒子的中心为鼠标位置,因为黄色盒子以鼠标为起点  分别往上、往左走,为负值)
    var maskX = x - mask.offsetWidth / 2;
    var maskY = y - mask.offsetHeight / 2;
    //(3)判断范围是否合理,比如小于0的话 就停在0的位置,大于盒子宽(高) 就停在最右边(下边) 父盒子宽度 - mask盒子的宽度 、父盒子高度 - 黄色盒子的高度【如果大于它,就赋值令其等于它】
    if (maskX <= 0) {
      maskX = 0;
    } else if (maskX >= preview_img.offsetWidth - mask.offsetWidth) {
      maskX = preview_img.offsetWidth - mask.offsetWidth;
    }
    if (maskY <= 0) {
      maskY = 0;
    } else if (maskY >= preview_img.offsetHeight - mask.offsetHeight) {
      maskY = preview_img.offsetHeight - mask.offsetHeight;
    }
    //(4)给mask盒子left、top赋值
    mask.style.left = maskX + 'px';
    mask.style.top = maskY + 'px';
    // 3.遮挡层移动 / 遮挡层移动最大 = 大图片移动 / 大图片移动最大
    // bigImg mask 一定要加定位(才可以给left 和 top),才可以移动
    // 大图片移动 = (遮挡层移动【给mask赋的值】 * 大图片移动最大【大图片宽度 - 大盒子宽度】)/ 遮挡层移动最大【到最低部或最右边时mask的移动距离】[图片宽度是800,盒子是500,两者相减就是盒子的最大移动距离]
    var bigImg = document.querySelector('.bigImg');
    // mask 最大移动
    var maskMax = preview_img.offsetWidth - mask.offsetWidth;
    // 大盒子最大移动
    var bigMax = bigImg.offsetWidth - big.offsetWidth;
    // 大图片移动距离
    var bigX = maskX * bigMax / maskMax;
    var bigY = maskY * bigMax / maskMax;

    bigImg.style.left = -bigX + 'px';
    bigImg.style.top = -bigY + 'px';
  });

})

最终实现效果如下图: