核心原理
无论哪种方法,放大镜的核心原理都离不开以下几点:

(图片来源网络,侵删)
-
三个基本元素:
- 原图: 用户看到的正常大小的图片。
- 放大镜区域: 一个在原图上移动的半透明区域,显示放大的部分。
- 放大图: 一张比原图分辨率高得多(通常是原图的几倍)的图片,作为放大的内容源。
-
交互流程:
- 用户鼠标在 原图 上移动。
- JavaScript 监听鼠标的坐标。
- 根据鼠标坐标,在 原图 上显示一个 放大镜区域。
- 将 放大图 的对应部分移动到 放大镜区域 的位置,从而实现放大效果。
使用 CSS background-position (最常用、最简单)
这种方法利用了 CSS 的 background-position 属性,通过改变背景图片的位置来模拟放大效果,它不需要额外的 HTML 元素来承载放大图,性能较好,实现起来也最简单。
HTML 结构
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">CSS放大镜效果</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="magnifier-container">
<!-- 原图,作为放大镜的背景 -->
<img src="https://via.placeholder.com/400x300" alt="原图">
<!-- 放大镜的镜片 -->
<div class="magnifier-lens"></div>
<!-- 放大后的图片显示区域 -->
<div class="magnifier-result"></div>
</div>
<script src="script.js"></script>
</body>
</html>
CSS 样式 (style.css)
关键点:

(图片来源网络,侵删)
.magnifier-container设置为position: relative,作为内部元素的定位基准。.magnifier-lens设置为position: absolute,cursor: none,并设置一个圆形边框和半透明背景。.magnifier-result设置为position: absolute,通常放在原图旁边,并设置一个固定大小。- 最关键的一步:将原图作为
.magnifier-result的背景图片,并且通过background-size将其放大。
.magnifier-container {
position: relative;
display: inline-block;
margin: 50px;
}
/* 原图样式 */
.magnifier-container img {
display: block;
/* 确保图片不会被放大镜覆盖 */
z-index: 0;
}
/* 放大镜镜片 */
.magnifier-lens {
position: absolute;
border: 2px solid #ccc;
border-radius: 50%; /* 圆形放大镜 */
cursor: none;
width: 100px;
height: 100px;
background-color: rgba(255, 255, 255, 0.5); /* 半透明 */
display: none; /* 默认隐藏 */
z-index: 1;
}
/* 放大后的图片显示区域 */
.magnifier-result {
position: absolute;
right: -420px; /* 放在原图右侧 */
top: 0;
width: 400px;
height: 300px;
border: 1px solid #ccc;
background-repeat: no-repeat;
background-color: #fff;
overflow: hidden; /* 隐藏超出部分 */
display: none; /* 默认隐藏 */
z-index: 2;
}
JavaScript 逻辑 (script.js)
逻辑步骤:
- 获取所有需要的 DOM 元素。
- 定义放大倍数。
- 为原图添加
mousemove事件监听器。 - 在
mousemove事件中:- 获取鼠标在图片上的相对坐标。
- 计算放大镜镜片的位置(
left,top)。 - 限制镜片不能移出图片边界。
- 设置镜片的显示位置。
- 核心:计算放大后背景图片的
background-position,这个位置与鼠标位置和放大倍数相关。
document.addEventListener('DOMContentLoaded', () => {
const container = document.querySelector('.magnifier-container');
const lens = document.querySelector('.magnifier-lens');
const result = document.querySelector('.magnifier-result');
const img = container.querySelector('img');
// 放大倍数
const zoom = 3;
// 1. 当鼠标移入图片区域时,显示放大镜和结果区域
img.addEventListener('mouseenter', () => {
lens.style.display = 'block';
result.style.display = 'block';
});
// 2. 当鼠标移出图片区域时,隐藏放大镜和结果区域
img.addEventListener('mouseleave', () => {
lens.style.display = 'none';
result.style.display = 'none';
});
// 3. 鼠标在图片上移动时
img.addEventListener('mousemove', (e) => {
// 获取图片和容器的位置信息
const rect = img.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// 计算放大镜镜片的位置
// 镜片中心对准鼠标
let lensX = x - lens.offsetWidth / 2;
let lensY = y - lens.offsetHeight / 2;
// 限制镜片不能移出图片边界
if (lensX < 0) lensX = 0;
if (lensY < 0) lensY = 0;
if (lensX > img.offsetWidth - lens.offsetWidth) {
lensX = img.offsetWidth - lens.offsetWidth;
}
if (lensY > img.offsetHeight - lens.offsetHeight) {
lensY = img.offsetHeight - lens.offsetHeight;
}
// 设置镜片的位置
lens.style.left = `${lensX}px`;
lens.style.top = `${lensY}px`;
// --- 核心逻辑:计算背景图片位置 ---
// 鼠标在图片上的相对位置比例
const bgX = (x / img.offsetWidth) * 100;
const bgY = (y / img.offsetHeight) * 100;
// 设置放大后图片的背景位置
// background-position 的值需要是负数,并且根据放大倍数进行调整
// 鼠标在图片中心,背景图片也应该移动到中心,从而让放大的部分显示在结果区域中心
result.style.backgroundImage = `url(${img.src})`;
result.style.backgroundSize = `${img.width * zoom}px ${img.height * zoom}px`;
result.style.backgroundPosition = `${bgX}% ${bgY}%`;
});
});
使用 <canvas> (更灵活,性能更好)
对于需要高性能处理、或者对图片进行复杂操作(如滤镜、裁剪)的场景,使用 canvas 是更好的选择,它直接操作像素,可以实现更流畅的放大效果。
HTML 结构
<div class="canvas-magnifier-container">
<img id="canvas-img" src="https://via.placeholder.com/400x300" alt="原图">
<canvas id="magnifier-canvas"></canvas>
</div>
CSS 样式
.canvas-magnifier-container {
position: relative;
display: inline-block;
margin: 50px;
}
#canvas-img {
display: block;
}
#magnifier-canvas {
position: absolute;
border: 2px solid #ccc;
border-radius: 50%;
pointer-events: none; /* 让鼠标事件穿透到下面的img */
display: none;
}
JavaScript 逻辑
- 获取原图和
canvas元素。 - 设置放大镜的尺寸和放大倍数。
- 在
mousemove事件中:- 获取鼠标坐标。
- 创建一个临时的
canvas来绘制原图。 - 使用
ctx.drawImage()的裁剪和缩放功能,只绘制鼠标周围的一小块区域,并将其放大到放大镜canvas的整个尺寸上。
document.addEventListener('DOMContentLoaded', () => {
const img = document.getElementById('canvas-img');
const magnifierCanvas = document.getElementById('magnifier-canvas');
const ctx = magnifierCanvas.getContext('2d');
// 设置放大镜尺寸
const lensSize = 100;
magnifierCanvas.width = lensSize;
magnifierCanvas.height = lensSize;
// 放大倍数
const zoom = 3;
img.addEventListener('mouseenter', () => {
magnifierCanvas.style.display = 'block';
});
img.addEventListener('mouseleave', () => {
magnifierCanvas.style.display = 'none';
});
img.addEventListener('mousemove', (e) => {
const rect = img.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// 计算放大镜位置
let lensX = x - lensSize / 2;
let lensY = y - lensSize / 2;
// 边界检查
if (lensX < 0) lensX = 0;
if (lensY < 0) lensY = 0;
if (lensX > img.offsetWidth - lensSize) {
lensX = img.offsetWidth - lensSize;
}
if (lensY > img.offsetHeight - lensSize) {
lensY = img.offsetHeight - lensSize;
}
magnifierCanvas.style.left = `${lensX}px`;
magnifierCanvas.style.top = `${lensY}px`;
// --- Canvas 核心逻辑 ---
// 清除画布
ctx.clearRect(0, 0, lensSize, lensSize);
// 计算要裁剪的区域大小
const sourceSize = lensSize / zoom;
// 使用 drawImage 的裁剪和缩放功能
// ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
// sx, sy: 源图片裁剪的起始坐标
// sWidth, sHeight: 源图片裁剪的尺寸
// dx, dy: 在画布上绘制的起始坐标
// dWidth, dHeight: 在画布上绘制的尺寸
ctx.drawImage(
img,
x - sourceSize / 2, y - sourceSize / 2, // 从鼠标周围裁剪
sourceSize, sourceSize, // 裁剪一小块
0, 0, // 从画布(0,0)开始绘制
lensSize, lensSize // 绘制到整个放大镜画布上
);
});
});
使用第三方库 (最快捷)
如果你只是想快速实现一个功能完善的放大镜,不想自己写代码,使用成熟的库是最好的选择。
一个非常流行的库是 jQuery.zoom,它非常轻量且易于使用。

(图片来源网络,侵删)
步骤
-
引入 jQuery 和 jQuery.zoom:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-zoom/1.7.21/jquery.zoom.min.js"></script>
-
HTML 结构:
<div id="zoom-container"> <img id="zoom-img" src="https://via.placeholder.com/400x300" data-zoom-image="https://via.placeholder.com/1200x900" alt="原图"> </div> -
JavaScript 调用:
$(document).ready(function(){ $('#zoom-img').zoom({ on: 'hover', // 触发方式: 'hover' 或 'click' magnify: 1.5 // 放大倍数 }); });
这个库会自动为你处理所有细节,包括创建放大镜区域、处理移动逻辑等,如果你的项目已经使用了 jQuery,这无疑是最高效的选择。
总结与选择建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
CSS background-position |
实现简单,代码量少,性能较好,不依赖库。 | 需要准备一张高分辨率的放大图,不够灵活。 | 绝大多数标准放大镜需求,是首选方案。 |
<canvas> |
性能最好,非常灵活,可对图片进行像素级操作。 | 代码逻辑相对复杂,需要理解 canvas API。 |
对性能要求高、需要动态处理图片(如电商商品图)的场景。 |
| 第三方库 | 最快,功能稳定,开箱即用。 | 引入了额外的库,增加了项目体积,可能不满足高度定制化需求。 | 快速开发、项目已使用 jQuery、不想自己造轮子时。 |
对于初学者和大多数项目,强烈推荐方法一(CSS background-position),它完美地平衡了简单性、性能和效果。
