原生 JS 实现放大镜效果

1,034 阅读1分钟

实现原理 准备小图片和大图片各一张,存放小图片和大图片的容器,有一个半透明的遮罩层;
鼠标移入小图片时,通过捕捉鼠标在小图片上的位置,定位大图片的相应位置;
放大镜的移动方向和大图片的移动方向:横向和纵向都是相反,才可以保证同步;

功能实现效果图如下:

鼠标放上去半透明遮罩层和大图片显示出来效果图:

代码如下:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片放大镜</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }
        
        // 容器布局
        .box {
            position: relative;
            top: 200px;
            left: 200px;
            width: 450px;
            height: 450px;
            display: flex;
            justify-content: center;
            align-items: center;
            border: 1px solid #000;
        }
		
        // 半透明遮罩层
        .mask {
            display: none;
            font-style: normal;
            position: absolute;
            left: 0;
            top: 0;
            width: 220px;
            height: 220px;
            background-color: goldenrod;
            opacity: 0.5;
            cursor: move;
        }

        // 大图片盒子
        .big {
            display: none;
            overflow: hidden;
            position: absolute;
            top: -25px;
            left: 450px;
            width: 500px;
            height: 500px;
            margin-left: 15px;
            border: 1px solid #000;
        }
		
        // 大图片设置为绝对定位(否则图片移动效果无效)
        .bigImg {
            position: absolute;
        }
    </style>
</head>

<body>
    <div class="box">
        <img src="../images/small.jpg" class="small">
        <i class="mask"></i>
        <div class="big">
            <img src="../images/bigImg.jpg" class="bigImg">
        </div>
    </div>

    <script>
    	// 获取元素
        var box = document.querySelector('.box');
        var mask = document.querySelector('.mask');
        var big = document.querySelector('.big');
        var bigImg = document.querySelector('.bigImg');
		
        box.addEventListener('mouseenter', function () {
            mask.style.display = 'block';
            big.style.display = 'block';

            box.addEventListener('mousemove', function (e) {
                // 获取鼠标在盒子中的位置
                var x = e.pageX - box.offsetLeft;
                var y = e.pageY - box.offsetTop;

                // 遮罩层的移动距离  将鼠标在盒子中的位置赋值给遮罩层并将鼠标定位到盒子中间位置
                maskX = x - mask.offsetWidth / 2;
                maskY = y - mask.offsetHeight / 2;

                // 遮罩层的最大移动距离
                maskMax = box.offsetWidth - mask.offsetWidth;
                if (maskX <= 0) {
                    maskX = 0;
                } else if (maskX >= maskMax) {
                    maskX = maskMax;
                }
                if (maskY <= 0) {
                    maskY = 0;
                } else if (maskY >= maskMax) {
                    maskY = maskMax;
                }
                mask.style.left = maskX + 'px';
                mask.style.top = maskY + 'px';

                // 大图片与遮罩层成比例移动    
                // 遮罩层的移动距离/遮罩层的最大移动距离=大图片的移动距离/大图片的最大移动距离
                bigImgMax = bigImg.offsetWidth - big.offsetWidth;
                bigImgX = maskX * bigImgMax / maskMax;
                bigImgY = maskY * bigImgMax / maskMax;
                
                //大图片向相反方向移动
                bigImg.style.left = -bigImgX + 'px';
                bigImg.style.top = -bigImgY + 'px';

            })
        })
        // 鼠标离开小图片盒子  遮罩层、大图片隐藏不显示
        box.addEventListener('mouseleave', function () {
            mask.style.display = 'none';
            big.style.display = 'none';
        })
    </script>
</body>
</html>