JS实现商城商品放大镜效果

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

highlight: a11y-dark

整体代码在最下方
放大镜特效如图(这种效果一般只有pc端的商品详情展示能用到 )

在这里插入图片描述

做法:
主要通过外层div的onmousemove事件获取X,Y坐标,同时设置蒙版的位置,做到蒙版跟随鼠标移动,再将右侧大图的位置根据一定的比例缩放移动,显示对应位置的图片。

HTML
通过监听.preview-box的onmousemove,给里面的.mask元素设置位置,当执行onmousemove时,让.mask元素显现,.mask默认隐藏,用visibility: hidden;让其隐藏,因为后面会用到.mask元素的宽高,所以不能使用display:none让其隐藏,然后禁止.mask的鼠标事件因为会跟外层的onmousemove冲突,需要给.mask设置 pointer-events: none;移除其鼠标事件。

<body>
  <div class="container">
    <div class="preview-box">
      <img src="img/img.png" alt="">
      <div class="mask"></div>
    </div>
    <div class="big-box">
      <img class="big-img" src="img/img.png" alt="">
    </div>
  </div>
</body>

.mask样式如图
当鼠标放上去之后显示蒙版跟右侧大图

 .preview-box .mask {
      position: absolute;
      top: 0;
      left: 0;
      width: 120px;
      height: 120px;
      background-color: aqua;
      opacity: 0.5;
      /* 使用 display: none; 在 js 中无法获取元素的宽高 */
      visibility: hidden;
      /* 取消蒙板的鼠标事件 */
      pointer-events: none;
    }
    .preview-box:hover .mask { 
    visibility: visible; 
    } 
    .preview-box:hover+.big-box { 
    visibility: visible; 
    }

JS
获取外层.preview-box跟.mask元素
然后获取预览区域的内容大小,蒙板大小
获取放大显示区的大小,计算放大的倍数,设置大图的大小

根据 move 事件获取鼠标位置,动态设置蒙板位置
将鼠标的坐标位置转换为蒙板定位的位置,将鼠标控制在蒙板的中心,将鼠标位置的边缘进行处理
最终将处理过的值最终设置为样式,根据蒙板的位置确定大图的位置

获取预览区域的内容大小

  var previewBox = document.querySelector('.preview-box');
  var mask = document.querySelector('.mask');
  var previewWidth = previewBox.clientWidth;
  var previewHeight = previewBox.clientHeight;
  var bigBox = document.querySelector('.big-box');
  var bigImg = document.querySelector('.big-img');

获取蒙板大小

  var maskWidth = mask.offsetWidth;
  var maskHeight = mask.offsetHeight;

获取放大显示区的大小

 var bigWidth = bigBox.clientWidth;
 var bigHeight = bigBox.clientHeight;

计算放大的倍数

var scale = bigWidth / maskWidth;

设置大图的大小

bigImg.style.width = previewWidth * scale + 'px';
bigImg.style.height = previewHeight * scale + 'px';

根据 move 事件获取鼠标位置

previewBox.onmousemove = function (e) {
  // 鼠标位置
  var mouseX = e.offsetX;
  var mouseY = e.offsetY;
 } 

动态设置蒙板位置,将鼠标的坐标位置转换为 蒙板定位的位置
将鼠标控制在蒙板的中心

 var maskLeft = mouseX - maskWidth / 2;
 var maskTop = mouseY - maskHeight / 2;

将蒙版位置进行边缘处理

    maskLeft = maskLeft < 0 ? 0 : maskLeft;
    maskLeft = maskLeft > (previewWidth - maskWidth) ? (previewWidth - maskWidth) : maskLeft;
    maskTop = maskTop < 0 ? 0 : maskTop;
    maskTop = maskTop > (previewHeight - maskHeight) ? (previewHeight - maskHeight) : maskTop;

将处理过的值最终设置为样式

 mask.style.left = maskLeft + 'px';
 mask.style.top = maskTop + 'px';

根据蒙板的位置确定大图的位置

bigImg.style.left = -maskLeft * scale + 'px';
bigImg.style.top = -maskTop * scale + 'px';

整体代码

<!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>
  <style>
    .container {
      position: relative;
      width: 300px;
      height: 300px;
      border: 2px solid #666;
    }

    .preview-box {
      position: relative;
      width: 100%;
      height: 100%;
    }

    .preview-box img {
      display: block;
      width: 100%;
      height: 100%;
      pointer-events: none;
    }

    .preview-box .mask {
      position: absolute;
      top: 0;
      left: 0;
      width: 120px;
      height: 120px;
      background-color: aqua;
      opacity: 0.5;
      /* 使用 display: none; 在 js 中无法获取元素的宽高 */
      visibility: hidden;
      /* 取消蒙板的鼠标事件 */
      pointer-events: none;
    }

    .preview-box:hover .mask {
      visibility: visible;
    }

    .preview-box:hover+.big-box {
      visibility: visible;
    }

    .big-box {
      visibility: hidden;
      position: absolute;
      top: -2px;
      left: 300px;
      width: 500px;
      height: 500px;
      border: 2px solid #666;
      overflow: hidden;
    }

    .big-box .big-img {
      position: absolute;
      width: 100%;
      height: 100%;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="preview-box">
      <img src="img/img.png" alt="">
      <div class="mask"></div>
    </div>
    <div class="big-box">
      <img class="big-img" src="img/img.png" alt="">
    </div>
  </div>
</body>
<script>
  var previewBox = document.querySelector('.preview-box');
  var mask = document.querySelector('.mask');

  // 获取预览区域的内容大小
  var previewWidth = previewBox.clientWidth;
  var previewHeight = previewBox.clientHeight;
  var bigBox = document.querySelector('.big-box');
  var bigImg = document.querySelector('.big-img');

  // 获取蒙板大小
  var maskWidth = mask.offsetWidth;
  var maskHeight = mask.offsetHeight;

  // 获取放大显示区的大小
  var bigWidth = bigBox.clientWidth;
  var bigHeight = bigBox.clientHeight;

  // 计算放大的倍数
  var scale = bigWidth / maskWidth;

  // 设置大图的大小
  bigImg.style.width = previewWidth * scale + 'px';
  bigImg.style.height = previewHeight * scale + 'px';
  // 根据 move 事件获取鼠标位置
  previewBox.onmousemove = function (e) {
    // 鼠标位置
    var mouseX = e.offsetX;
    var mouseY = e.offsetY;

    // 动态设置蒙板位置,将鼠标的坐标位置转换为 蒙板定位的位置
    // 将鼠标控制在蒙板的中心
    var maskLeft = mouseX - maskWidth / 2;
    var maskTop = mouseY - maskHeight / 2;
    // // 边缘处理
    maskLeft = maskLeft < 0 ? 0 : maskLeft;
    maskLeft = maskLeft > (previewWidth - maskWidth) ? (previewWidth - maskWidth) : maskLeft;
    maskTop = maskTop < 0 ? 0 : maskTop;
    maskTop = maskTop > (previewHeight - maskHeight) ? (previewHeight - maskHeight) : maskTop;

    // 将处理过的值最终设置为样式
    mask.style.left = maskLeft + 'px';
    mask.style.top = maskTop + 'px';

    // 根据蒙板的位置确定大图的位置
    bigImg.style.left = -maskLeft * scale + 'px';
    bigImg.style.top = -maskTop * scale + 'px';
  }
</script>

</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

“诗和远方”

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值