如何利用鼠标滚轮结合SVG的viewBox属性实现鼠标定点缩放
鼠标滚轮控制SVG缩放并保持鼠标点位固定
直接上可运行的实现代码,核心是通过调整viewBox属性,结合鼠标坐标转换来实现缩放时的点位锁定:
<svg id="svgContainer" width="100%" height="600" viewBox="0 0 1000 600" style="border:1px solid #ccc;"> <!-- 示例内容,方便观察缩放效果 --> <circle cx="500" cy="300" r="50" fill="red"/> <rect x="200" y="200" width="100" height="100" fill="blue"/> </svg> <script> const svg = document.getElementById('svgContainer'); const viewBox = { x: 0, y: 0, width: 1000, height: 600 }; const zoomSpeed = 0.1; // 每次滚轮的缩放幅度 // 将鼠标屏幕坐标转换为SVG内部坐标系坐标 function getMouseSVGCoords(event) { const point = svg.createSVGPoint(); point.x = event.clientX; point.y = event.clientY; return point.matrixTransform(svg.getScreenCTM().inverse()); } svg.addEventListener('wheel', (e) => { e.preventDefault(); // 阻止页面默认滚动行为 const mousePos = getMouseSVGCoords(e); // 根据滚轮方向计算缩放因子:向上滚放大,向下滚缩小 const scaleFactor = e.deltaY > 0 ? (1 - zoomSpeed) : (1 + zoomSpeed); // 调整viewBox参数,确保鼠标指向的点位在缩放后位置不变 viewBox.x = mousePos.x - (mousePos.x - viewBox.x) * scaleFactor; viewBox.y = mousePos.y - (mousePos.y - viewBox.y) * scaleFactor; viewBox.width /= scaleFactor; viewBox.height /= scaleFactor; // 更新SVG的viewBox属性 svg.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}`); }); </script>
关键逻辑拆解
- 坐标转换:利用
createSVGPoint和matrixTransform把浏览器屏幕坐标转成SVG内部坐标,精准定位鼠标指向的SVG元素点位。 - 缩放方向判断:通过滚轮事件的
deltaY值区分缩放方向,正数为向下滚(缩小),负数为向上滚(放大)。 - viewBox核心调整:通过公式计算新的viewBox原点,让鼠标点位在缩放前后,相对于viewBox的位置保持一致;同时反向调整viewBox的宽高,实现缩放效果。
- 默认行为拦截:调用
e.preventDefault()避免页面整体滚动,确保缩放仅作用于目标SVG。
内容的提问来源于stack exchange,提问作者pomeroy
相关产品推荐
相关产品推荐

