# 鲸鱼尾巴动画的参考与适配 参考项目:[asdnmy123/dsh-whale-sway](https://github.com/asdnmy123/dsh-whale-sway)。2026-09-30 阅读,参考提交为 [`26cec3e`](https://github.com/asdnmy123/dsh-whale-sway/tree/26cec3ef0b3cd42827659e5c58ffbe833d5080e8)。该项目采用 MIT 许可证。本次借鉴设计思路,继续使用 status-rotator 自己的 SVG 轮廓、流式事件采样和配置存储。 | 参考做法 | 对当前实现的价值 | 本地适配 | | --- | --- | --- | | 积分推进相位,改速时不重启时间轴 | tok/s 上下波动时,尾巴不会突然跳到另一帧 | 已加入:修改 CSS 周期时按新旧周期换算 `currentTime`,保留循环次数和圈内进度;6 帧衔接保持自己的时长 | | 图标被宿主替换后,重新应用当前动作 | React 重绘状态行时不会丢失尾巴效果 | 已加入:回收旧元素与监听,恢复动作、速度、炫彩及圈内进度;正在进行的过渡继续原目标,随机模式沿用切换计划 | | 并排动画卡片采用相同预览速度 | 用户能看清动作差异,速度不会影响摆幅比较 | 可用于下一步设置页:三种动作统一 1 秒周期并排展示,随机选项独立保留;预览遵循减少动态效果偏好 | | 独立测量根部漂移、相邻帧步进和素材身份 | 便于判断描边精度、图标抖动和衔接质量 | 可用于下一步素材工具:保存源文件摘要,测量根部与尾鳍的运动,检查相邻帧和首尾衔接;往返回放的重复帧应记录真实数量 | 参考项目的运动循环和重绘恢复逻辑见 [client.js](https://github.com/asdnmy123/dsh-whale-sway/blob/26cec3ef0b3cd42827659e5c58ffbe833d5080e8/client.js#L1107),并排卡片见 [配置界面](https://github.com/asdnmy123/dsh-whale-sway/blob/26cec3ef0b3cd42827659e5c58ffbe833d5080e8/client.js#L1651),素材与运动指标见 [README](https://github.com/asdnmy123/dsh-whale-sway/blob/26cec3ef0b3cd42827659e5c58ffbe833d5080e8/README.md)。 ## 保留的交互约定 - 翻转摆尾、24 帧左右摆尾、36 帧扭转摆尾及随机切换继续可选。 - 随机动作在匹配姿态处切换,经过 6 帧轮廓衔接;最短过渡 120ms。 - 新增工具调用可按概率请求动作切换,默认开关关闭、概率 35%;历史与重复通知不触发,连续命中合并等待。固定动作也可参与,关闭此项后恢复所选动作。 - tok/s 默认等待一轮 1 秒,默认最高 1.5 次/秒;连续和分档共用可调上限,固定范围仍为 0.25–6 次/秒。 - 用户明确开启的运行中摇动继续服从当前开关;设置页的可选预览不应强制播放。 ## 验证入口 `npm test` 检查配置与纯逻辑。以下浏览器场景覆盖这次适配: ```sh node scripts/run-turn-process-test.cjs --case=020-running-row-wag-tps --case=020-running-row-tail-rebuild --case=020-running-row-random-rebuild --case=020-running-row-random node scripts/run-turn-process-test.cjs --case=020-running-row-tool-switch --case=020-running-row-tool-zero --case=020-running-row-tool-disabled node scripts/run-turn-process-test.cjs --case=020-running-row-tool-late-icon --case=020-running-row-tool-rebind --case=020-running-row-tool-rebuild --case=020-running-row-tool-bridge-rebuild ``` 调速场景锁定真实 CSS 动画的轮廓与循环进度,改变流式输出速率后检查二者保持一致;重绘场景真实替换宿主图标,检查恢复动作和回收旧监听;随机场景检查 6 帧衔接的两端轮廓及卸载清理。 工具触发场景检查历史过滤、参数流过滤、重复通知去重、0% 与 100% 概率、连续调用合并,以及固定动作切换后的保持与清理。设置页回归还覆盖开关、百分比与动作选择的自动保存。 边界场景覆盖图标迟到、请求在回合结束/关闭/切会话时过期、同一会话重新绑定、慢速连续重建以及过渡中重建。新图标只恢复圈内相位,避免把已完成的循环重新 seek 到新 CSS 动画而制造假的衔接事件;缺席期间保存的是时钟与动作的数值快照。 ## 官方原版晃动与动作池 用户提供并标注为官方晃动的参考文件(原文件名 `59f36e77cec79628049a39b407802806.jpg`,实际为 GIF89a,320×320,150 帧,每帧 20ms,一轮 3 秒)保存在 `assets/references/official-tail.gif`,SHA-256 为 `4a97c91a602c5d2c420b44bd89d031d38f33ef01862c33d8b649ef085d5edf02`。`scripts/trace-official-tail.py`(需 Pillow + numpy)复现数据段:提取蓝色轮廓、重采样为 256 点、只平移 (16, 18) 对齐既有根部,115 个不同轮廓用有符号位移编码复用,时间轴保留全部 150 帧及重复帧,逐帧掩码 IoU 最低约 96.8%、平均约 97.1%。生成数据约 63KB,仅在使用该动作时解码并注入 CSS,运行时不加载位图。重跑脚本对 `lib/client.js` 的输出是字节一致的。 `official` 以第一帧作为衔接姿态,与其它动作共用既有 6 帧轮廓过渡。`randomActions` 默认含四种动作、至少保留一种,随机切换与工具调用触发共用该动作池;修改动作池时当前循环先结束,再在衔接处转到池内合法动作。 速度:tok/s 等待时为 1 次/秒(每轮 1 秒),2–5 档上限分别为 1 / 1.5 / 2 / 2.5,默认 3 档(1、1.25、1.5),档位边界两侧各有约 4.8 tok/s 缓冲;`tpsMaxSpeed` 可在 1–10 间自定义,连续模式同样受限。`officialRecommendedSpeed` 默认开启,官方原版按 0.25 次/秒(4 秒一轮)播放,且按**实际动作**解析而非下拉选择:随机或工具切到官方时采用推荐速度,切回其它动作恢复用户设置;关闭后官方也跟随通用速度。改速按动画实际时长换算相位;浮点换算让精确帧边界落到相邻帧时,仅在能恢复原轮廓的前提下作不超过 1 微秒的修正。过渡跨图标重建时,溢出时间按目标动作周期换算。 边界修复:循环完成事件可能先于宿主替换节点、却晚于监听释放送达。快照现在带已消费的循环计数,恢复时补回实际跨过但未消费的衔接;新工具请求先记录当前圈数,避免把请求之前的完成圈数误判为新触发。`020-running-row-missed-junction` 真实阻断一次事件通知来复现这两项契约。随机切换要等当前动作的完整循环边界,官方慢速循环会让请求后的实际切换晚于 8 秒。 验证:`npm test` 408 通过 0 失败;`verify-whale-tail-tiers` 通过;浏览器回归覆盖官方 150 帧与原始 3 秒周期、6 帧衔接、动作池配置重载、单动作池、工具调用、隐藏恢复、慢速与过渡中图标重建、调速相位保持和卸载回收。