Skip to content

pulse · story:整理脉冲 ​

状态:2026-10-19,第 3 步(story),在任何东西动起来之前定下;motion 照此做。同日第三轮修改按用户反馈改了三处:两层统一成以根为圆心的几何,云里一颗亮粒子就是一条事件,采用的先落到根再顺着枝流上去;节拍随之放宽到 4.25 秒,下文已同步。第四轮(同日)用户指出枝条“弧度还是不一样”:根弧与外沿已经同心,差在枝条是先抬升再外倾的曲线,弯出了射线网格;改成每根枝就是一条射线;另加悬停与点击(见末节“交互”)。数字以 data.json 为准,节奏依据见 spec.md(写的是参考视频,没有改)。

定位。 官网用的概念性动画,不承载作答,只标问题的开与闭。show 不是目的,但想 show 就能 show、不动底层,是这套设计的优势:页面和其他形式一样只读同一份 scenario.mjs 回放(frames / batch / asks / feedback),用 engine.mjs 重放、按 notation.mjs 与 stage.mjs 的算法现算,不另造数据管道、不改契约、不加只为动画服务的字段,炫全在渲染层。同一份状态,既能压成手表上的一圈刻度,也能铺成官网的一整屏动画。

论点。 每一轮涌进来上百条,Agent 扫一遍,只有几件长进你的 64 份;真正要你开口的,一轮至多一两件(composite 28 轮里 27 轮如此,例外是从空状态起步的 f01,一次登记 5 个)。

英雄数字:本轮收到的条数 N(composite 每轮 54–234,中位 108.5)。云里虽然一颗亮粒子就是一条,234 颗没人数得清,它仍是画面上唯一能直接读出的量;不用图例就懂;它每轮大起大落,动了几件(中位 3)、新问几件(中位 1)却几乎不动,这种不对称就是论点。每轮第 1 拍出现在主图左上,字高约画面六分之一,全场只有它这么大,随事件落下从 0 计到 N;第 2 拍降到半亮,拍末右侧接上三分之一大小的“→ 动了 3”;第 3 拍朱红线打下的同一刻补上“ · 新问 1”,“新问”与它的数是朱红。静帧样张取 f20:234 → 3 → 1。

一个圆心。 两层共用以根为圆心的极坐标:根是半径 r0 的一段弧,扇形是半径 R 的圆扇(张角 160°),64 条份额线是从根出发的射线,扇形外沿是 R 处的一道细弧。每根枝就是其中一条射线从根到梢被点亮:直线,梢的半径按份额定;楔形宽度为奇数格时取正中那条,偶数格时正中落在两条射线之间,取靠自己一侧(左边的条目取左边那条,右边的取右边那条),让相邻的枝分开;补间时偏移随楔形移动连续过渡,落定的每一帧都正好在射线上(?debug=geom 画出逐枝角度差,f20 全部为 0)。概念层的一切都落在同一套坐标里:云在外沿之外的环带(从 R 到画面边缘、只在扇形张角内),事件沿射线朝根落下;收拢弧与根同心、张角等于扇形,从云的最外沿一路收到根;暂缓的余烬是外沿外侧一圈同心的环带;背景流光沿 64 条射线走,过了外沿以不到一半的亮度一直延到画面边缘。上一版的云是顶部矩形雨,扇形外沿是椭圆而弧是正圆,两层叠在一起对不齐,看起来像两张画。

三个节拍(一轮 4.25 秒。自动播放从 f00 空状态起,静 0.4 秒后根上的“64”亮一下,这是第一个动作;f01 从第 1 秒开始,约 22 秒走完 f01–f05,第 20.5 秒前后看到 f05 的让位:猫看病 12 份 → 3 份)

拍主图面板观众此刻
1 涌入 · 1.0 秒顶部打出时间、signal.reason 与旁白 frame.title;事件一条一颗,沿射线从画面外朝根落下(先快后缓、砸到位),停在外沿之外的环带里成云,按流分扇区;你对登记问题的回应沿朱红细线从根往上走N 随粒子落定逐颗计数;流水线亮“收到”好多
2 折叠 · 2.1 秒收拢弧 0.45 秒扫过云:碰到的噪音原地熄灭,暂缓的被推到外沿外侧沉成一圈余烬,采用的跟着弧走;再用 0.7 秒穿过扇形、越收越慢地合到根上,采用的一路转向所属的枝,落在它在根上的格子(2.15 秒)。停 0.12 秒(枝脚一个小亮点),每颗化成一束光顺枝从根流到梢,0.4 秒走完,同一根枝的先后流过、0.24 秒内都出发;光到哪里枝亮到哪里,到梢时枝梢闪一下、枝按新份额一点点变粗;新枝随第一束光长出,没收到光的枝 2.4 秒起变细、枯掉,或沉向根、沿根转到并入目标的射线上再淡去“没采用”随弧逐颗跳数,弧到外沿时补上暂缓 + 噪音 + 重复的分项;根上的 64 格在弧穿过扇形时重分,让出的格子空出来;2.85 秒“动了”跳数;流水线亮“归并”,光出发时亮“分配”大多数没了,只剩几根枝在变
3 一问 · 1.15 秒整屏先压暗 0.3 秒,新登记的问题再从枝梢打一道朱红亮线到根(0.14 秒画完,余光约 0.8 秒),留下一根细线;没有新问题的轮次不压暗、什么也不打,只剩余辉开着的问题加一行 short,答掉的划去;流水线亮“回应”只有这一件要我

两层,叠而不打架。

  • 概念层(约八成画面,可以炫、可以密、可以一直动):粒子云、弧的笔触、辉光、余辉、背景里缓慢流动的结构。云里一颗亮粒子就是一条真实事件(f20 是 234 颗),各带三颗更小更暗的尘埃做质感;尘埃数固定是亮粒子的三倍,弧经过就散,不进根、不成余烬。亮粒子的去向与面板的分类一一对应:f20 的 234 颗里 66 颗进根并化成 66 束光,111 颗成余烬,57 颗熄灭,与“采用 66”“没采用 168 = 暂缓 111 + 噪音 57”对得上;重复与噪音一样熄灭,未判的原地散掉。上一版每条事件放大成 4–16 颗一簇,只有疏密比例是真的,用户问“真实的事件数量和待处理的动画是否相关”,这一版收回了“绝对个数是装饰”。自带 A 式错拍时钟。只用灰白,不出文字、数字与朱红。
  • 信息层(约两成,少、准、有出处,只在节拍上动):英雄数字、根上的 64、枝的粗细、64 格带、问题面板、流水线、朱红线。每个数在 data.json 有出处,页面用同一推导现算;缓动在本拍内完成,拍外静止。
  • 规则:概念层最亮处(闪光时也算)不超过信息层的字与线;信息层每次动作的 300 毫秒内概念层压暗约三成;面板区不进粒子;概念层的大闪光放在收拢弧合到根的那一刻(2.05–2.45 秒),之后只有信息层的光在枝上走,让第 3 拍的朱红成为全场唯一的亮点;概念层不暗示信息层没有的事实:空轮不下雨,没有新问题时不闪任何像朱红线的东西。

动起来之前的约束

  • 绝不动:根的位置与“64”这个数(开场只亮一次,不移不变);枝的相对顺序(按首次出现排定,只在出现、消失时让位);朱红的含义。
  • 只动一次:f00→f01 树从根上长出;f28 之后的片尾“两周 3196 条 · 新登记 26 个问题”,随后整棵树收回根,回到 f00(全程约 124 秒)。收回的 1 秒里片尾的字先淡出、换成 f00 的字再淡入,收回结束的画面就是 f00 的第一帧,循环看不出接缝。
  • 朱红只给回应路径:新问题的亮线与细线、你的回应沿线返回、答掉后根上的记号、“新问”的数。改写后失效的细线褪成灰。不给本人事件、needs-you 条目或装饰。
  • story 数据集(每轮 0–9 条,事件没有 stream,只有一列)照同一规则跑:云稀、N 小;f17、f27 两个 review 轮不下雨,只有一道淡弧扫过,表示检查过、没有变化。

交互(2026-10-19 第四轮加,与份额拨盘的交互同一套标准):悬停看概要,点击展开详情。两者都只读同一份回放:用拨盘的 itemFacts(dial-model.mjs)取事实,但“哪条输入进了哪件”按本页自己的规则(先看批次声明引用的来源,再看 relatedIds),所以卡上“本轮进了 N 条”就是那根枝上走过的 N 束光(composite 与 story 两套数据逐轮逐件核过)。两者都让本轮的时钟停在当前时刻,概念层照走自己的钟;上面的约束照旧:根的位置与“64”不动,枝只沿自己的射线动,朱红只给回应路径。

  • 悬停
    • 触发:鼠标移到枝条上(线很细,命中区放宽到线两侧各 10 px)、它的名字、枝梢光点或它在根上的格子;Tab 到枝条;触屏没有悬停,轻点一下就是悬停。
    • 动什么:枝梢旁一张概要卡(近黑底、细框、等宽字),写来自哪条流、几份、本轮怎么变、本轮进了几条输入、开着的问题与期限,一根细引线从名字(没有名字的从枝梢)连到卡。这根枝、它的格子、名字与朱红细线保持原亮度,楔形里的份额线略提亮;其余枝、格、名字降到七成。概念层里这根枝楔形内(一直到画面边缘)的射线与粒子、以及进了它的那几颗亮粒子保持,其余降到四成。卡下的粒子退开(卡加入概念层的遮罩)。
    • 节拍:卡上的数和面板一样守本轮的节拍。停在轮中途时,弧还没把输入合到根上(2.15 秒前)就写“本轮的输入还在路上”,“动了”落定(2.85 秒)前写“本轮的份额还没落定”,朱红线打下(3.4 秒)前不列本轮新登记的问题。
    • 收回:离开 0.15 秒后概要卡用 0.12 秒淡出,再过 0.4 秒时钟接着走。
  • 展开
    • 触发:点枝条、名字、枝梢、格子或概要卡;Tab 到枝条后按 Enter 或空格。
    • 动什么:0 秒是切点,左上的信号与旁白改写成“这一件 · f20 · 时间 / 第 20 轮 · 条目标题”,三块面板切到这一件(本轮:份额与变化、进了它几条、来自哪条流;开着的问题:只列它的,带期限;流水线:它经过的段亮),面板的数仍守本轮节拍;0–0.3 秒枝条连同它在根上的格子沿自己的射线外推 8 px(ease-out,过冲 3.7%;格子推到半径 r0 + 8 的同心弧上,枝仍在原来那条射线上);0.4–0.6 秒从枝梢引出引线,先沿同一条射线出到外沿之外,再直着连到卡;0.6–0.9 秒详情卡从引线末端展开,先沿它接上的那条边、再向外。卡贴在枝条朝向一侧的画面边上,避开左上的字、底部面板和这根枝自己(旁边放不下就放它上方或下方,必要时收窄)。卡里是摘要、子层、份额逐轮(28 轮小条图,本轮亮、之后的淡)、本轮进了它的真实输入(按来源分组,标题截断)、开着的问题与期限、你的回应;不承载作答,问题旁的“去回答 →”链到同一帧的 D 手机首页。
    • 收回:Esc、点空白、再点同一根枝:卡 0.2 秒收起、引线 0.15 秒缩回、枝 0.2 秒落回,然后一帧切回旁白与面板,0.4 秒后时钟接着走。点另一根枝先收回再展开那一件。←/→、选帧、连播键与合页顶栏选帧会立即收起并照常执行。prefers-reduced-motion 时直接到终态。
  • 脚本:window.foldPulse 有与 foldDial 同名同义的 hover / unhover / open / close / ixAt / paused / pointOf,名字可用条目 id 或短名(母亲换水管、猫看病)。

和拨盘不同的地方:拨盘的扇区是面,悬停按角度命中;这里枝是线,命中区按到线的距离放宽,并把名字、枝梢与根上的格子算进来。拨盘的扇区整块平移;这里枝与格子沿半径外推,仍落在同一圆心的几何里。拨盘停的是循环与连播;这里停的是本轮 4.25 秒的时钟,停在轮中途时卡和面板都不提前说出后面节拍的事。