基于SVG viewBox实现鼠标指向点居中缩放的偏移量计算问题
解决SVG以鼠标点为中心缩放的偏移量计算问题
要实现鼠标滚动时以当前指向点为中心缩放,你需要先将鼠标的屏幕坐标转换为SVG内部坐标系的坐标,再通过公式计算新的offsetX和offsetY。
完整代码实现
processMouseScroll(event: WheelEvent) { const svg = event.currentTarget as SVGSVGElement; // 转换鼠标屏幕坐标到SVG内部坐标系 const point = svg.createSVGPoint(); point.x = event.clientX; point.y = event.clientY; const mouseSvgCoords = point.matrixTransform(svg.getScreenCTM().inverse()); const mouseSvgX = mouseSvgCoords.x; const mouseSvgY = mouseSvgCoords.y; const oldZoomFactor = zoomFactor(this.scroll); const newScroll = this.scroll + event.deltaY; const newZoomFactor = zoomFactor(newScroll); // 计算缩放比例 const scale = newZoomFactor / oldZoomFactor; // 核心公式:计算新的偏移量 this.offsetX = mouseSvgX - (mouseSvgX - this.offsetX) * scale; this.offsetY = mouseSvgY - (mouseSvgY - this.offsetY) * scale; this.scroll = newScroll; }
公式逻辑说明
- 坐标转换:通过
SVGPoint和matrixTransform将鼠标的屏幕坐标(clientX/clientY)转换为SVG内容自身的坐标系坐标,这个坐标不受viewBox的缩放和平移影响,是SVG元素的原始坐标。 - 缩放比例计算:
scale是新缩放因子与旧缩放因子的比值,代表本次滚动的缩放幅度。 - 偏移量推导:
- 缩放前,鼠标点相对于当前viewBox左上角的偏移为
mouseSvgX - offsetX(x方向) - 缩放后,这个偏移会被缩放
scale倍,为了让鼠标点在屏幕上的位置不变,新的viewBox左上角需要调整,使得鼠标点到新左上角的偏移等于原偏移乘以缩放比例,最终推导出新的offsetX和offsetY公式。
- 缩放前,鼠标点相对于当前viewBox左上角的偏移为
内容的提问来源于stack exchange,提问作者Minop
相关产品推荐
相关产品推荐

