Communitygithub.com

wiggle-that-diagram

将一个静态的“工作原理”示意图转化为带有字幕的循环动画,并提供三种格式供读者选择,适用于HTML幻灯片或报告。

wiggle-that-diagram 是什么?

这个技能提供了一套完整的方法,用于将静态的机制流程图(如文件流转、规则检查、审批流程等)转化为三种不同风格的、带字幕的循环动画,并嵌入到HTML幻灯片或报告中。它支持三种风格:A(类似3Blue1Brown风格的干净图表视频)、B(白板手绘风格)、C(利用SVG和GSAP构建的交互式动画)。该技能的核心在于确保动画节奏适中、字幕清晰,并且所有风格共享同一个核心剧本(beats),从而实现一致的叙事。它提供了从前期分析、脚本编写、节奏验证、风格选择、构建到最终测试集成的端到端流程,特别适合用于那些需要清晰展示步骤和流程的场景,而不是简单的交互或带旁白的视频。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/wan-huiyan/wiggle-that-diagram/tree/HEAD/plugins/wiggle-that-diagram/skills/wiggle-that-diagram

在你喜欢的 AI 中提问

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

文档

wiggle-that-diagram:三种风格的解说动画

将一个静态的“工作原理”示意图转化为一个简短的、带字幕的循环动画,放入HTML幻灯片或报告中,并提供三种格式供读者选择。该方法基于一个真实的客户幻灯片项目(见“实际案例”)。它使用 huashu-art-motion 作为导演指导(分镜、镜头规则、六种失败方式),对于风格A和B,还将其作为渲染引擎。

何时使用,何时不使用

在以下情况下使用:

  • 幻灯片或HTML报告中有机制图(文件流、规则检查、人员审批),而读者应该能够“亲眼看到”它逐步发生,并配有可读的文字说明;
  • 用户希望获得真正不同格式的选项,而不是同一种动画的三种配色方案;
  • 之前的动画“太快无法阅读”或需要添加字幕。

不要将其用于:单个微交互(使用 animate)、带旁白的视频(直接使用 huashu-art-motion)、或数字图表(使用 dataviz)。

三种风格(它们的区别在于格式,而非调色板)

A · 图表片段B · 白板C · 实时SVG
画面huashu 引擎画面场景,t1_3b1b 语法,渲染为无文字H.264huashu y3_whiteboard 语法,深色背景,用笔绘制和手写文字(Kalam字体),方形视频由虚拟摄像机拍摄的内联SVG世界(通过GSAP 3.12.5 补间 viewBox)
画面上的文字基于导出的摄像机轨道将HTML标签覆盖在视频上(始终清晰)绘制到视频中(在手机上必须足够大)真实的SVG文字(清晰,可根据宽度更改摄像机帧来重排)
每个影片大小(实际案例)360–820 KB(预算900 KB)847–886 KB(预算900 KB)21–34 KB(预算40 KB)
感觉像一个干净的3Blue1Brown风格图表有人在白板上讲解一个精致的产品动画
主要风险如果场景在未重新渲染的情况下发生变化,标签会漂移严格的大小预算;手机标签 12–14 px繁琐的摄像机数学运算;GSAP变换怪癖

三者共享一份字幕脚本、相同的节拍和相同的嵌入契约,因此样式切换器可以展示用三种方式讲述的同一个故事。

方法,从端到端

每个步骤都以检查点结束,以证明该步骤已完成。

  1. 找到机制和一个具体示例。 阅读宿主页面(只读)。选取要展示的时刻,并在每个节拍中贯穿一个真实的示例(一行、一条记录、一个案例,及其真实值)。列出不得虚构的内容(ID、人物、图像)。→ 检查点:你可以将每个节拍描述为“这个对象做了这个”,包含名词和动词。

  2. 首先编写字幕脚本。 每个节拍一句字幕,每个影片3-6个节拍,保存在 beaks.json 中(格式参考:scripts/common/beats.example.json)。字幕在所有风格中完全相同。然后运行节奏检查,并读取它打印的下限:

    python3 ~/.claude/skills/wiggle-that-diagram/scripts/common/pace_check.py beats.json
    

    → 检查点:每个节拍都正常,并且用户已同意生成的循环长度(或更短的字幕)。切勿独立于字幕设置循环目标;请参阅“节奏”部分。

  3. 编写简报。 将 references/brief-template.md 的内容填入 SPEC.md:引用的反馈、令牌数、节奏规则、字幕脚本、节拍、包含完整代码片段的嵌入契约、预算、交付物。→ 检查点:一个没有其他上下文的智能体可以基于该简报进行构建。

  4. 方向选择轮次(可选,当用户尚未看到风格时)。 三个智能体并行工作,每种风格一个,分别制作同一影片的一个片段原型(约8–12秒),并在1280和390像素宽度下拍摄静态图。并排展示静态图;用户选择一个或保留全部三种。→ 检查点:用户的决定是书面形式的。

  5. 构建轮次。 每种风格一个智能体(各自继续自己的原型),构建该风格的所有影片,仅在 <work>/<style>/final/ 下写入。简报:references/agent-briefs.md。在启动前向用户说明智能体的数量和层级。→ 检查点:每个智能体返回文件、静态图、NOTES.md 和一个诚实的未解决问题列表。

  6. 构建配方(每个风格智能体实际执行的操作;脚本位于 scripts/style-a|b|c/): 两个中性影片以所有三种风格提供,每个包含 beats.json 加上 style-a/、style-b/、style-c/: examples/pizza/(5个节拍,简单)和 examples/expenses/(6个节拍:卡片、颜色编码的原因、指向第二个和第三个面板的箭头)。从对应风格的文件夹开始。

    • A. cp -R ~/.claude/skills/huashu-art-motion/scripts/engine <A>/engine 并执行 touch <A>/engine/favicon.ico。添加 engine/ways/way_make.js(来自 scripts/style-a/),运行 beats_js.py beats.json --engine engine --var <VAR>(字幕和时间来自共享脚本,绝不手动复制),创建一个场景文件 engine/ways/<film>.js,调用 WAY.make({poster, beats, camBase, cam, labels}),并注册 SCENES['<film>'],以及 engine/eras_<film>.js,设置 FILM_SIZE=[1280,720]、PUNCH=0(否则引擎会在过渡时添加0.03的推近效果)、SCENE_LIBS=['ways/way_make.js','ways/<film>_beats.js','ways/<film>.js']、SCENE_DIR='ways'、ERAS=[{id:'<film>',dur:1}]。不要在画布上绘制文字。绘图辅助函数(圆角矩形、点、线、淡入淡出、沿路径移动)是针对每个影片编写的;examples/pizza/style-a/pizza.js 包含一小套可复制的函数。然后执行 render_way.py <film> --scale 0.75 --crf 30 → build.py <film> --meta meta.json → pace_check.py work/<film>_data.json → test_embed.py final/<film>.html:<verdict beat>(或一次性完成:make.sh)。在任何场景编辑后,重新渲染并在中间移动时间点运行 midmove.py:标签必须停留在其对象上。
    • B. 以相同方式复制引擎(包含空的 favicon.ico:在真实Chrome下,其404错误被视为页面错误,render.py 在写出正常视频后也会以退出码1退出)并将 render.py 修改为 chromium.launch(channel='chrome', …)。将 kit.js 放入 engine/demos/_hb/,编写 engine/demos/<film>/board.js(使用 HB.make(),将事件锚定到 BEATS[k].t0 + offset)和 engine/demos/<film>/eras.js(FILM_SIZE=[1080,1080],PUNCH=0,Kalam字体,SCENE_LIBS=['demos/<film>/beats.js','demos/_hb/kit.js','demos/<film>/board.js'])。然后执行 build_beats.py beats.json --engine engine → uv run --with playwright python engine/render.py --film demos/<film> --fps 30 --crf 12 --out work/<film>_master.mp4 → build_html.py <film> --beats beats.json(720²,24 fps,能容纳的最低CRF)→ test_contract.py final/<film>.html --beats beats.json。每个影片最终都需要拉远到整个白板,保持≥1秒,然后擦除;空白白板是循环重新开始的地方。beats.json 中最后一个节拍的 still 由所有风格共享,并且必须在擦除开始前完成,否则海报帧和减少动效模式下的帧将显示一个半擦除的白板。移动的对象(如滑板车、盒子)是 K.custom 项,带有 handed: false,其位置是时间的函数;为每个对象指定一个结束时间,否则它在完成工作后会一直停留在白板上。
    • C. 从 examples/pizza/style-c/(SVG、时间线、主题)开始。编写 src/<film>.svg(一个 `<svg id=

相关技能