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

以光标为变换原点缩放SVG出现圆形位置偏移问题求解

问题根源

你代码的问题出在计算transformOrigin的坐标基准每次都会变:getBoundingClientRect()返回的是SVG元素应用了transform缩放之后的实际渲染尺寸和位置,你每次缩放都基于当前已经变形的尺寸计算百分比坐标,导致变换原点的实际对应位置每次都偏离你想要的光标位置,连续操作就会出现偏移。

修复方案

只需要在初始化时缓存一次SVG未缩放状态下的原始位置和尺寸,后续所有坐标计算都基于这个固定的原始基准即可,修正后的完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" content="width=device-width">
    <style>
        .container
        {
            position: fixed;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
        }
    </style>
</head>
<body>
<div class="container">
    <svg id="svg" height="600" width="600">
        <circle cx="300" cy="300" r="300" stroke="black" stroke-width="3" fill="white"/>
    </svg>
</div>
<script>
    let scale = 1;
    const e = document.getElementById("svg");
    // 初始化缓存未缩放的原始位置与尺寸
    const originalRect = e.getBoundingClientRect();

    function wheelZoom(event)
    {
        event.preventDefault();

        scale += event.deltaY * -0.01;
        scale = Math.min(Math.max(.5, scale), 2);

        // 坐标计算基于原始尺寸,不受当前缩放状态影响
        const x = 100*(event.clientX - originalRect.left)/originalRect.width;
        const y = 100*(event.clientY - originalRect.top)/originalRect.height;

        e.style.transformOrigin = `${x}% ${y}%`;
        e.style.transform = `scale(${scale})`;
    }

    e.addEventListener("wheel", wheelZoom);
</script>
</body>
</html>

内容的提问来源于stack exchange,提问作者ckc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 15:06:00