
Archify 视觉演进第 13 轮Path-aware Story Trail——把命名视图变成沿真实路径的语义叙事【免费下载链接】archifyAgent skill for beautiful, verifiable architecture, workflow, sequence,>项目地址: https://gitcode.com/GitHub_Trending/arch/archify导读本文聚焦 Archify 项目中「视觉演进 Round 13」的核心产出Path-aware Story Trail路径感知的故事轨迹。它是一个完全运行在 Viewer 侧的阅读层把 Guided View 的有序focus列表翻译成一条紧凑的文本轨迹rail并沿着图中真实渲染的边做运动叠加回答读者最关心的问题——当前视图里到底什么在动、方向是否真实。读完本文你将掌握 Story Trail 的关系判定规则→/←/·、叠加层如何在不污染原图语义的前提下克隆路径几何、播放调度与深链#view…beat…的工作机制以及它在导出、无障碍与降级场景下的完整边界。一、读者问题静态分镜缺少路径感在 Round 13 之前Archify 的 Viewer 已经能做到两件事播放命名引导视图Guided Views以及让Semantic Camera对每一次选区进行取景。但把两者串起来看切换仍然像一叠静态截图Viewer 只报出章节名却没有展示这一章里有序的语义站点ordered semantic stops章节内部的关系不会随着讲解真正动起来环境光效ambient trace animation能让 Demo 显得有生命力却没有回答读者更关键的问题这个视图里移动的是什么哪个方向是真实的Round 13 的解题思路因此确立不追求让每一条线都动而是把运动绑定到当前正在讲解的那个精确语义子图semantic subgraph上。关联文档docs/research-visual-evolution-round-13.md二、值得借鉴的模式运动必须保留语义文档调研了多个图可视化领域的成熟做法提炼出四条可借鉴的准则线的颜色与虚线样式必须承载语义视觉丰富度不能沦为装饰来源于 fireworks-tech-graph 类项目的经验常驻的蚂蚁线与呼吸效果属于元素级动画局部动画应能覆盖全局默认类 G6 动画指南的结论动画作用域应当收窄到单条边而不是把运动做成整个画布的全局属性类 React Flow Edge API 的思路动画应复用已经计算好的真实边路径路径定义与动画生命周期分离类 React Flow animated-edge 示例的做法。文档明确点出真正值得借鉴的不是让每条线都动而是bind motion to the exact semantic subgraph currently being explained——运动只应发生在当前被解释的语义子图上。三、核心决策Story Trail 是 guided view 的派生阅读层Story Trail 的关键架构约束是完全从已有的 Guided View 派生不新增任何 schema 字段也不做超出渲染语义钩子semantic hooks之外的拓扑推断。这与guidedViews在 schema 中的地位完全一致——它只是把作者已经写好的有序选择翻译成视觉叙事。3.1 Guided View 的 schema 基础focus数组是 Story Trail 的唯一数据来源。依据 archify/schemas/common.schema.json一个 Guided View 的结构如下additionalProperties: false字段严格受限{ guidedViews: [ { id: trace-flow, label: Trace flow, focus: [External API, Context Store, Trace Log], note: 最长 140 字符的章节说明可选 } ] }约束要点id复用通用$defs/idlabel最短 1 字符、最长 48 字符focus是有序的节点 id 数组minItems: 1整个guidedViews最多 5 个视图maxItems: 5。3.2 三条派生规则有序 focus 变成紧凑文本 railmeta.views[].focus列表渲染为一行可横向滚动的按钮序列关系标记只反映真实边相邻两个站点之间只有当渲染图中确实存在正向边时才显示→只有反向边时显示←二者都没有但属于主题性排序时显示·详见第五节的关系判定运动叠加层覆盖所有真实边只要一条真实渲染边的 source 与 target 都入选不限于相邻 focus 项它就会被纳入动画叠加——因此分支branches、汇合joins和重复的 sequence 消息都能被完整呈现。3.3 叠加层是无标记的几何克隆文档给出了严格的克隆纪律叠加形状只克隆path/line/polyline几何不携带marker、边 key、关系元数据、标签或交互状态。克隆过程中会逐个剥离这些属性在 archify/assets/template.html 中可以看到完整的属性清理列表id、marker-start、marker-mid、marker-end、aria-label、role、data-animate、data-edge-from、data-edge-to、data-edge-key、data-edge-id、data-edge-label。叠加层通过firstEdge.parentNode.insertBefore(overlay, firstEdge)template.html插入到作者边图层之下因此原始颜色、虚线样式、箭头、标签和 z-order 始终保持权威性——叠加只是影子。3.4 播放与静态态播放playback拥有运动叠加层只有正在播放时才挂上data-story-playing暂停或深链deep-link打开的视图只保留克制的静态路径辉光static path glow不做循环动画prefers-reduced-motion完全禁用轨迹流动与站点动画但保留可读的有序 rail 和静态选中子图导出SVG/raster序列化前移除叠加层、Story Trail 状态、节点 step 变量、语义 focus 与相机变换保证导出物回到作者画布的干净状态同一套 Viewer 契约覆盖 architecture、workflow、sequence、dataflow、lifecycle 五种渲染器。四、源码级实现剖析4.1 关系判定storyStep()如何区分→/←/·核心逻辑在 template.html 的storyStep(view, index, edgeList, byId)取出view.focus[index]作为当前站点 idfocus[index - 1]作为前驱 id遍历[data-edge-from][data-edge-to]边列表按from previousId to id收集正向边按反向条件收集反向边源码中from id to previousId见 template.html正向边与反向边各自去重后合并再按原边列表顺序排序由此推导五类relationrelation判定条件rail 记号语义startindex 0—轨迹起点forward恰好 1 条边且为正向→真实正向关系reverse恰好 1 条边且为反向←真实反向关系不改写方向multiple边数 1⇄caption 用并行/重复消息group无任何边·主题性排序非直接关系这个判定被同名的测试断言直接锁定edges.length 1 forward.length 1 ? forwardarchify/test/story-trail.test.mjs。4.2 rail 渲染与叠加层构建renderStoryTrail()renderStoryTrail(view)template.html是整条轨迹的装配函数收集[data-node-id]与[data-edge-from][data-edge-to]建立byId索引为每个 focus 站点生成storyStep给对应节点打上data-story-step与 CSS 变量--story-step为每个站点创建button classguided-view-stop写入data-story-node/data-story-index/data-story-relation/data-story-number/data-story-link并设置 ARIA 标签与 title文本来自storyBeatAria/storyBeatCopy支持 i18n组装叠加层对每个 step 的每条边克隆其path/line/polyline几何打上story-trail-flow类与data-story-beat-step包进带 transform 的g最后插入到第一条第边的下方。rail 容器是idguided-view-trail、rolegroup、aria-label走 i18n 的隐藏元素默认hidden站点数为 0 时保持隐藏见 template.html 与测试断言 story-trail.test.mjs。4.3 Beat 状态机past / active / next / pending播放过程用data-story-beat表达第几步 / 共几步并用storyBeatState()template.html把每一步标记为四态之一past、active、next、pending。对应的 CSS 定义了辉光强度层级template.htmlsvg[data-story-beat] .story-trail-flow { opacity: 0; transition: opacity 160ms ease; } svg[data-story-beat] .story-trail-flow[data-story-beat-statepast] { opacity: 0.34; } svg[data-story-beat] .story-trail-flow[data-story-beat-statenext] { opacity: 0.2; } svg[data-story-beat] .story-trail-flow[data-story-beat-stateactive] { opacity: 0.92; }站点按钮与 SVG 节点/边同步获得相同的 beat-state 标记active站点同时设置aria-currentsteptemplate.html保证屏幕阅读器能跟随叙事节奏。4.4 播放调度与驻留时间scheduleStoryPlayback()template.html控制整条轨迹的推进每一步的驻留时间由storyBeatDwell(total) Math.max(STORY_FOLLOW_MIN_DWELL_MS, VIEW_INTERVAL_MS / Math.max(1, total))计算template.html——站点越多单步驻留越短但不会低于最小驻留值用setTimeout驱动下一步并携带storyPlaybackGeneration代际编号防止切换视图后旧的定时器误触发template.html章节播完finishStoryChapter会自动交接给下一个 Guided View 继续播放template.html进度条动画archify-guided-progress与分享 cue 的进度同步由startProgress/currentStoryProgress管理。4.5 语义相机跟随followStoryStep()为了让动的边始终处于视野内每一步会调用Archify.view.reveal()template.html参数为padding: 64、maxScale: 1.65——与文档中约 2× 取景的浏览器验证结果一致duration: STORY_FOLLOW_DURATION_MS若reducedMotion()或data-motion ! live则instant: true直接落位而非平滑移动。跟随期间面板标记data-story-followmoving完成后变为settled异常中断则为interrupted。4.6 脉冲 token单步的蚂蚁线载体播放到某一步时pulseStoryStep()template.html还会在该步唯一的正向/反向边上叠加一个流动的 carrier token通过Archify.flowTokens.create()生成 0.78s 的流动元素包进story-carrier-overlay并插入到第一个节点之前同时通过Archify.motionGovernor.claim(story, …)申请运动资源确保与全局运动治理motion governor协调动画结束后自动释放 token 并清理 overlay。该能力受storyMotionAllowed()门控文档隐藏、reduced-motion、非 live 模式、或 embed 未开启 share-playback 时都不触发。4.7 深链#view…beat…每一步都有一个可复制的时刻链接。storyMomentLink()template.html生成#viewview.idbeatnodeId形式的 hash粘贴该链接的读者会直接落在该视图的该语义站点上hashBeatMatchesCurrent()校验 hash 与当前状态是否一致。这解释了文档中导航/深链会从新选中的子图重建叠加层的行为。4.8 导出清理保证导出物回到作者画布文档规定导出前必须移除 Story Trail 状态。在导出克隆逻辑中可以看到硬性清理clone.removeAttribute(data-story-active)、clone.removeAttribute(data-story-playing)template.html清理[data-story-overlay], [data-story-carrier-overlay]与[data-story-step], [data-story-beat-state], [data-story-beat-step]并移除--story-step样式属性story-trail.test.mjscanonicalStateClean会把data-story-active/data-story-playing等视为非规范状态template.html非规范状态直接拒绝导出viewer.export.error.viewerState见 template.html——从机制上杜绝带播放痕迹的导出物。五、浏览器驱动的修正→不能臆造·才是诚实文档记录了一次由真实浏览器验证暴露的正确性 bug第一版 rail 在每两个相邻 focus 项之间无条件渲染→。但部分 Guided View 是主题性子图于是External API → Context Store → Trace Log就错误地暗示了一条并不存在的边。修正后的行为External API · Context Store → Trace Log文本 rail 上External API · Context Store主题排序无直接关系与Context Store → Trace Log真实正向边分得很清楚图内叠加层两条真实内部边External API → Trace Log与Context Store → Trace Log照常动画反向关系同理渲染为←而非悄悄把方向转正。浏览器验证还确认了以下事实Presentation Stage把所有选中节点保持在语义相机内约 2× 尺度安全视图safety view恰好生成 3 个无 marker 的轨迹形状而原始安全边仍保留a-security类、虚线 marker 与 trace 元数据——叠加层确实没有污染原图390px 移动端rail 在 253px 的横向阅读面内保持 21px 高文档整体仍是精确的 390px 宽SVG 维持移动端 100% 模型暂停移除播放态但不删除静态轨迹导航/深链会按新选中的子图重建叠加层。六、刻意不借鉴的部分不做假叙事文档最后明确划出了边界Archify不会引入动画时间线 schema、不移动节点、不做可编辑关键帧、不引入图运行时、也不允许任意路径创作。Story Trail 是编译后 SVG 语义之上的诚实阅读层a truthful reading layer如果源图里不存在某条关系Viewer 绝不会为了视觉连贯而虚构一条。这条约束与第五节的关系判定、第四节的克隆纪律一脉相承动画永远从属于语义语义永远来自作者画布。七、测试与验证矩阵Story Trail 的正确性由 archify/test/story-trail.test.mjs 完整锁定测试覆盖五种渲染器各自使用真实示例输入渲染器测试输入architectureweb-app.architecture.jsonworkflowagent-tool-call.workflow.jsonsequencecache-miss-request.sequence.jsondataflowproduct-analytics.dataflow.jsonlifecycleagent-run.lifecycle.json每条断言都对应本文讲解过的机制rail 的 ARIA 结构rolegroup、aria-labelStory trail与按钮语义renderStoryTrail/storyStep/scheduleStoryPlayback等关键函数存在关系判定的forward分支、prefers-reduced-motion: reduce降级、overlay 插入位置导出克隆中data-story-*状态被全部移除且生成的 SVG 中不得残留data-story-*痕迹。八、延伸阅读架构契约与 guided view 语义references/authoring-contract.md各渲染器的 Viewer 契约references/viewer-runtime.md五种渲染器实现renderers/architecture/render-architecture.mjs、renderers/workflow/render-workflow.mjs、renderers/sequence/render-sequence.mjs、renderers/dataflow/render-dataflow.mjs、renderers/lifecycle/render-lifecycle.mjs相关 Viewer 测试动画治理 archify/test/motion-governor.test.mjs、动画基础 archify/test/animation.test.mjs、站点导航器 archify/test/story-beat-navigator.test.mjs前序研究文档docs/research-fireworks-tech-graph.md【免费下载链接】archifyAgent skill for beautiful, verifiable architecture, workflow, sequence,>项目地址: https://gitcode.com/GitHub_Trending/arch/archify创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考