如何在D3响应式地图中编程实现点击元素自动缩放定位?
解决D3.js SVG响应式场景下点击元素居中缩放偏移问题
问题根因
你直接读取的cx/cy是SVG原生文档的用户坐标系属性值,当SVG外层容器缩放、或SVG通过viewBox实现响应式适配时,该属性值和SVG实际渲染的像素坐标存在比例差,因此固定用属性值计算位移会出现定位偏差。
解决方案
通过SVG原生坐标变换接口自动计算元素相对于当前SVG视口的实际坐标,无需手动获取父级缩放比例,适配所有窗口尺寸场景。
修正后的代码如下:
// 点击事件回调内的逻辑 const targetEl = this; const svgNode = svg.node(); // 初始化SVG坐标点,赋值元素中心点坐标 const point = svgNode.createSVGPoint(); // 若要适配所有SVG元素,可替换为以下两行计算包围盒中心点 // const bbox = targetEl.getBBox(); // point.x = bbox.x + bbox.width / 2; // point.y = bbox.y + bbox.height / 2; point.x = parseFloat(targetEl.getAttribute('cx')); point.y = parseFloat(targetEl.getAttribute('cy')); // 转换为适配当前SVG缩放状态的实际视口坐标 const currentPoint = point.matrixTransform(targetEl.getScreenCTM().inverse()); svg.transition().duration(750).call( zoom.transform, d3.zoomIdentity .translate(widthContainer / 2, heightContainer / 2) .scale(2) .translate(-currentPoint.x, -currentPoint.y), d3.pointer(event, svgNode) );
补充说明
- 该方案自动适配SVG设置的
viewBox、preserveAspectRatio属性以及外层容器的尺寸变化,无需额外手动计算缩放比例 - 代码中注释的包围盒计算逻辑适配所有SVG元素(路径、矩形、多边形等),替换后可复用为通用元素缩放方法
- 缩放倍数可直接修改
scale()的入参,坐标计算逻辑无需调整
内容的提问来源于stack exchange,提问作者Yeet
相关产品推荐
相关产品推荐

