切换外观
打磨记录:B 时间展开 · C 流动形态
状态:原型打磨记录,2026-10-15。只描述 prototype/variants/ 里 B、C 两种形式在演示数据上的做法与验证;产品契约以 docs/ 为准。记录写于第一次自由运行(free-composite-2026-10-15)打磨出的演示数据,2026-10-15 晚按第二次自由运行(free-20261015-161501)的演示数据更新了引用:事项 ID、标签里的计数与例句换成新数据;性能数字与截图是在旧数据上测得、拍下的,没有重做,旧现象在新数据里不再出现的在原处注明。
两种形式共用新文件 prototype/variants/temporal.mjs(只给 B、C 用):
- 动作句:来源处的回应写成“你在问答站回复了 Gerda”,不贴原文;只有带
link.ask的反馈才写“回答了登记的问题「…」”,否则写“不是在回答「…」,那个问题仍开着”。原文折叠在“原文”里。 - 两周版本:29 帧份额柱(有问题的帧下方一点朱红),加版本列表,点任一柱跳到那一帧。
- 依据与来源:来源渠道小签 + 最多几条原始依据。
- 期限:问题的
due_at优先,没有再用事项的due_at。 - 回应:用
respond.mjs的控件。作答后先显示“已保存,等下一轮整理(时间)由 Agent 确认”,推进到下一帧显示“已收到”,可以撤回;推后的事到点以后,回执上加一行“已到点,在某一轮浮回 · 再推后…”。演示回放不随本页回应改写,所以回执写明“问题在回放里仍开着”。 - 焦点:阅读区重绘时,如果焦点原本在阅读区里,就把它移到回执或标题上,不掉到
<body>,Esc 和 Tab 不会失去位置。
共享文件(engine、motion、shared、app、explore、respond、data、forms 下其他文件)都没改。
截图目录:.local/polish-temporal/(不入库)。性能是 1440×900、Metal ANGLE 无头 Chrome 下用 performance.now() 自测的数字;同机有其他浏览器并发,多次运行最差值波动约 ±30%,下面写的是最近一次,括号里是多次运行的范围。
B · 时间展开
2026-10-20 按第三轮的标准重做了换轮、作答的节拍与悬停、展开(英雄数字是最近的期限还有几小时,交互共用 motion/ix.mjs),见 b-motion.md;下面是第二轮的做法,与它不一致处以 b-motion.md 为准。
场景:期限落在此刻之后的哪里。左边是最近 5 次(或全部)整理里每件事的份额带,中间是此刻的 64 份柱,右边是此刻之后:期限画成刻度,一眼看出谁先到。
承载的回应类型:schedule(定时间,如后刹排气)、choose(二选一,如猫用药)、带期限的 decide;任何进行中的事项都可以“稍后提醒”(数据集默认反馈)。
信息承载
- 份额不足 3 的事项(≥2 件时)合成中性色的“小事”带,标签写“另 6 件小事 · 6 份 · 2 件登记了问题”(f26;旧数据这一帧是 30 件、30 份、6 件,小事带是按它设计的,规则不变)。展开后,成员按真实份额和颜色分开;阅读区列出“小事”清单,登记了问题的排在前面。
- 此刻之后的条带只画在此刻线右边:分段刻度(12 小时、1 天、3 天、1 周、5 周),虚线标出下一次整理。问题的期限画成朱红三角,已过期的期限在此刻线上画粗线并写“已过 3 天”(f26 是 Signe 漫画那件事自己的期限 8/12 23:59)。你定的时间画 ◆,稍后提醒画 ◷,勾表示本页已作答(空心勾 = 已保存,实心勾 = 已收到)。
- 刻度说明按估算宽度放在左边或右边,并夹在条带内;窄屏上逐行截断加省略号,不压到此刻柱。
- 概览依次是:旁白、本轮信号、“此刻之后 · 谁先到”(按时间排序,包括下一次整理)、“本轮你在各处的回应”(动作句),再列条目。
交互清单(全部可以只用键盘完成)
| 操作 | 鼠标 / 触控 | 键盘 |
|---|---|---|
| 换帧 | ←/→ 按钮、拖动底部时间轴、点历史节点 | ←/→(外壳);时间轴上 ←/→/↑/↓、PageUp/PageDown(±5)、Home/End |
| 播放 | 播放按钮 | 空格 |
| 展开 / 收起小事 | 点小事带或它的标签 | 标签上按 Enter |
| 在标签间移动 | — | 标签上按 ↑/↓ |
| 打开详情 | 点带、标签或小事清单的行 | Enter |
| 作答 | 回应区的按钮;schedule 打开时刻面板 | Tab 到按钮后按 Enter,面板打开时焦点在第一个选项上 |
| 撤回 | 回执上的“撤回” | Tab,Enter |
| 返回 | “↶ 本轮”“← 小事列表” | Esc:先关面板,再取消选择,再收起小事,最后返回上一层 |
| 重播过渡 | “重播过渡” | — |
动画清单
- 带的帧间过渡用 340 ms(跳多帧时 420 ms),缓动
cubic-bezier(.22,.68,.32,1):起步快、落点软,读起来像生长而不是平移。只插值几何(位置、粗细、透明度);份额数字和文字直接给终值。 - 新出现的带从此刻处、从自己的中线长出来;撤下的带向中线收成一条线,再淡出。小事展开或收起 280 ms,进出层 420 ms。
- 透明度分段:离开的元素在前 34% 时间内淡出,到来的元素在 42% 以后淡入,两段文字不会同时占同一个位置。沉入小事的标签向“小事”标签的位置移动,从小事升出的标签从那里出发。
- 过渡可以被打断:新的一帧从屏幕上当前的样子起算,不会跳。
- 阅读区:回应面板 180 ms 下滑出现,回执 260 ms 上浮出现。
prefers-reduced-motion:不做补间,直接给终态(实测换帧后 0 个补间 tick);CSS 动画也关闭。- 不整页重绘:SVG 元素按 key 复用;换帧时阅读区放进下一个任务里重建,带先动起来。
性能(35 件事的 composite 数据集,指旧数据 f26 的根层;新数据 f26 只有 14 件,没有重测;走完 29 帧、倒退、每 90 ms 连续拖动,再展开收起小事)
- 每个补间 tick(采样 + 写 SVG 属性):共 1123 次,p50 2.5 ms,p95 6.4 ms,p99 8.6 ms,最差 13.9 ms(多次运行 11–14 ms),没有超过 16 ms 的。
- 换帧处理(建场景 + 准备元素 + 第一帧,不含阅读区):p50 4.4 ms,p95 11.2 ms,最差 12–20 ms。
- rAF 间隔:1441 帧里 4 帧超过 20 ms(每次只掉 1 帧,33 ms),没有超过 34 ms 的;都出现在换帧开头。
- story 数据集:tick p95 4.2 ms,最差 11.8 ms;换帧最差 12.6 ms。
截图(.local/polish-temporal/)
- 静态帧:
b-f10.png、b-f22.png、b-f26.png(35 件)、b-f12-all.png(“全部”范围)、b-story-f14.png、b-story-dive.png、b-narrow-f26.png(390 宽)、b-reduced-f26.png - 切帧过渡(f25→f26,按时间定格,每 80 ms 一张):
b-seq-0ms.png…b-seq-400ms.png,拼图sheet-b-seq.png - 展开与详情:
b-small-expanded.png、b-detail.png - 作答(schedule,kajsa-bike-brake):
b-before.png(面板打开)→b-after.png(已保存,◆ 落在此刻之后)→b-next.png(推进一帧:已收到;时间已过,◆ 消失)→b-undo.png(撤回,控件恢复)。新数据里这个 schedule 问题只在 f20 开着(f21 Kajsa 买了新车,条目改写后失效);2026-10-15 晚在 f20 作答、推进到 f21 核过,回执仍显示“已收到”。 - choose:
b-choose-before.png、b-choose-after.png - 打磨前基线:
base-b-f26.png
未解决
- 换帧开头偶尔掉 1 帧(约 0.3%),出在场景重建和第一次写入 SVG 时;要彻底消除,需要把场景计算挪到空闲时间或 worker 里。
- 标签内容在帧间是瞬切(份额数字、“已过 N 小时”),只有位置和透明度是连续的。
- “全部”范围下最左边的标签会被裁掉;窄屏上历史轴只保留隔一个的时间标注。
- 本页回应不改写回放,所以作答以后问题在回放里仍开着、仍算“需要你”。回执里写明了这一点,但图上朱红标记不会因为作答而消失。
- 刻度说明的宽度是按字符估算的,个别中英混排的说明会比实际宽或窄几个像素。
C · 流动形态
2026-10-20 起 C 按第三轮的动画与交互标准重做(换轮四段、讲一遍、悬停与展开接 motion/ix.mjs、作答收成回执),做法、数据出处与验证见 c-motion.md;本节以下仍是第一版的记录,与它不一致时以 c-motion.md 为准。
场景:可以推后的事,沉下去,到点浮起。每件 3 份以上的事是一滴液体,面积和份额成正比;不足 3 份的沉在底部,串成一串小珠。你把一件事推后,它就沉到水面以下,到点的那一帧再浮回原处。只有明确的 merged_into 才让两滴融成一滴。
承载的回应类型:defer(如 pr-13295-writeout、pr-reviews-0814 的“推到什么时候”)。旧数据里的另一例 qa-ac-range(热浪里空调控制器推到哪天)在新数据里没有成件:Agent 把空调的提问与回复判为暂缓(最后一条判为噪音)。defer 问题在详情里直接列出推到的时刻,不用再点“推到…”。没有登记问题的进行中事项,也可以用默认反馈“推后…”;其他问题照常用 respond.mjs 的控件(choose、approve、reply 等)。
信息承载
- 只给 ≥3 份的事画液滴(WebGL2 着色器,一次最多 24 个液滴,Canvas2D 兜底)。不足 3 份的是底部的 DOM 小珠,登记了问题的小珠带朱红环;说明写“小珠 6 件 · 各不足 3 份 · 2 件登记了问题”(f26;旧数据这一帧是 30 件、6 件)。
- 只有登记了问题的液滴带外部标签:标题、“等你决定 · 34 小时后到期”、问题原文(最多两行)。没有问题的大液滴,在滴内写份额和标题的前半句(冒号之前,最多两行);悬停或聚焦小珠时,用同一个提示框显示标题、份额、问题。
- 水面以下右侧是“推后”托盘:推后的事在那里缩小、变淡,像沉在深处,下方标“◷ 09:00”。64 格预算条里,推后的格子画成斜纹。
- 标题行写“5 件等你回应,2 件在液滴里,2 件是底部小珠,1 件你推后了”(f26 把 pr-reviews-0814 推后之后;推后之前是“5 件等你回应,3 件在液滴里,2 件是底部小珠”)。
- 概览:旁白;“◷ 到点浮起”(这一帧浮回来的事);本轮变化(滴入 / 融合 / 沉没 / 升降,例如“3→1 沉成小珠” / 调整);“水面以下 · 你推后的 N 件”;本轮你在各处的回应(动作句,前 5 条,其余折叠);本轮输入的处置计数。不再贴 158 条原文(f26)。
- 详情:位置(液滴、底部小珠、沉在水面以下几点浮起)、摘要、回应、份额理由、依据、来源处的回应、两周版本、原始 JSON。
交互清单(全部可以只用键盘完成)
| 操作 | 鼠标 / 触控 | 键盘 |
|---|---|---|
| 换帧 | ←/→ 按钮、拖动或点击顶部时间轴 | ←/→(外壳);时间轴上 ↑/↓、PageUp/PageDown、Home/End |
| 播放 | 播放按钮 | 空格 |
| 看一件事 | 悬停液滴或小珠,出现提示框 | Tab 到液滴、小珠或托盘里的事(顺序按优先级 rank,与形态无关),出现同样的提示框 |
| 打开详情 | 点液滴、标签、小珠或预算格 | Enter |
| 推后 | 详情里的时刻(1 小时后、2 小时后、明早 09:00);没有问题的事项先点“推后…” | Tab,Enter |
| 再推后 / 撤回 | 回执上的“再推后…”或“撤回” | Tab,Enter |
| 进入子层(story) | 点有子项的液滴 | Enter;Esc 返回 |
| 返回 | “‹ 本轮概览” | Esc:先关面板,再取消选择(焦点回到那一滴),最后返回上一层 |
动画清单
- 每滴的 x、y、半径都有自己的弹簧和速度(位置 k=92、ζ=.8,半径 k=150、ζ=.56):落点带一点回弹,可以随时被新的一帧打断而不跳;全部静止以后不再渲染。移动中的液滴沿速度方向微微拉长。
- 新的液滴从上方落下并长大;撤下的液滴下沉、缩小、淡出(“沉没”)。
- 合并:两滴(或一颗小珠)被放进同一组,着色器做平滑并集,并集半径随两滴距离变化,看起来像融成一滴;合并完成后分组取消,无关的液滴永远不会粘在一起。倒放时从宿主里分出来。
- 小珠和液滴互相交接:份额升到 3 份时,小珠变成液滴从珠位升起;降到 3 份以下时,液滴飞到珠位,再交给 DOM 小珠。小珠的位置变化用 CSS
translate过渡,悬停时放大(scale)。 - 推后:作答当下,液滴(或小珠)沉进托盘,变小变淡,到位后才显出“◷”标签。到点的那一帧,它从托盘升回原来的位置(原位置会被记住),概览出现“到点浮起”。撤回后马上开始浮回。
- 标签不跳:偏移也用弹簧;内容改变时只换文字,位置连续。标签透明度要等液滴不透明度过 .6 才出现。
prefers-reduced-motion:直接设成终态(实测换帧后只渲染 2 次),CSS 过渡也关闭。- 不整页重绘:液滴画在一块 canvas 上;DOM 覆盖层按 id 复用,只写 transform 和 opacity;换帧时阅读区放进下一个任务里重建。
性能(composite:f26 有 5 滴 + 30 颗小珠,指旧数据;新数据 f26 是 8 滴 + 6 颗小珠,没有重测;走完 29 帧、倒退、每 90 ms 连续拖动)
- 每个动画 tick(物理 + 着色器提交 + 覆盖层写入):共 1655 次,p50 0.3 ms,p95 0.8 ms,p99 1.3 ms,最差 1.7 ms(多次运行 1.3–5.8 ms),没有超过 16 ms 的。
- 含 GPU 的单次绘制(
readPixels强制同步):p50 1.6 ms,p95 5.3 ms。 - 换帧处理(布局求解 + 标签批量测量 + DOM,不含阅读区):p50 4.4 ms,p95 11.7 ms,最差 13–25 ms,大多是第一次进入某个布局时的冷启动求解。阅读区在下一个任务里重建:p95 约 7 ms,最差约 9 ms。
- rAF 间隔:1783 帧里 6 帧超过 20 ms(每次只掉 1 帧,33 ms,都在换帧开头);另一次长帧来自测量 GPU 时的同步读回,不是真实运行。
- story 数据集:tick 最差 1.7 ms;换帧最差 10 ms。
截图(.local/polish-temporal/)
- 静态帧:
c-f10.png、c-f17.png、c-f22.png、c-f26.png(拼图sheet-c-frames.png)、c-story-f14.png、c-story-dive.png、c-story-rise.png、c-narrow-f26.png、c-reduced-f26.png - 切帧过渡(f13→f14:一滴 6 份和一颗小珠融进新的一滴,按时间定格,每 80 ms 一张):
c-seq-0ms.png…c-seq-400ms.png,拼图sheet-c-seq.png;story 的合并:c-story-merge-0ms.png…c-story-merge-400ms.png。新数据里 f13→f14 只有三颗小珠并成一颗;“一滴 6 份和一颗小珠融进新的一滴”出现在 f21→f22(#13567 那滴与“待审 PR”小珠并成 pr-reviews-0814),C 的本轮变化写“融合”,2026-10-15 晚核过。 - 小珠路径(pr-13295-writeout 的 defer 问题):
c-f25.png→c-bead-hover.png(提示框)→c-detail.png(时刻直接列出)→c-after.png(已保存,沉进托盘)→c-next.png(推进一帧:已收到,仍在水下)→c-floated.png(f27 到点浮起)→c-undo.png。新数据里这个 defer 问题只在 f12–f17 开着(f18 并进“待审 PR”),f25 的 defer 问题挂在 6 份的液滴 pr-reviews-0814 上,所以这条小珠路径要在 f12–f17 走:f15 核过,小珠带朱红环,详情直接列出三个时刻。原记录保留作为设计理由。 - 液滴路径(ci-urls-master,6 份,没有登记问题,用“推后…”):
c-big-detail.png→c-big-defer-open.png→ 沉下c-sink-0ms.png…c-sink-640ms.png(拼图sheet-c-sink.png)→c-big-after.png→c-big-next.png→ 浮起c-rise-0ms.png…c-rise-640ms.png(拼图sheet-c-rise.png)→c-big-floated.png→c-big-back-detail.png(“已到点 · 再推后…”)→c-big-undo.png - 打磨前基线:
base-c-f26.png
未解决
- 浮起和沉下走直线,路上会穿过别的液滴(
c-rise-240ms.png);可以让 y 方向的弹簧比 x 方向快一些,走一条先升后移的弧线。 - 合并时新液滴用的是目标事项的颜色,融合的中间态是两种颜色的混色,没有表达“谁并进了谁”。
- 冷启动布局(第一次进入某一层或某个布局)偶尔超过 16 ms;可以预先算好各帧布局,或者分帧求解。
- 浮回“原位”是近似的:它离开期间,别的液滴会慢慢挤进那块空地,回来后会被推开一点。
- 窄屏上 3 份的小液滴不写份额数字(半径小于阈值);深色模式没有做。
- 和 B 一样,本页回应不改写回放;推后的问题在回放里仍然登记着,所以标题行仍把它算进“等你回应”,只单独注明“1 件你推后了”。
Safari 检查(2026-10-15)
合页 all.html 做完后,在 Safari 27 里实际打开看过,并用离屏 WebKit(WKWebView,与 Safari 同一引擎)按 1440×900 逐节截图,和 Chrome 无头截图并排对比;顶栏切到 f05 后再截一遍。B 时间展开的流带与 C 流动形态的 WebGL2 液滴都与 Chrome 一致,没有需要修的差异。