本文详解如何在 svg 中实现以鼠标悬停/滚动位置为缩放中心的交互式缩放功能,通过坐标空间转换、`transform-origin` 动态设置与 css 变量协同控制,避免默认居中缩放的局限性。
要在 SVG 中实现“以鼠标指针位置为中心”的缩放(而非默认的 SVG 元素中心),关键在于三点:
- 将屏幕坐标(clientX/Y)准确映射到 SVG 用户坐标系;
- 动态设置缩放元素的 transform-origin 为该 SVG 坐标;
- 使用 CSS transform: scale() 配合 transition 实现平滑缩放动画。
✅ 核心原理:坐标空间转换
SVG 的 getScreenCTM().inverse() 是核心工具——它返回一个从屏幕像素坐标(如 event.clientX, event.clientY)逆向映射到 SVG 本地用户坐标系的变换矩阵。配合 DOMPoint.matrixTransform() 即可获得精确的 SVG 内部坐标:
function cursorPoint(event: MouseEvent): DOMPoint {
const point = new DOMPoint(event.clientX, event.clientY);
return point.matrixTransform(svg.getScreenCTM()!.inverse());
}
⚠️ 注意:svg.getScreenCTM() 在 未渲染或未挂载时可能返回 null,建议添加空值检查(如 ! 断言或 if (ctm) 判断)。
✅ 完整 TypeScript + HTML 实现(适配你的 Angular 场景)
将原 @HostListener(‘wheel’) 逻辑升级为支持锚点缩放: