Communitygithub.com

caceresfjulian/motion-figure

构建可移动或响应用户交互的图形,分为三个层级:课程中的SMIL动画和滑块组件、显示系统命名部件并计算结论的交互式机构图,以及课程调色板中的有序抖动色带。

motion-figure 是什么?

Motion Figure 技能专为 AI 代理(如 Claude Code、Cursor、Codex 等)设计,用于在技术文档、课程和页面中创建动态和交互式图形。它提供三个层级:第一层用于课程内部,通过声明式 SMIL 动画或滑块组件实现图形随时间或参数变化;第二层适用于独立页面,构建显示真实系统命名部件并允许读者调节参数以获取计算结果的交互式机构图;第三层则用于页眉或章节分隔,生成基于 WebGL 的有序抖动色带。该技能强调遵循严格的规则集以确保可访问性、性能(如 SVG 元素数量限制)和跨主题兼容性。它通过读取 SKILL.md 文件的代理工作,并利用引用文件(如 `references/smil-rules.md`)和模板来指导实现。总体而言,Motion Figure 通过精确控制动画和交互逻辑,提升了技术内容的直观性和参与度。

兼容平台✓Claude Code✓Codex CLI✓Cursor
npx skills add https://github.com/caceresfjulian/ai-engineering-from-scratch/tree/HEAD/.claude/skills/motion-figure

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

运动图形

本技能用于制作可移动或响应用户输入的图形,分为三个层级。可与 Claude、Cursor、Codex、OpenClaw、Hermes 或任何读取 SKILL.md 的代理一起使用。

层级制作内容放置位置
1. 课程图形声明式 SMIL 动画,或可重绘 SVG 的滑块组件。两者均通过 ```figure 栅栏挂载。课程内容
2. 机构图一个 HTML 面板,显示系统的命名部件。读者驱动一个控件并读取计算的结论。独立页面、README、文章、课程站点内非课程页面
3. 抖动场使用纸张色、强调色和墨水色的有序抖动点构成的 WebGL 色带,带有四种种子运动。页面页眉和章节分隔

层级 1 的规则最多,因为课程运行时环境有严格限制。层级 2 和 3 有其各自的参考文件。

何时使用

  • 课程解释随时间变化的过程:如经过各阶段的令牌、逐渐填满的队列、重复的循环。
  • 课程解释一个公式,其中一个输入改变输出:如学习率、温度、块大小、批次大小。
  • 作者写下“为此图形添加动画”、“添加滑块”或“使图表可交互”。
  • 页面需要一个演示,读者改变一个参数并观察系统行为:如缓存、队列、上下文窗口、路由器。使用层级 2。
  • 页面需要一个使用课程颜色的缓慢移动的页眉。使用层级 3。

何时不使用

  • 想法是一个固定结构,没有时间轴和输入。制作一个静态 SVG 图形。同级技能 blueprint-figure 负责静态图形。
  • 页面是一个完整的解释器页面,拥有自己的状态模型和机器几何结构。同级技能 isometric-explainer 负责此情况。
  • 你只需要调色板、字体或散文规则。同级技能 course-style 包含这些。本技能将其所需部分复制到 references/tokens.md 中。

方法

  1. 写一个句子,命名图形展示的单一变化。如果需要两个句子,则制作两个图形。

  2. 选择层级。在课程内部,使用层级 1。对于层级 2,阅读 references/mechanism-figures.md 并从 templates/mechanism.html 开始。对于层级 3,阅读 references/dither-fields.md 并复制 templates/dither.js。以下步骤针对层级 1。在层级 1 中,当时间作为变量时使用动画图形;当数字作为变量时使用滑块组件。

  3. 选择一个短横线命名,例如 request-path 或 context-budget。首先在注册表中搜索该名称。后续模块注册相同名称将替换先前的图形。

  4. 将代码放入名为 figures-<topic>.js 的模块文件中。用 IIFE 包裹,读取 window.LF,如果缺失则提前返回。

  5. 编写一个图形函数 function (host, cfg)。它向 host 追加一个 .lf 卡片,并可返回一个 dispose 函数。

  6. 构建卡片:带大写 .lf-label 和简短提示的 .lf-head、.lf-body,以及带标题的 .lf-cap。

  7. SVG 使用 viewBox="0 0 520 H"。大多数课程图形的 H 在 200 到 250 之间。单个条形需要更小。

  8. 添加 <title> 和 <desc>,并使用在 render 函数外创建一次的 id。

  9. 对于动画图形,先添加入场动画,然后一个慢速循环。逐行遵循 references/smil-rules.md。

  10. 对于滑块组件,在调用 LF.slider 或 LF.select 之前定义 state._render。然后在最后调用 state._render() 一次。

  11. 在模块末尾调用 LF.register({ 'your-name': fn })。

  12. 在课程 Markdown 中,添加栅栏。将名称放在第一行,可选的 JSON 配置放在其后:

    ```figure
    context-budget {"windowK": 32}
    ```
    
  13. 运行“完成前检查”中的检查。在浅色主题、深色主题、375 px 宽度以及启用减少动效时查看图形。

页面如何挂载图形

  • Markdown 解析器将栅栏转换为 <div class="lesson-figure" data-figure="name {json}">。
  • 站点构建扫描课程 Markdown 以寻找栅栏名称。它找到包含引用名称的模块文件并写入清单。没有提供者的栅栏名称会停止构建。
  • 页面仅加载课程所需的模块,按固定顺序。新模块文件按字母顺序排在已列出的模块之后。
  • 挂载函数读取第一个单词作为名称,并将剩余部分解析为 JSON。格式错误的 JSON 给出空 cfg。
  • 如果图形函数抛出异常,运行时清空宿主元素并记录警告。课程的其余部分仍正常渲染。
  • 挂载后,运行时添加标题、描述、role="img",如果缺少控件标签则添加。当图形有 SMIL 动画时添加暂停按钮,当任何动画播放一次时添加重播按钮。
  • 当图形离开视口、标签页隐藏或读者按下暂停时,运行时暂停动画。在减少动效或打印模式下,显示静态帧。

references/toolkit.md 描述了每个运行时函数,并有两个完整的示例模块。

规则

动画图形:

  1. 仅使用 <animate>、<animateTransform> 和 <animateMotion>。不要在图形中使用 setInterval 或 requestAnimationFrame。
  2. 每个图形最多包含 55 个 SVG 元素。
  3. 入场动画从不透明度 0 和缩放 0.95 开始,到不透明度 1 和缩放 1 结束。切勿以 0 为起始缩放值。
  4. 入场使用 calcMode="spline" 和 keySplines="0.23 1 0.32 1"。入场持续时间为 0.5 到 0.6 秒。
  5. 入场开始时间交错 0.05 到 0.4 秒。退场持续时长短于入场。
  6. 循环持续 2.5 到 6 秒,并使用 repeatCount="indefinite"。不要对循环设置 fill="freeze",否则运行时将使其只播放一次。
  7. 每个 keyTimes 列表的元素数量与 values 相同。它以 0 开始,以 1 结束,并且从不递减。
  8. 每个 keySplines 列表比 keyTimes 少一个元素。仅在 calcMode="spline" 时使用。
  9. 带 keyPoints 的 animateMotion 使用 calcMode="linear"。其 keyPoints 数量等于 keyTimes 数量。它没有 values。
  10. 不要在动画的 fill 或 stroke 值中使用 var()。应动画一个具有目标颜色的辅助元素的不透明度。
  11. 循环仅动画不透明度、变换、stroke-dashoffset 或沿路径的运动。运行时将使任何对 x、y、x1、y1、x2、y2、width、height、r、cx、cy、rx 或 ry 的动画只播放一次。
  12. 宿主元素 data-static-time(默认 1.5 秒)处的帧应完整且可读。当稍后时刻显示完整状态时,在宿主上设置该属性。
  13. 围绕中心缩放元素。围绕 (0, 0) 绘制组的内容,并使用 translate 移动组。使用 additive="sum" 添加缩放。

滑块组件:

  1. 仅编写 ES5:使用 var、函数表达式、字符串拼接。禁止使用箭头函数、let、const 或模板字面量。
  2. 在第一次调用 LF.slider 或 LF.select 前定义 state._render。滑块在创建时包装渲染函数。
  3. 在 state._render 中,移除所有 SVG 子元素并重新添加。不要原地编辑节点。
  4. 在 state._render 外部创建一次 id。运行时会移除新节点没有的属性,包括 id。
  5. 通过长度或路径上的 stroke-dasharray 来增长条状元素。不要使用缩放增长条状元素,因为协调后的节点从中心缩放。
  6. 保持每个滑块标签简短,小写,并附上括号内的单位,例如 chunk size (tokens)。

两种图形:

  1. 从 CSS 变量中获取所有颜色,并以浅色主题值作为默认值,例如 var(--blueprint,#3553ff)。仅当没有变量可用时才使用字面十六进制。
  2. 最多使用一种强调色 (--blueprint) 用于主要对象,--warn 用于一种次要状态。其余部分使用墨色和规则令牌。
  3. SVG 文本设置为 12 单位或更大,使用 var(--font-mono)。如果标签必须更小,则赋予 SVG 最小宽度 500 px,并允许其横向滚动。
  4. 在手机上测量标签大小。在 375 px 屏幕上,卡片内 520 单位的 SVG 绘制为 279 px 宽。12 单位的标签大约绘制为 6.4 px。
  5. 使用纯技术英语编写标题。说明每种颜色代表什么。保持句子在 25 个单词或更少。
  6. 在 .lf-label 中以大写形式给出标签,两到四个单词。

机构图(层级 2):

  1. 显示真实名称和真实数字:文件名、键、令牌计数。切勿使用 item 1 或没有名称的灰色条。
  2. 为读者提供一个控件:步骤、滑块、开关、播放或停止某个部分。
  3. 以文本形式结束一个结论行,该结论根据主体中的数字计算得出。切勿编写固定的结果。
  4. 当图形 35% 可见时运行一次,添加重播按钮,且永不循环。
  5. 仅动画 transform 和 opacity,使用 cubic-bezier(0.23, 1, 0.32, 1)。按压时间 120 到 160 ms,揭示时间 200 到 300 ms,折叠时间 380 到 500 ms。
  6. 每个项目交错 30 到 70 ms,仅针对前 8 个项目。
  7. 保持每个标签在所有帧中完整:无省略号、无重叠、无文本覆盖在点上。文本 11 px 或更大,结论 12.5 px 或更大。
  8. 在 320 px 宽度下,将面板堆叠成一列,并为每个控件提供 40 px 的触摸目标。
  9. 使用站点上其他页面未使用的机制,并将其添加到站点的机制表中。

抖动场(层级 3):

  1. 从 --bg、--blueprint 和 --ink 读取颜色,并在 data-theme 变化时重绘。
  2. 最多以每秒 30 帧的速度绘制,且仅在色带可见时绘制。
  3. 在减少动效模式下,绘制一个静态帧。没有 WebGL 时,显示静态阴影线。
  4. 将色带标记为 aria-hidden="true",并且除标签标签外,不要在点上放置任何文本。

完成前检查

  • 栅栏名称与注册名称完全匹配,且没有其他模块注册该名称。
  • 模块中没有 =>、let、const 或反引号字符串。
  • 模块中没有 setInterval 和 requestAnimationFrame。
  • references/smil-rules.md 中的验证器对挂载的宿主返回空列表。
  • 每个动画图形的 SVG 元素不超过 55 个。
  • 每个循环的持续时间在 2.5 到 6 秒之间。
  • 没有循环动画规则 11 中的几何属性。
  • 启用减少动效时,图形显示完整图片,且没有元素缺失。
  • 在深色主题下,每条线和标签均可见。
  • 在 375 px 宽度下,每个标签均可读,且页面在图形外没有水平滚动。
  • 对于组件,将每个滑块移动到其最小值和最大值不会产生 NaN、负宽度或控制台错误。
  • SVG 有一个标题和一个描述,并且它们的 ID 在滑块移动后保持不变。
  • 标题命名了图形使用的每种颜色。
  • 层级 2:references/mechanism-figures.md 末尾的检查清单中的所有项目均通过。
  • 层级 3:references/dither-fields.md 末尾的检查清单中的所有项目均通过。

文件

  • references/smil-rules.md:完整的十二条 SMIL 规则、每条规则防止的问题以及在浏览器控制台可运行的验证器。
  • references/toolkit.md:LF 函数和挂载序列。它还包含一个完整的滑块组件、一个完整的 SMIL 图形以及一个用于课程站点外使用的预览页面。
  • references/tokens.md:浅色和深色主题的颜色令牌、字体和动效时序值。
  • references/mechanism-figures.md:层级 2。真实名称、被拒绝的图形、机制形状、结构、结论、动效预算和检查。
  • references/dither-fields.md:层级 3。着色器绘制方式、四种运动、标记、规则、抖动条和检查。
  • templates/mechanism.html:一个完整的层级 2 图形,带有大小控制的 LRU 缓存,可在任何浏览器中打开。
  • templates/dither.js:一个完整的层级 3 脚本。加载它并添加 <div class="dither" data-seed="...">。

在 AI Engineering from Scratch 仓库中,还可以查看运行时文件 site/lesson-figures.js 和更多图形文件 site/figures-*.js。

相关技能