如何从SVGTransform对象提取旋转变换的中心cx与cy?
从SVG旋转变换对象中提取旋转中心坐标
当SVG元素使用带旋转中心的rotate(angle cx cy)变换时,通过JavaScript遍历元素的transform.baseVal集合拿到SVGTransform对象后,旋转角度可以直接从angle属性获取,但旋转中心的cx和cy没法直接读取,得从matrix属性的参数里推导计算。
推导逻辑
带自定义中心的旋转变换,本质是三个步骤的组合:
- 把元素平移,让旋转中心(cx, cy)对齐坐标系原点:
translate(-cx, -cy) - 执行角度为
angle的旋转:rotate(angle) - 再把元素平移回原位置:
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
相关产品推荐
相关产品推荐

