You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用鼠标滚轮结合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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 05:52:35