cx 和 cy 是 svg 圆/椭圆的强制几何定位参数,决定其中心在逻辑坐标系中的位置,非 css 样式属性;支持数字、带单位长度和百分比(相对于 svg 根元素宽高),不支持 em/rem/vw;百分比在无显式宽高时按 0 解析;动态更新需用 setattribute,css transition 无效;与 viewbox 耦合缩放,不随容器像素尺寸变化;嵌套 svg 中独立于外层坐标系;与相机标定内参 cx/cy 无任何关系,仅命名巧合。

cx 和 cy 决定圆/椭圆在 SVG 画布中的物理位置
它们不是样式属性,而是几何定位的强制参数:没有 cx 和 cy,<circle></circle> 默认中心为 (0, 0)(左上角),<ellipse></ellipse> 同理。这常导致图形“消失”在可视区外——尤其当 SVG 宽高较大但未显式设置坐标时。
-
cx和cy值支持数字(如50)、带单位的长度(如50px)、百分比(如50%),但不支持 em/rem/vw 等 CSS 相对单位 - 百分比值是相对于 SVG 根元素的
width和height计算的,不是父容器;若 SVG 未设宽高,则百分比按 0 解析,图形塌缩到原点 - 动态修改时,直接操作 DOM 属性最可靠:
circleEl.setAttribute('cx', '120'),用style.left或 CSS transform 无效
用 JavaScript 动态更新 cx/cy 时的常见失效场景
很多开发者试图用 CSS 动画或 transition 驱动 cx/cy,但 SVG 属性本身不支持 CSS 过渡——浏览器会忽略 transition: cx 0.3s 这类声明。
- 正确做法是用
requestAnimationFrame+setAttribute手动插值,或借助SMIL(已废弃)或现代方案如GSAP的 SVG 插件 - 若通过
document.querySelector('circle').cx.baseVal.value读取,注意该值是只读的SVGLength对象,必须用.baseVal.valueAsString或直接设属性 - React/Vue 中绑定
:cx="xPos"没问题,但避免在模板里写cx="{{xPos}}"(旧版 Vue 2 的 mustache 在 SVG 中可能被解析为文本节点)
cx/cy 与 viewBox 缩放的关系容易被低估
当 SVG 设置了 viewBox="0 0 200 200" 但实际渲染宽高为 400x400px,cx="100" 仍表示逻辑坐标系中的水平中点,而非像素位置——它会随 viewBox 自动缩放,无需手动换算。
- 错误认知:“我要让圆始终居中,就得根据容器宽高实时算 cx/cy”,其实只要
cx="50%" cy="50%"+ 合理的viewBox,就能响应式居中 - 但如果用 JS 动态计算像素位置再赋给
cx,需确保该像素值是相对于 viewBox 定义的逻辑坐标系,而非 clientWidth/clientHeight - 嵌套 SVG 时,内层
cx基于其自身viewBox,不继承外层坐标系,这点和 CSS transform 不同
相机标定里的 cx/cy 和 SVG 的 cx/cy 完全无关
搜索时容易混淆——图像处理中相机内参的 cx、cy 是主点(principal point)在像素坐标系下的偏移量,单位是像素,用于构建投影矩阵;而 SVG 的 cx、cy 是绘图坐标,无物理意义,仅用于定位图形。
- 两者命名巧合,但领域、用途、数据类型、更新机制全部不同:一个由 OpenCV 标定得出并固化在
cameraMatrix中,另一个是纯前端声明式属性 - 若你在做 AR 可视化(比如把相机标定结果映射到 SVG 上),需要自己做坐标转换:将像素坐标
(cx_px, cy_px)按比例缩放到 SVG 逻辑坐标系,再赋给cx/cy - 别尝试把 OpenCV 返回的
cameraMatrix[0][2](即 cx)直接塞进<circle cx="..."></circle>,大概率错位
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











