HTML+CSS+JavaScript实现放大镜效果

作者:像素漫游

时间:2026-10-25

浏览:92

本文详细解析如何使用HTML、CSS和JavaScript实现图片放大镜效果。重点讲解鼠标移入移出时的显示控制、mousemove事件中相对坐标的计算原理,特别是absolute定位与transform对offsetLeft/Top的影响。通过数学比例计算实现大图跟随鼠标移动,并限制查看范围,提供完整代码参考。

文章目录

效果演示

本文分享使用HTML、CSS和JavaScript实现图片放大镜功能的具体代码,供读者参考学习。

效果演示

效果演示

JS 详解

JS 详解

HTML结构和CSS样式代码已置于文章末尾的源代码部分,此处仅对JavaScript核心逻辑进行详细解析。

获取操作对象

首先,需要获取需要操作的目标元素:

  • 图片展示框(用于监听鼠标移入事件)
  • 放大镜容器(控制其显示状态及跟随鼠标移动)
  • 放大镜内部图片(根据计算结果改变位置)
let imgShow = document.querySelector('.img-show');  // 图片展示框
let imgLarge = document.querySelector('.img-large');    // 放大镜
let img = document.querySelector('img');    // 放大镜中图片

鼠标移入事件处理

为图片展示框添加事件监听器,当鼠标移入该区域时,使放大镜显示:

imgShow.addEventListener('mouseover', function() {
    // 鼠标移入图片时,显示放大镜
    imgLarge.style.display = "block";
});

鼠标移动事件监听

监听鼠标在图片展示框内移动的事件:

imgShow.addEventListener('mousemove', function(event) {
    // 计算鼠标在图片展示框中相对位置
    let x = event.pageX - this.offsetLeft;
    let y = event.pageY - this.offsetTop;
});

注意:打印输出的x和y值显示,鼠标相对于图片展示框的位置可能出现负数,如下图所示:

效果演示

理论上这些值应为正数。这是因为图片展示框使用了absolute定位,并通过transform进行了二次平移以实现水平垂直居中。暂时注释掉transform的平移效果后再次打印x和y值:

效果演示

此时相对位置均变为正值。这表明transform的平移操作不影响offsetLeft和offsetTop的值。对于absolute定位,offsetLeft和offsetTop仍使用原始位置的值,坐标系也未改变,依然以原始位置的左上角为基准。这就是出现负值的原因,可通过一张动图来理解鼠标相对位置的参考坐标系:

效果演示

理解了x和y值的含义后,即可进行下一步的数学计算。

放大镜跟随鼠标移动实现

接下来实现放大镜跟随鼠标移动的功能:

// 放大镜跟随鼠标移动
imgLarge.style.left = (x + 480 - 125)+'px';
imgLarge.style.top = (y + 270 - 125)+'px';

基于上述坐标系,(x + 480)用于让放大镜始终跟随鼠标,(- 125)用于让鼠标指针始终保持在放大镜的中心位置(因为放大镜宽度为250px)。若不理解,可先移除+480和-125查看效果,再逐个添加观察变化。此处不再演示。

限制查看范围

限制放大镜的查看范围:

// 放大镜超出范围后消失
if (x < -480 || x > 480 || y < -270 || y > 270) {
    imgLarge.style.display = "none";
}

内部图片移动计算

放大镜中图片的移动:

// 放大镜中图片位置的移动
img.style.left = (-(x+480)*2 + 125)+'px';
img.style.top = (-(y+270)*2 + 125)+'px';

原理是计算两张图片之间的比例,根据鼠标在图片展示框中的相对位置,计算出放大镜中图片的位置偏移量,从而实现图片的移动。

  • (x+480)用于回归原始位置坐标系
  • *2表示两张图片的比例
  • -(x+480)*2添加负号是为了实现同方向移动,否则移动方向相反,可自行尝试验证。
  • +125如果不添加,会发现放大位置与原始位置不对齐,可自行尝试验证。

源代码

源代码

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>放大镜效果</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            background: url(./images/bg.jpg);
            background-size: cover;
        }
        /* 背景图片高斯模糊 */
        body::before {
            content: "";
            position: absolute; /* 一定要用绝对定位 */
            width: 100%;
            height: 100%;
            backdrop-filter: blur(30px); /* 模糊半径 */
        }
        .img-show {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 960px;
            height: 540px;
            border: 2px solid #bebebe;
            border-radius: 15px;
            box-shadow: 8px 8px 20px rgba(0, 0, 0, .3), -8px -8px 20px rgba(0, 0, 0, .3);
            background: url(./images/show.jpg);
            background-size: cover;
        }
        .img-show .img-large {
            display: none;
            position: absolute;
            width: 250px;
            height: 250px;
            border: 2px solid #bebebe;
            border-radius: 125px;
            overflow: hidden;
            background-color: #fff;
        }
        /* 放大镜中间的准心 */
        .img-show .img-large::after {
            content: "+";
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            color: #3e3e3e;
            font-size: 30px;
        }
        /* 放大镜显示时隐藏鼠标指针 */
        .img-show .img-large:hover {
            cursor: none;
        }
        .img-show .img-large img {
            position: absolute;
            width: 1920px;
            border-radius: 15px;
        }
    </style>
</head>
<body>
    <div class="img-show">
        <div class="img-large">
            <img src="./images/show.jpg" alt="">
        </div>
    </div>
    <script>
        // 获取需要操作的对象
        let imgShow = document.querySelector('.img-show');
        let imgLarge = document.querySelector('.img-large');
        let img = document.querySelector('img');
​
        // 鼠标移入图片时,显示放大镜
        imgShow.addEventListener('mouseover', function() {
            imgLarge.style.display = "block";
        });
​
        // 放大镜跟随鼠标移动
        imgShow.addEventListener('mousemove', function(event) {
            // 计算鼠标在图片展示框中相对位置
            let x = event.pageX - this.offsetLeft;
            let y = event.pageY - this.offsetTop;
            // 放大镜跟随鼠标移动
            imgLarge.style.left = (x + 480 - 125)+'px';
            imgLarge.style.top = (y + 270 - 125)+'px';
            // 放大镜超出范围后消失
            if (x < -480 || x > 480 || y < -270 || y > 270) {
                imgLarge.style.display = "none";
            }
            // 放大镜中图片位置的移动
            img.style.left = (-(x+480)*2 + 125)+'px';
            img.style.top = (-(y+270)*2 + 125)+'px';
        });
    </script>
</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章