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

如何从SVGTransform对象提取旋转变换的中心cx与cy?

从SVG旋转变换对象中提取旋转中心坐标

当SVG元素使用带旋转中心的rotate(angle cx cy)变换时,通过JavaScript遍历元素的transform.baseVal集合拿到SVGTransform对象后,旋转角度可以直接从angle属性获取,但旋转中心的cx和cy没法直接读取,得从matrix属性的参数里推导计算。

推导逻辑

带自定义中心的旋转变换,本质是三个步骤的组合:

  1. 把元素平移,让旋转中心(cx, cy)对齐坐标系原点:translate(-cx, -cy)
  2. 执行角度为angle的旋转:rotate(angle)
  3. 再把元素平移回原位置:translate(cx, cy)

这三步合并后的变换矩阵对应SVGTransform.matrix的属性:

  • a = cosθ,b = sinθ(θ是旋转角度的弧度值)
  • e = cx*(1 - cosθ) + cy*sinθ
  • f = cy*(1 - cosθ) - cx*sinθ

通过解这两个关于cx和cy的方程,可以得到计算式:

分母 = 2*(1 - a)
cx = (e*(1 - a) - b*f) / 分母
cy = (f*(1 - a) + b*e) / 分母

如果旋转角度是0或360的整数倍(此时a=1,b=0),旋转中心没有实际意义,可以设为默认值(比如0)。

代码实现

把计算逻辑加到你的代码里,就能正确提取旋转中心:

console.clear();
let r = document.querySelector('svg rect');

let transforms = r.transform.baseVal;

for(let i=0; i<transforms.length; i++)
{
  let t=transforms[i];
  if(t.type==SVGTransform.SVG_TRANSFORM_TRANSLATE)
  {
    console.log('Found translate '+t.matrix.e+', '+t.matrix.f);
  }
  else if(t.type==SVGTransform.SVG_TRANSFORM_ROTATE)
  {
    console.log('Found rotation');
    console.log(' - angle is '+t.angle); // 输出30
    const a = t.matrix.a;
    const b = t.matrix.b;
    const e = t.matrix.e;
    const f = t.matrix.f;

    let cx, cy;
    // 处理角度为0/360倍数的特殊情况
    if (Math.abs(1 - a) < 1e-6) {
      cx = 0;
      cy = 0;
    } else {
      const denominator = 2 * (1 - a);
      cx = (e * (1 - a) - b * f) / denominator;
      cy = (f * (1 - a) + b * e) / denominator;
    }
    console.log(' - cx is '+cx); // 输出50
    console.log(' - cy is '+cy); // 输出25
  }
}

对应的SVG代码:

<svg width="300" height="200">
  <rect style="fill: blue;" width="100" height="50" transform="translate(30 30) rotate(30 50 25)" />
</svg>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 05:06:35