这是一个 Compose 自定义绘制技能,用于在卡片、芯片或按钮周围绘制旋转的扫掠渐变光环。
用途 它生成的是“边框光环”效果,而非普通的描边或蒙版:先在整个控件上绘制一层旋转的扫掠渐变,再用一块不透明的内嵌表面盖住中间,未被覆盖的边缘区域即形成光环。
主要能力 文中给出可复用的实现思路:使用无限过渡产生 0° 到 360° 的线性角度动画;用 animateFloatAsState 控制光环从缩放到展开的过渡;通过 clip 限定渐变范围,通过 drawBehind 在整块区域内绘制渐变,再通过 padding 留出边框宽度,并用相同形状的 Surface 覆盖中心。还说明了如何实现固定圈数后停止的变体:用状态变量和 LaunchedEffect 控制绘制时机,而不是控制过渡本身。
修饰符顺序的关键性 技能强调,效果的关键在于修饰符顺序,而不是混合模式:drawBehind 在 padding 之前,渐变才能覆盖到边框间隙;如果放在 padding 之后,只能拿到内尺寸,无法绘制边框。半径要取 size.width,而不是默认的 minDimension/2,否则宽控件的四角会变暗。
混合模式与图层开销 文中分析了 SrcIn 在预乘颜色下的计算结果:它只会保留目标 alpha 区域,恰好与光环相反;要在未 padding 的整块图层上用 SrcOut 才能刻出光环。因此更推荐无需混合模式的版本。CompositingStrategy.Offscreen 会为每个实例引入一块离屏缓冲区,并逐帧重绘,适合英雄元素而不适合列表行。
限制与陷阱 内表面必须不透明,否则渐变会透到中间,变成色块而不是光环;内外形状必须一致,否则边角宽度会漂移。无限过渡只要被组合就会持续请求帧,即使将缩放设为零也不会停止;如果效果很少出现,应把动画变体放到条件分支里。LaunchedEffect(true) 只在首次组合时运行一次;如果实例挂载时标志为关闭,之后再打开,就永远不会播放动画。RepeatMode.Reverse 会让角度往返,看起来像摆动而不是旋转。扫掠渐变的最后一个颜色会与第一个颜色在起始角相接,形成接缝。
验证方式 文中提供 grep 命令排查离屏图层、混合模式、无限过渡与 LaunchedEffect(true);还建议手工测试:把控件分别放在深色和浅色背景上,检查光环是否被限制在自身图层内;以及在界面出现后再切换标志,而非初始即为开启。文中还记录了一处“已发布组件顺序相反”的观察,并建议先截图确认再修改。
本文分类依据是:该技能面向 Compose 的 UI 绘制与动画实现,属于前端与界面构建范畴,因此归入前端与建站。