JS实现放大镜效果

需求:
鼠标滑过缩略,会显示一个滑块,右侧出现滑块对应的大图部分,就是购物网站商品详情的放大镜效果。
思路:

  • 首先显示缩略图abbre,缩略图上有一个滑块mark
  • 缩略图的右侧是与其对应的具体放大的部分detail,放大的盒子对应着大图片detaiIImg

事件:

  • 鼠标移入缩略图abbre,滑块mark和放大部分detail显示
  • 鼠标移动,可以控制滑块mark在缩略图abbre上的移动
  • 滑块mark移动的距离不能超出缩略图abbre的范围
  • 同时还需要控制大图片detaiIImg在放大部分detail中的移动。

用到的数值:

  • 缩略图abbre的尺寸:300 * 200
  • 滑块mark尺寸:50 * 50
  • 放大部分detail尺寸:300 * 300
  • 大图detaiIImg尺寸:
    • 计算公式 : mark / abbre = detail / detaiIImg
    • detaiIImg = detail /(mark / abbre)

事件:

  • 鼠标移入缩略图abbre,显示滑块mark和放大部分detail
  • 移动滑块mark的位置,控制大图在放大部分的移动(鼠标处于滑块的中间位置)
    • 滑块的位置: mark = 鼠标的位置 = abbre - mark / 2
    • 且mark不可以超出abbre的范围:
      • 最小top / left : 0
      • 最大top / left : abbre - mark
    • 大图的位置:
      • 滑块mark在缩略图abbre中移动的距离A
      • 大图detaiIImg要移动的距离B
      • A / abbre = B / detaiIImg
      • B = (A / abbre) * detaiIImg
      • 大图移动的方向和滑块mark是相反的
  • 鼠标移出缩略图abbre,隐藏滑块mark和放大部分detail

代码

<style>
    .magnifier {position: relative;}        
    .abbre {position: relative;width: 300px;height: 200px;}        
    .abbre img {display: block;width: 100%;height: 100%;}        
    .abbre .mark {position: absolute;top: 0;left: 0;width: 50px;height: 50px;
    background: rgba(255, 255, 255, .4);cursor: move;}        
    .detail {position: absolute;top: 0;left: 300px;width: 300px;height: 300px;
    overflow: hidden;display: none;}        
    .detail img {position: absolute;}
</style>
<section class="magnifier">
    <!-- 缩略图 -->
    <div class="abbre">
        <img src="1.jpg" alt="">
        <!-- MARK遮罩层 -->
        <div class="mark"></div>
    </div>
    <!-- 放大部分 -->
    <div class="detail">
    	<!-- 大图 -->
        <img class="detailImg" src="1.jpg" alt="">
    </div>
</section>
<!-- 需要引入jquery-->
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script>
$(function() {
    // 获取需要操作的元素
    let $magnifier = $(".magnifier"), //放大镜父元素
        $abbre = $magnifier.find(".abbre"), //缩略图
        $mark = $magnifier.find(".mark"), //滑块               
        $detail = $magnifier.find(".detail"), //放大的部分
        $detailImg = $magnifier.find(".detailImg"); //大图
    // 按照比例算出大图的尺寸
    let markW = $mark.width(), //滑块的宽
        markH = $mark.height(), //滑块的高
        abbreW = $abbre.width(), //缩略图的宽
        abbreH = $abbre.height(), //缩略图的高
        imgWidth = 0, //大图的宽
        imgHeight = 0, //大图的高
        detailW = $detail.width(), //放大部分的宽
        detailH = $detail.height(), //放大部分的高
        abbreOffset = $abbre.offset(); //滑块的偏移
    // 动态计算出大图的宽高
    imgWidth = (detailW * abbreW) / markW;
    imgHeight = (detailH * abbreH) / markH;
    // 为大图重新设置样式
    $detailImg.css({
        "width": imgWidth + "px",
        "height": imgHeight + "px"
    });
    // 计算Mark和大图移动的位置
    const computed = function(ev) {
        // 计算Mark移动的位置:ev.pageX / ev.pageY 鼠标的位置
        let curL = ev.pageX - abbreOffset.left - markW / 2,
            curT = ev.pageY - abbreOffset.top - markH / 2;
        // 边界处理
        let minL = 0,
            maxL = abbreW - markW,
            minT = 0,
            maxT = abbreH - markH;
        curT = curT < minT ? minT : (curT > maxT ? maxT : curT);
        curL = curL < minL ? minL : (curL > maxL ? maxL : curL);
        // 缩略框样式的时时修改
        $mark.css({
            "left": curL,
            "top": curT
        });
        // 大图样式的时时修改
        $detailImg.css({
            "left": -curL / abbreW * detailW,
            "top": -curT / abbreH * detailH
        });
    };
    // 添加事件
    $abbre.mouseenter(function(ev) {
            // 鼠标移入,显示大图
            $mark.css("display", "block");
            $detail.css("display", "block");
            computed(ev);
        })
        .mousemove(function(ev) {
            computed(ev);
        })
        .mouseleave(function(ev) {
            // 鼠标移出,隐藏大图
            $mark.css("display", "none");
            $detail.css("display", "none");
        });
});
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值