js原声实现缩放
原生JavaScript实现缩放功能
通过监听鼠标事件和触摸事件,结合CSS的transform属性实现元素的缩放效果。以下代码示例展示如何实现基于鼠标滚轮和触摸手势的缩放。
HTML结构
<div id="zoom-container" style="width: 500px; height: 500px; border: 1px solid #ccc;">
<img id="zoom-target" src="image.jpg" style="transform-origin: 0 0;">
</div>
核心JavaScript代码

const target = document.getElementById('zoom-target');
const container = document.getElementById('zoom-container');
let scale = 1;
const minScale = 0.5;
const maxScale = 3;
// 鼠标滚轮缩放
container.addEventListener('wheel', (e) => {
e.preventDefault();
const delta = -e.deltaY * 0.01;
applyZoom(delta, e.clientX, e.clientY);
});
// 触摸手势缩放(移动端)
let touchDistance = 0;
container.addEventListener('touchstart', (e) => {
if (e.touches.length === 2) {
touchDistance = getDistance(e.touches[0], e.touches[1]);
}
});
container.addEventListener('touchmove', (e) => {
if (e.touches.length === 2) {
e.preventDefault();
const newDistance = getDistance(e.touches[0], e.touches[1]);
const delta = (newDistance - touchDistance) * 0.01;
const centerX = (e.touches[0].clientX + e.touches[1].clientX) / 2;
const centerY = (e.touches[0].clientY + e.touches[1].clientY) / 2;
applyZoom(delta, centerX, centerY);
touchDistance = newDistance;
}
});
function getDistance(touch1, touch2) {
return Math.hypot(
touch2.clientX - touch1.clientX,
touch2.clientY - touch1.clientY
);
}
function applyZoom(delta, x, y) {
const rect = container.getBoundingClientRect();
const offsetX = x - rect.left;
const offsetY = y - rect.top;
const newScale = Math.min(maxScale, Math.max(minScale, scale + delta));
if (newScale === scale) return;
// 计算缩放中心点相对位置
const originX = offsetX / scale;
const originY = offsetY / scale;
target.style.transform = `scale(${newScale}) translate(${(1 - newScale/scale) * originX}px, ${(1 - newScale/scale) * originY}px)`;
scale = newScale;
}
实现原理说明
坐标转换计算 缩放时保持鼠标位置作为中心点的关键公式:
- 计算当前鼠标位置相对于元素的比例位置: [ originX = \frac{offsetX}{currentScale} ]
- 计算新缩放比例下的位移补偿: [ translateX = (1 - \frac{newScale}{currentScale}) \times originX ]
触摸手势处理 通过两点触摸的初始距离和移动距离差值计算缩放比例,使用两点中点作为缩放中心。

扩展功能建议
限制平移范围 添加边界检查防止元素被完全移出视图:
function checkBoundaries() {
const matrix = new DOMMatrix(target.style.transform);
const currentX = matrix.m41;
const currentY = matrix.m42;
// 根据实际需求设置边界值
const maxX = container.clientWidth * (1 - 1/scale);
const maxY = container.clientHeight * (1 - 1/scale);
target.style.transform = `scale(${scale}) translate(${Math.min(0, Math.max(-maxX, currentX))}px, ${Math.min(0, Math.max(-maxY, currentY))}px)`;
}
动画平滑过渡 添加CSS过渡效果使缩放更平滑:
#zoom-target {
transition: transform 0.1s ease-out;
}
重置缩放按钮 添加重置功能按钮:
document.getElementById('reset-btn').addEventListener('click', () => {
scale = 1;
target.style.transform = 'scale(1) translate(0, 0)';
});
以上实现方案适用于大多数需要缩放功能的场景,可根据具体需求调整参数和交互细节。






