频谱播放态 / 开发交付

固定状态,照这个做

左侧是最终效果。右侧只保留原生开发需要的实现方式、固定参数和验收标准。

只读预览 · 持续播放 · 参数已锁定

一句话理解

线条永远不动,播放时只改变一块不可见的波形 Mask;Mask 露出哪里,哪里就显示线条。

固定参数

频谱坐标
394 × 344
中轴位置
Y = 172
线宽 / 间距
3 / 4 px
播放强度
0.90(高)
Mask 宽 / 高
83% / 48%
Mask 柔边
7 px
背景
#9F3224
条线中心色
白色 10%

实现顺序

  1. 先画条纹。在 394 × 344 容器里一次性创建固定竖线;每条 3px,线与下一条之间 4px。
  2. 给每条线加渐变。顶部 5% 透明,中间 50% 为白色 10%,底部 95% 透明。
  3. 把整组条纹放进 Mask。Mask 是闭合波形,白色区域显示条纹,透明区域隐藏条纹。
  4. 播放时只更新 Mask 路径。不要改线条 frame、宽度、间距,也不要移动整个频谱容器。

两端怎么落地

iOS / UIKit

  • 条纹:约 57 个 CAGradientLayer,创建后 frame 固定。
  • Mask:条纹容器的 layer.mask 使用 CAShapeLayer。
  • 刷新:用 CADisplayLink,每帧只更新 shapeLayer.path。
  • 柔边:Mask Alpha 做 7pt 模糊;不要模糊最终条纹。

Android / View 或 Compose

  • 条纹:Canvas 一次性绘制并缓存,3dp 宽、7dp 步距。
  • Mask:离屏绘制条纹,再用 DST_IN 合成波形。
  • 刷新:用 Choreographer 或 withFrameNanos。
  • 柔边:Mask Paint 使用 7dp BlurMaskFilter。

播放时接入什么数据

输入:播放器实时输出的归一化 RMS / 音量值,范围 0...1。
处理:先做平滑,再用它改变 Mask 的整体高度;波形中心始终保持在 Y=172。
刷新:按 deltaTime 推进动画,不能写死 60fps。

不要做

  • 不要让每根线单独变高、变宽或左右移动。
  • 不要把 Mask 画成可见的白色/半透明色块。
  • 不要加入逐帧随机噪声,否则会出现细碎抖动。
  • 不要把音量直接映射成整组 UI 的位移或透明度。

验收标准:暂停观察时条纹几何完全不变;播放时只有线条显隐范围变化;波形不整体上下跳动;封面和文字不受 Mask 影响。