单纯用transform: rotate()做不出雷达光圈效果,因其使整环原地旋转成“旋转饼图”,而雷达需“固定背景+移动扇区”;必须用absolute定位锚定中心、scale()+opacity模拟脉冲扩散,并分层错延动画实现真实扫描节奏。

为什么单纯用 transform: rotate() 做不出雷达光圈效果
因为 rotate() 作用在整块元素上,结果是整个圆环原地打转——这叫旋转饼图,不是雷达。雷达光圈的核心是“固定背景 + 移动扇区”,必须让扫描线(或光晕)以中心为原点扫过,而非容器自转。常见错误是给 .radar 直接加 animation: spin 4s linear infinite,导致视觉上像电风扇,没有方向感和脉冲节奏。
必须用 position: absolute + transform-origin 锚定旋转中心
扫描线或光圈层需脱离文档流,否则旋转时会触发重排、抖动甚至溢出容器。关键三步:
-
.radar容器必须设position: relative,否则伪元素或子元素的absolute定位会相对于body,造成旋转中心偏移 - 扫描臂(如
::before)设position: absolute; top: 50%; left: 50%; width: 200%; height: 2px;,再用transform-origin: 0 0(左上角)或transform-origin: -50% -50%(精确锚定中心) - 避免用
%值做transform-origin的偏移量,Safari 对负百分比解析不稳定;推荐用px或calc()精确控制,例如transform-origin: calc(50% + 1px) calc(50% + 1px)
光圈扩散动画要用 scale() + opacity,不能只靠 rotate()
雷达光圈模拟的是信号从中心向外传播并衰减的过程,scale() 从 0 到 1 天然对应物理行为,而 rotate() 只能表达方向扫描。若混用,容易出现“旋转+放大”导致光圈变形、边缘撕裂。
- 每个光圈层应是独立
div或伪元素,不要复用同一 DOM 节点控制多个动画 - 统一动画总时长(如
3s),用animation-delay错开起始:第一个0s,第二个1s,第三个2s—— 不要用百分比延迟,浏览器不支持 - 性能敏感场景下,限制同时运行的光圈数 ≤ 6;超过后低端安卓 WebView 易掉帧,可用
@media (prefers-reduced-motion: reduce)降级为单层淡入
conic-gradient 光圈必须配合 animation-delay 分层,否则就是匀速“硬扫”
单层 conic-gradient 配合 rotate 动画,视觉上就是一根光条划过,缺乏真实雷达的“起始加速→峰值亮度→拖尾衰减”节奏,人眼感知为“扫一下就停”。根本问题不在动画没跑完,而在节奏缺失。
- 至少拆三层:
::before(主扫描臂,z-index: 2)、::after(拖尾,z-index: 1)、额外伪元素或:first-child(前置光晕,z-index: 3) - 所有层
animation-duration必须一致,延迟用calc(var(--scan-speed) * -0.05)这类比例式写法,避免硬编码导致 Safari/Chrome 行为不一致 - 别依赖默认堆叠顺序:Chrome 和 Safari 对伪元素层叠上下文的创建时机有细微差异,显式声明
z-index+position: absolute才稳
实际中最容易被忽略的,是容器未设 position: relative 导致旋转中心漂移,以及多层 conic-gradient 动画 duration 不一致引发的拖影撕裂——这两点一旦出错,调试时往往要花半小时反复对比 Chrome DevTools 的 computed styles 和 timeline 面板。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











