最轻量的鼠标悬停缩放用 transform: scale()(IE9+),需设 transform-origin: center 和 overflow: hidden;移动端双指缩放靠 touchstart/move/end 计算两指距离变化并限制缩放范围;PC端滚轮缩放需 preventDefault() 并动态设置 transform-origin 为光标局部坐标;canvas 缩放仅适用于需像素级操作的场景。

用 transform: scale() 实现鼠标悬停缩放
最轻量、兼容性好(IE9+),适合静态展示类图片。核心是利用 CSS 的 transform 属性,配合 :hover 触发,不依赖 JS。
- 缩放中心默认是元素左上角,加
transform-origin: center才能居中放大 - 必须给图片容器设
overflow: hidden,否则放大后边缘会溢出 - 不要直接在
上写width/height内联样式,否则缩放可能失真;推荐用 CSS 控制尺寸
.zoom-img {
display: inline-block;
overflow: hidden;
transition: transform 0.2s ease;
}
.zoom-img img {
display: block;
transition: transform 0.2s ease;
transform-origin: center;
}
.zoom-img:hover img {
transform: scale(1.3);
}用 touchstart/move/end 实现移动端双指缩放
纯手势缩放需监听原生触摸事件,pinch 不是标准事件,得靠计算两指距离变化来模拟。关键点在于实时更新 scale 和 translate,并防止缩放失控。
- 记录初始两指距离(
getDistance())和图片当前scale,每次touchmove重算比例增量 - 必须限制最大最小缩放值(如
minScale=0.5,maxScale=3),否则用户可能缩到看不见或卡死 - 要处理
touchend后的惯性回弹(可选),否则松手时图片可能停留在非整数倍缩放状态
let scale = 1; let lastDistance = 0;img.addEventListener('touchstart', e => { if (e.touches.length === 2) { lastDistance = getDistance(e.touches[0], e.touches[1]); } });
img.addEventListener('touchmove', e => { if (e.touches.length === 2) { const dist = getDistance(e.touches[0], e.touches[1]); const delta = dist / lastDistance; scale = Math.min(Math.max(scale * delta, 0.5), 3); img.style.transform =
scale(${scale}); lastDistance = dist; } });
用 WheelEvent + preventDefault() 做滚轮缩放
PC 端最自然的交互方式,但默认滚轮会触发页面滚动,必须拦截并手动计算缩放中心点(光标位置相对图片左上角的偏移),否则缩放会“跑偏”。
-
event.clientX/Y是视口坐标,需减去图片getBoundingClientRect()才能得到局部坐标 - 缩放时要用
transform-origin动态设为该局部坐标,否则总以左上角为基点 - 记得在
wheel里调event.preventDefault(),不然页面会跟着滚动
img.addEventListener('wheel', e => {
e.preventDefault();
const rect = img.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const scale = parseFloat(getComputedStyle(img).transform.split(',')[3]) || 1;
const newScale = e.deltaY < 0 ? scale 1.1 : scale 0.9;
img.style.transformOrigin = ${x}px ${y}px;
img.style.transform = scale(${Math.min(Math.max(newScale, 0.3), 5)});
});
为什么不用 做缩放?
Canvas 确实能精确控制像素,但除非你做图像编辑器或需要滤镜叠加,否则没必要。它带来三个硬伤:
立即学习“前端免费学习笔记(深入)”;
- 每次缩放都要
clearRect()+drawImage(),CPU 开销明显高于 CSStransform -
响应式布局下,canvas 的
width/height属性和 CSS 尺寸常不一致,导致拉伸模糊 - 无法直接继承父容器的
object-fit行为,裁剪、对齐逻辑全得自己写
只有当你需要逐像素操作(比如缩放同时加锐化)、或叠加图层(文字+蒙版+图片)时,才值得切到 canvas 方案。











