r属性本身不支持动画,需配合<animate>或CSS @keyframes实现呼吸效果;直接设r值是静态的,必须通过定时器、内联动画或transform缩放才能产生动态变化。

r 属性在 SVG 中只控制圆形(<circle>)或椭圆(<ellipse>)的半径,它本身不支持动画呼吸灯效果——必须配合 animate 或 CSS @keyframes 才能实现缩放、明暗交替等“呼吸”动效。
为什么直接设 r 不会动
SVG 元素的属性默认是静态的。写成 <circle r="20"></circle> 就只是个固定大小的圆;浏览器不会自动让它胀缩或闪烁。
-
r是一个数值型呈现属性(presentation attribute),不是动画属性,不能单独触发过渡 - 没有 JavaScript 或 CSS 干预时,
r值一旦解析完成就锁定,后续不变化 - 若用 JS 动态改
r,需手动定时器 +setAttribute('r', newValue),否则无响应
用 <animate> 实现呼吸缩放
最轻量、无需外部依赖的方式:内联 SVG 动画。关键点是用 attributeName="r" 控制半径,并配合理想的 dur、repeatCount 和缓动(calcMode="spline" 可选)。
<svg width="200" height="200">
<circle cx="100" cy="100" r="10" fill="#4a90e2">
<animate attributeName="r"
from="8" to="24"
dur="2s"
repeatCount="indefinite"
calcMode="spline"
keySplines="0.4 0 0.2 1; 0.4 0 0.2 1" />
</circle>
</svg>
-
from/to定义呼吸范围(太小看不出变化,太大易抖动;建议差值 ≤ 2× 初始值) -
dur="2s"对应典型呼吸节奏;快于 1.2s 易显急促,慢于 3s 易被忽略 -
keySplines模拟自然加减速——首段慢入、中段快、末段慢出,比线性更像“呼吸”
CSS @keyframes 更灵活但有兼容陷阱
用 CSS 控制 r 需通过 transform: scale() 间接实现,因为原生 CSS 无法直接动画 SVG 属性(r 不是 CSS 属性)。直接写 animation: breathe 2s infinite; + @keyframes breathe { to { r: 24; } } 无效。
立即学习“前端免费学习笔记(深入)”;
- ✅ 正确做法:给
<circle>加 class,用transform: scale()缩放整个元素(视觉等效于改r) - ⚠️ 注意:
transform会连带影响描边宽度(stroke-width),若需保持描边恒定,得同步用vector-effect="non-scaling-stroke" - ❌ 不要尝试
attr(r)CSS 函数——目前无浏览器支持该语法动画
容易被忽略的细节
呼吸灯常被当成“简单动效”,但实际部署时三个点最容易翻车:
- 缩放中心偏移:没设
cx/cy或父容器transform-origin,导致圆在呼吸时“漂移” - 动画卡顿:在低端设备上用 JS 频繁 setAttribute('r') 造成 layout thrashing;优先选 CSS
transform或<animate> - 无障碍干扰:持续动画可能触发用户设置的
prefers-reduced-motion,应包裹媒体查询或提供开关



















