原生JS 只要三步实现某东“放大镜”效果

3,636 阅读2分钟

JS “放大镜”效果实现

需求阐述

  1. 用户鼠标移入出现遮罩层(即放大镜),
  2. 同时右侧显现放大同样位置的图片,
  3. 鼠标移出,遮罩层和放大的图片隐藏不见,
  4. 鼠标移动,遮罩层移动,显示大图的位置也移动。
  5. 遮罩层的移动范围只限于图片的容器内部。

效果演示

放大镜.gif

设计思路

  • 鼠标移上图片以后,显示遮罩层以及右盒子
  • 鼠标移出图片以后,隐藏遮罩层以及右盒子
  • 鼠标图片移动的时候, 遮罩层跟随移动
  • 细节1,要在中间
  • 细节2,边界问题, 不能跑出图片内部
  • 细节3,右盒子中的大图片也要跟随移动
    • 获取当前鼠标在让鼠标居中在遮罩层中
    • 边界判断
    • 设置遮罩层偏移量
    • 右盒子里面的图片跟随遮罩层反向移动
    • 设置大图的偏移量

知识栈

HTML CSS简单布局+CSS背景图片基础知识 JS之CSS非行内属性的获取/设置 JS之鼠标事件的绑定 JS之鼠标坐标及元素坐标的获取/设置

代码解析

CSS部分

简单的CSS部分排版,放大镜对排版的要求不是很高;核心部分是实现其效果,像这样的排版不是“有手就行”?

<style>
        * {
            padding: 0;
            margin: 0;
        }

        .box {
            position: relative;
            margin-top: 20px;
            margin-left: 40px;
        }

        .left {
            border: 1px solid #000;
            width: 400px;
            height: 500px;
            position: absolute;
            top: 0;
            left: 0;
            background: url(./images/pic0.jpg);
            background-size: 100% 100%;
            cursor: move;
            position: relative;
        }

        .right {
            border: 1px solid #000;
            width: 400px;
            height: 500px;
            margin-top: 20px;
            margin-left: 40px;
            position: absolute;
            top: 0;
            left: 400px;
            background: url(./images/pic0.jpg) no-repeat;
            background-position-x: 0;
            background-position-y: 0;
        }

        .mark {
            width: 100px;
            height: 100px;
            position: absolute;
            top: 0px;
            left: 0px;
            background-color: pink;
            opacity: 0.3;
        }
    </style>

HTML部分

很简单的HTML部分,会搭建基本的解构就可以了,俗称,“没手都行”。

 <div class="box">
        <div class="left">
            <div class="mark"></div>
        </div>
        <div class="right"></div>
    </div>

JS部分

最简单的js核心部分,“放大镜”的效果实质上就是两张图片的显示隐藏与边距变化(即移动);所以这还不简单吗?你只需要一张小图和一张大图就可以啦哟。哈哈!image.png

<script>
        //获取元素
        var box = document.querySelector(".box");
        var left = document.querySelector(".left");
        var mark = document.querySelector(".mark");
        var right = document.querySelector(".right");
        //
        var boxleft = box.offsetLeft;
        var boxtop = box.offsetTop;


        //鼠标移入显示
        function lover() {
            mark.style.display = "block";
            right.style.display = "block";
        }
        left.addEventListener("mouseover", lover);
        //鼠标移除隐藏
        function lout() {
            mark.style.display = "none";
            right.style.display = "none";
        }
        left.addEventListener("mouseout", lout);
        //鼠标移动
        function mmove(e) {
            //计算滑块移动的距离
            var markleft = e.clientX - box.offsetLeft - mark.offsetWidth / 2;
            var marktop = e.clientY - box.offsetTop - mark.offsetHeight / 2;
            //计算放大图片移动的距离
            var rLeft =markleft* 2160 /(left.offsetWidth - mark.offsetWidth);
            var rTop = marktop* 940 /(box.offsetHeight - mark.offsetHeight);
            // 设置滑块移动的距离
            mark.style.left = markleft + "px";
            mark.style.top = marktop + "px";

            // 设置放大图片移动的距离
            //公式:大图的移动距离=(遮罩层的最大移动距离*大图最大移动距离)/遮罩层最大移动距离
            right.style.backgroundPositionX = -rLeft + "px";
            right.style.backgroundPositionY = -rTop + "px";
            //判断滑块移动的范围
            //左边界
            if (mark.offsetLeft <= 0) {
                markleft = 0;
            }
            // 右边界
            if (mark.offsetLeft > left.offsetWidth - mark.offsetWidth) {
                markleft = left.offsetWidth - mark.offsetWidth;
            }
            // 上边界
            if (mark.offsetTop < 0) {
                marktop = 0;
            }
            // 下边界
            if (mark.offsetTop > box.offsetHeight - mark.offsetHeight) {
                marktop = left.offsetHeight - mark.offsetHeight;
            }
            mark.style.left = markleft + "px";
            mark.style.top = marktop + "px";
        }
        left.addEventListener("mousemove", mmove);
    </script>

最后一句

这是小沉曦自己的学习心得哦!初来乍到,时而腼腆;小小学徒,学识略浅;若有不正,还望斧正。希望渴望正义的你们不要吝啬对我的建议哟。各位回见。