让 124 根光柱排好队再升起
一张三维地图上立着 124 根光柱,最初的循环里,任何时刻都没有全部光柱同时立着。我把满高停留从 1.5 秒拉到 3.5 秒,又把鼠标交互改成按状态补齐,画面才有了能读数的时刻。
- CATEGORY
- 研究
- YEAR
- 2026
- STATUS
- 笔记
- TOOLS
- figma / mcp / motion
entry记录
一块数据大屏的中央是一张三维地图,31 个省每省立着 4 根不同颜色的光柱,对应 4 项指标,一共 124 根;平台所在的原点省份展开一张详情卡,其余省份只标省名。静态稿已经画完,接下来要让光柱动起来:大屏整天挂在墙上,没人看时要有生命力,有人走近想看数据时又要读得清。最初的设想是每省 4 根光柱按时间差依次升起,然后循环,但这个想法还没有验证过。
光柱的高度就是数据,如果一直升降,大部分时间读到的高度都不是真实值;而且三秒一个周期,几轮之后就会变成机械呼吸。四个方案各做成了一个可交互的小样:A 是全体错峰循环,高度大部分时间不真实;B 是入场后靠流光待机,动感弱;C 是入场后每隔几秒挑一个省重新升起,实现复杂;D 是入场后每隔几秒高亮一种颜色,但东部同色光柱太密。最后保留了 A,因为大屏的第一观感需要整体律动,读数问题交给交互去解决;另加一条,省与省之间也要错开。
124 根光柱同时动,东部省份本来就挤在一起,画面容易乱。三种排法做成了带滑块的小样:以原点省份为中心扩散、自西向东扫、随机相位。最后定了以原点省份为中心扩散,因为原点省份是主角,波纹从它推出去,一眼能看出重点。错开规则分两层:省内 4 根按颜色依次起步,相邻相差 0.15 秒,前一根还没到顶,后一根已经起步,像台阶;省间延迟与到原点省份的距离成正比,连续取值不分档,最远的省晚 1.6 秒,距离相近的省几乎同时升起。
设计稿里有两层光柱样式,共 248 个光柱图层,如果靠手摆关键帧,每改一次都要重来。做法是通过 Figma 的 MCP 接口在设计文件里运行脚本,逐一写入关键帧。这样每根柱子的时间都由同一个公式算出,改了参数就能整体重算。
一轮太快,看不清;把两个周期连起来放,再追问两轮之间的间隔,算出来单根光柱满高只停 1.5 秒,而波纹扩散到最远的省要 1.6 秒以上,西部还没升到顶,原点已经在落,任何时刻都没有全部光柱同时立着的画面;而且相邻两轮首尾重叠,没有呼吸。三个节奏做成了小样对比:旧节奏、四段式、四段式加由外向内收回。最终选了四段式,只把满高停留从 1.5 秒拉长到 3.5 秒,其余不动,两轮之间留 0.6 秒静场。整个周期定为 7.35 秒:扩散升起在 0 到 2.75 秒,全图齐高在 2.75 到 4.2 秒,扩散回落在 4.2 到 6.75 秒,静场在 6.75 到 7.35 秒。
最初的想法是鼠标进入地图时动画执行一次就停,可进入时若赶上全图齐高,重播就要先清零再长一遍,想看数据的人会先看到画面塌掉。所以改成了按状态响应,不按时间线重播:每根光柱从当前高度用 0.4 秒补齐到满高,不再错峰;满高的不动,正在回落的反向升回,已经落下的从底座升起。
鼠标悬停到某个省时,其他省压暗,该省弹出详情卡;压暗的比例先试了 40%,在模拟里看着太暗,改成了 60%。鼠标离开地图时不立刻恢复循环,先等 1.5 秒,避免指针在地图边缘来回晃时反复触发;由于离开时光柱都在满高,如果从升起段接回就必须先清零,所以从回落段接回。
评审和开发都需要看到实际效果,但第一版交互模拟在升起阶段进入,说明不了问题。于是在 Figma 里用鼠标指针素材重演,改在第二个周期部分光柱正在回落时进入,随后悬停原点省份,移出 1.5 秒后开始新一轮并播完。进入那一刻,每层约有 51 根满高、55 根正在回落、18 根已经落下,三种情况同时补齐;补齐逻辑也写成了对任意阶段通用。由于 Figma 的视频导出在长时间线上不稳定,交互四个状态的截图来自按同一套参数做的离线复刻演示。
每省原本是静态底座,后来换成此前做好的涟漪状态光环组件,包含一张光环贴图加两道向外扩散的涟漪,自带 2 秒循环;要求涟漪保持自己的循环,透明度和本省光柱同步。第一版让底座随光柱渐显渐隐,但保留光环本体,让静场时地图上不至于空无一物;看过之后,改成了光柱不显示时底座也不显示,整个底座随光柱一起出现、一起消失:光柱开始升起时渐显,最后一根落下时正好完全消失。
实现过程里处理了四个具体问题:纵向缩放默认以中心为轴,会导致柱底悬空,办法是补一条向下的位移,数值等于柱高的一半乘以一减缩放比例;有些省的动作跨过了时间线终点,就把缓动曲线在终点切成两段,前半段放末尾、后半段放开头,保证首尾帧一致,循环时不跳帧;Figma 不允许给组件实例内部的图层写关键帧,涟漪光环只好先放入实例再脱离组件,代价是以后改组件样式,这 31 个底座不会跟着变;视频导出在 7 秒以上频繁失败,日常改为手动导出,文中的循环画面是在临时副本上导出的一个周期。另外,规则里光柱一律用青、粉、黄、绿四种颜色称呼,不用指标名,因为指标名以后可能调整。
最终交付物包括 Figma 里的循环画板和交互模拟画板,各附一张说明卡,以及一份写给开发的动效规范,里面带有状态机伪代码;开发只需实现一根光柱的动画和一个延迟公式,就能还原 124 根,不用逐根对照关键帧。前面定的 7.35 秒周期是算出来的:1.6 加 0.45 加 0.7 加 3.5 加 0.5 加 0.6,最后一根光柱落完,再留 0.6 秒,正好是下一轮开始的时刻。数据大屏的动效先问什么时候能读数,再看好不好看:这次的改动是拉长满高停留,换来一段全图齐高的可读时刻。动效用参数和公式描述,不用关键帧,交给开发的也是同一套公式,设计稿和代码一致。交互把当前高度当作补间的起点,因为用户在任意时刻伸手是常态,这样任何时机进入都是平滑的。节奏先用可交互小样验证,再进设计工具:很多节奏问题点两下小样就能看出来,比在设计工具里反复改关键帧快。命名跟视觉走,不跟业务走,指标调整时规则不用改。
process对比
参数
- 单根光柱
- 升起 0.7s(先快后慢)· 满高 3.5s · 回落 0.5s(先慢后快)· 以柱底为锚点
- 省内
- 青 → 粉 → 黄 → 绿 · 相邻差 0.15s · 先升先落
- 省间
- 延迟与到原点省份的距离成正比 · 最远 1.6s
- 周期
- 7.35s · 扩散升起 0–2.75s · 全图齐高 2.75–4.2s · 扩散回落 4.2–6.75s · 静场 6.75–7.35s
- 省份提示
- 随本省第一根光柱渐显、渐隐
- 底座
- 涟漪光环保持 2s 循环 · 整体随本省光柱显隐
- 进入地图
- 所有元素从当前状态 0.4s 补齐到满 · 不错峰 · 满高的不动 · 回落中的反向升回 · 已落下的从底座升起
- 悬停
- 其他省 0.25s 压暗到 60% · 详情卡放大到 105%
- 离开地图
- 保持满高 · 等 1.5s 后从回落段接回循环
公式
延迟 = 该省到原点省份的距离 ÷ 最远距离 × 1.6s
位移 = 柱高 ÷ 2 × (1 − 缩放)
周期 = 1.6 + 0.45 + 0.7 + 3.5 + 0.5 + 0.6 = 7.35sresult小结
- 结论
- 满高停留从 1.5s 拉到 3.5s 后,7.35s 的周期里出现一段 1.45s 的全图齐高;鼠标进入时每根光柱从当前高度 0.4s 补齐,不再先塌后长。
- 参数
- 省内相邻 0.15s · 省间延迟 = 距离 ÷ 最远距离 × 1.6s · 悬停压暗到 60% · 离开后等 1.5s 从回落段接回
- 没做完
- 涟漪光环为了写关键帧脱离了组件,31 个底座不再随组件更新;Figma 的视频导出在 7 秒以上的时间线上频繁失败。
log日志
- 2026-10
- 首次记录