关于 diagram-animation
diagram-animation 是用于制作图表和数据动画的技能,面向网页或视频中的流程图、架构图和图表。它强调按节点、连线、标签的顺序逐步呈现,并提供动画实现与验证指导。
主要功能
- 01按顺序呈现节点、连线和标签
- 02制作流动连线与动画图表
- 03提供 SVG、CSS 和 GSAP 实现参考
- 04支持减少动态效果偏好
- 05指导独立 HTML 动画的截图验证
适用场景
- 01逐步展示架构或时序图
- 02制作柱状图和折线图动画
- 03说明流程或数据如何流动
- 04生成可定格检查的独立动画页面
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ iart-ai/ explainer-video-skills --skill diagram-animation安装后在 Claude Code 中输入/diagram-animation确认已加载。
附带文件README.mdreferences/diagram-and-chart-recipes.md
详细介绍
图表与数据动画
通过随时间逐步呈现结构和数据,让内容清晰易懂——每个节拍只表达一个要点。为网页或视频制作逐步显现的节点和边、流动的连接线,以及动画图表(柱形增长、线条绘制、数字递增)。
适用场景
- 逐步构建的架构图、流程图或时序图。
- 动画图表:柱形增长、线条绘制、数字递增。
- “工作原理”演示和流程解说。
- 展示数据或信号沿连接线流动。
核心原则:渐进式呈现
不要一次性展示所有内容。按以下顺序呈现:节点 → 边 → 标签。突出显示当前元素,并弱化其余元素(焦点 + 上下文)。节奏以便于理解为准,而非追求炫目——每一步停留 0.5–1.5 秒,让观众有时间消化。保持一致的视觉表达规则:颜色承载含义,且在整个内容中始终保持一致。
快速参考
| 目标 | 机制 | 缓动 |
|---|---|---|
| 节点出现 | 缩放 0.8→1 + 不透明度,transform-origin:center | back.out(1.5) / easeOut |
| 连接边 | stroke-dashoffset 从 len→0 | easeInOut,0.4–0.7s |
| 数据流动 | 循环动画 stroke-dashoffset + 移动的圆点 | linear,无限循环 |
| 柱形增长 | scaleY 从 0→1,transform-origin:bottom | easeOut,交错延迟 0.06s |
| 折线图 | 路径 stroke-dashoffset 从 len→0 | easeInOut,0.8–1.2s |
| 数字递增 | 使用缓动后的 t 对数值进行插值 | easeOutCubic |
| 高亮 | 当前元素不透明度为 1,其余元素为 opacity:.35 | 0.3s |
逐步显现节点和边(SVG + GSAP)
<svg viewBox="0 0 400 200" id="flow">
<g class="node" opacity="0"><circle cx="60" cy="100" r="28" fill="#0A84FF"/></g>
<g class="node" opacity="0"><circle cx="200" cy="100" r="28" fill="#0A84FF"/></g>
<g class="node" opacity="0"><circle cx="340" cy="100" r="28" fill="#0A84FF"/></g>
<path class="edge" d="M88 100 H172" stroke="#888" stroke-width="3" fill="none" pathLength="1"/>
<path class="edge" d="M228 100 H312" stroke="#888" stroke-width="3" fill="none" pathLength="1"/>
</svg>
<script type="module">
import gsap from "https://cdn.jsdelivr.net/npm/gsap/+esm";
gsap.set(".edge", { strokeDasharray: 1, strokeDashoffset: 1 });
const tl = gsap.timeline({ defaults: { ease: "power2.out" } });
tl.to(".node", { opacity: 1, scale: 1, transformOrigin: "center",
duration: .45, stagger: .35, ease: "back.out(1.6)", startAt: { scale: .8 } })
.to(".edge", { strokeDashoffset: 0, duration: .5, stagger: .35 }, "-=0.9");
</script>
pathLength="1" 可以让同一个虚线偏移值适用于任意长度的边。先显现节点,再绘制连接这些已显示节点的边。
流动连接线(移动的虚线 + 移动圆点)
.flow-line { stroke-dasharray: 8 8; animation: march 0.6s linear infinite; }
@keyframes march { to { stroke-dashoffset: -16; } } /* = sum of dash pattern */
@media (prefers-reduced-motion: reduce){ .flow-line { animation: none; } }
沿路径移动的圆点(offset-path,无需 JS):
.packet { offset-path: path("M88 100 H312"); animation: travel 1.4s linear infinite; }
@keyframes travel { to { offset-distance: 100%; } }
图表
柱形增长(从基线开始进行 scaleY 变换):
.bar { transform: scaleY(0); transform-origin: bottom; }
.bar.in { transform: scaleY(1); transition: transform .6s cubic-bezier(.22,1,.36,1); }
/* stagger via inline transition-delay per bar */
折线图绘制效果(绘制整个系列路径):
const len = pathEl.getTotalLength();
pathEl.style.strokeDasharray = len;
pathEl.style.strokeDashoffset = len;
pathEl.getBoundingClientRect(); // force reflow
pathEl.style.transition = "stroke-dashoffset 1s ease-in-out";
pathEl.style.strokeDashoffset = "0";
通过缓动插值递增数字(rAF):
function countUp(el, to, dur = 1200) {
const t0 = performance.now();
const fmt = new Intl.NumberFormat();
(function tick(now){
const k = Math.min(1, (now - t0) / dur);
const e = 1 - Math.pow(1 - k, 3); // easeOutCubic
el.textContent = fmt.format(Math.round(to * e));
if (k < 1) requestAnimationFrame(tick);
})(t0);
}
构建工具选择
- 内联动画 SVG + GSAP/CSS:最适合制作定制图表,并在网页上获得全面控制。
- Framer Motion (React):通过
variants+staggerChildren声明式地呈现内容;可与 Visx/Recharts 搭配制作图表。 - D3 + transitions:适用于数据绑定图表;使用
.transition().duration().attr()实现增长/绘制,使用tween实现数字递增。 - Mermaid / Excalidraw:快速编写图表结构,渲染为 SVG,然后为 SVG 添加动画。
- Remotion (React):适用于视频输出和可重复导出,可生成由数据驱动的确定性渲染结果。
输出检查清单
- 按节点 → 边 → 标签的顺序呈现;不会一次性显示所有内容。
- 每一步停留足够长的时间,便于阅读(0.5–1.5 秒)。
- 颜色表达规则一致且有意义。
- 当前元素突出显示,上下文元素弱化。
prefers-reduced-motion模式会显示最终组合图表,不包含循环动画。
交付与验证(独立 HTML)
打包的辅助脚本(
scripts/):scripts/seek-shot.sh anim.html 0 1.5 3会冻结?t=N测试框架,并为每个时刻截图;scripts/contact-sheet.sh sheet.png frame-*.png会将截图拼成一张图,方便一眼查看。参见scripts/README.md。
对于自包含图表(揭示动画、流动连接线、动画图表),交付物应是一个可直接在浏览器中打开的 HTML 文件——无需构建步骤,也无需渲染流程。单文件是网页动效的合适方案。(如果图表属于渲染视频的一部分,则应改为构建 Remotion composition,并通过 remotion still 验证——参见 remotion-video。)
输出约定:
- 一个
.html文件:内嵌 SVG;通过 CDN 加载 Framer Motion / D3 / anime / GSAP;动画放在一个内嵌<script>中(一个驱动器)。 - 提供一种方式,可冻结到用于截图的精确时刻,并与图表的动画方式相匹配:
- GSAP / JS 时间轴:构建一个主
tl,然后?t=N→tl.pause(); tl.seek(N)。 - SVG SMIL:
svg.pauseAnimations(); svg.setCurrentTime(N)。 - CSS 关键帧:使用
animationDelay控制揭示顺序;通过暂停或跳转到等效的 JS 时间轴来冻结。
- GSAP / JS 时间轴:构建一个主
<script>
// ... build your master timeline as `tl` ...
const t = new URLSearchParams(location.search).get("t");
if (t !== null) { tl.pause(); tl.seek(parseFloat(t)); } // frozen at t seconds
window.__ready = true; // ready signal for headless wait
console.log("duration", tl.duration());
</script>
验证循环——渲染 → 冻结 → 截图 → 检查:
- 在起始 / 中间 / 结束时打开文件:
…/diagram.html?t=0、?t=<dur/2>、?t=<dur>(在控制台读取tl.duration())。 - 对每个冻结帧进行无头截图:
npx playwright screenshot --wait-for-timeout=500 "file://$PWD/diagram.html?t=1.2" frame-mid.png - 检查保真度——逐步揭示按顺序呈现(节点 → 边 → 标签,每一步都出现在对应帧中),连接线指向正确的节点,计数动画停在准确的数值;并检查瑕疵(标签被裁切、节点超出画布、字体加载前出现 FOUC、衔接处卡顿)。
完成前:
- 可在浏览器中独立打开——没有控制台错误,也没有缺失的 CDN 资源。
- 只有一个驱动器 / 主时间轴;冻结操作(
?t=N/setCurrentTime)能得到确定的静止画面。 - 已对起始 / 中间 / 结束画面截图——揭示顺序正确,连接线落在正确的节点上,数字准确。
prefers-reduced-motion会显示最终组合图表,不会循环播放动画。- 色彩规则一致;突出显示活动元素,弱化上下文;不会一次性全部呈现。
参考文件
references/diagram-and-chart-recipes.md— 更完整的可运行代码:分阶段揭示节点 / 边和标签、流动虚线与移动圆点连接线、柱状图 / 折线图 / 数值递增图表示例、时序图和架构图构建模式,以及附有缓动说明的 D3 / Framer Motion / Remotion 实现。