| name | claude-algo-visualize |
| description | 生成单文件的交互式数据结构/算法可视化 HTML 教学页面。适用场景:用户提供 PDF/教材要求生成知识点讲解、给出主题要求做动画演示(如"演示快排"、"做个队列动画")、提供代码或算法要求可视化执行过程、要求对比两个概念或解释原理。即使用户没有明确说"HTML"或"可视化",只要涉及"知识点总结"、"教学页面"、"动画演示"、"算法执行过程"、"PDF 讲解"、"SVG 图示"、"逐步执行"等场景也应触发。 |
交互式可视化页面生成技能
当用户要求生成网页、可视化、动画演示、知识点总结、教学页面、代码执行动画时,加载此技能。
完整参考实现:references/heap_overview.html(428 行的"堆"全景讲解页面)。它是对照本 skill 所有约定(CSS 骨架、叙事密度、大小顶堆并排 SVG、Push/Pop/建堆/堆排序双面板联动动画)写出的完整样板。遇到"PDF → 讲解页面"类型任务时,建议先用 Read 工具浏览这个参考文件作为对齐基准;其他类型也可以参考它的叙事节奏和 SVG 写法。
定位
生成完整的交互式 HTML 页面(单文件)。页面风格是"说人话的教学梳理"——有逻辑流、有叙事感、有图示、有交互。
适用场景包括但不限于:
- 用户提供 PDF/教材,要求生成知识点讲解页面
- 用户提供一个主题(如"队列的操作"),要求生成教学 + 动画页面
- 用户提供代码/算法,要求生成逐步执行动画
- 用户要求对比两个概念、演示某个过程、解释某个原理
铁律(违反任何一条 = 质量不合格)
铁律一:正文为主,彩色框为辅
页面内容的 80%+ 应该是 <p> 段落和 <h2>/<h3> 标题。彩色 callout 框(.info、.warn、.ok、.def、.formula)只是偶尔穿插的旁白,整页加起来不超过 3-4 个。
参考 references/heap_overview.html(428 行,7 个章节):0 个 .def,0 个 .formula,总共只有 5 个 .info + 2 个 .ok + 4 个 .warn。定义、公式、性质全部用 <p> + <b> 写在正文里。
反面教材:连续出现 3 个以上 .def 框,或者把公式放进 .formula 框——这些会让页面变成一堆彩色方块的堆砌,不像教学页面。
铁律二:SVG 节点绝对不能重叠 + viewBox 必须留够空间
写 SVG 时(无论静态图还是 JS 动画),必须确保:
- 每个圆形节点的半径(通常 r=22~24)加上文字不会和相邻节点重叠
- 手算坐标时,相邻节点圆心距 ≥ 56px(2 × 半径 + 间隙)
- 父子节点之间的 y 轴间距 ≥ 60px(给连线和文字留空间)
- 如果空间不够,宁可增大
viewBox 的高度,也不能压缩节点间距
- 写完坐标后,在脑中画图验证:每个 (cx, cy) 周围 24px 半径内不能有其他圆心
viewBox 安全边距:viewBox 的宽高必须比所有内容的边界多出至少 20px。具体检查方法:
- 找出所有节点中最大的
(y + r) 值,再加上所有节点下方标注文字的高度(约 20px),viewBox 高度必须 ≥ 此值 + 10px
- 如果节点下方有
<text> 标注(如编码、层号),viewBox 底部还要再留 10px
- 经验公式:viewBox 高度 = max(节点 y + r) + 40
铁律三:动画必须与代码联动
当页面涉及代码执行过程时,交互动画必须与代码展示联动。不能出现"动画是动画,代码是代码"的割裂情况。
具体要求:
- 动画的每个 step 必须标注当前正在执行代码的第几行
- 代码展示区用
.code-panel 容器包裹,每行代码用 <div class="cl"> 包裹,当前执行行加 .cl.on 高亮
- 代码面板放在动画可视化区域的上方或左侧,形成"代码 + 可视化"的双面板布局
- 说明文字(
.cap)应同时解释代码在做什么和数据结构如何变化
- 如果代码太长(超过 12 行),只展示与当前动画相关的核心片段,其余用
// ... 省略
铁律四:每个概念/步骤必须配 SVG 图示
页面中讲到任何可视化概念时,必须有对应的 SVG 图:
- 数据结构(树、图、队列、栈等)→ 画结构图
- 操作过程(插入、删除、排序步骤等)→ 画状态图或做动画
- 对比/比较 → 并排 SVG
- 算法执行 → 步骤动画
具体要求:
- 概念讲完 → 紧跟 SVG 图示 → 再接文字说明,这个节奏不能断
- 静态 SVG 用内联 HTML 写(不需要 JS),颜色用 CSS 变量
- 交互式动画只用来演示"多步骤过程"(如算法执行、构造过程),静态图用来展示"单个状态/概念"
- 整页的静态 SVG 数量应该 ≥ 交互式动画的数量
反面教材:一个概念讲解章节只有文字没有图——读者看着纯文字根本无法理解。
铁律五:有来源时跟着来源的教学脉络走,顺着来源的页面顺序梳理章节——它先讲什么就先写什么章节,它用什么例子就用什么例子。不要从结论倒推,不要"提炼要点后重新组织"。
如果没有提供来源(纯主题/算法请求),则按自然教学顺序组织:
- 先讲"这是什么"(定义/背景)
- 再讲"怎么工作"(原理/步骤,配图)
- 然后讲"实际例子"(手动模拟,配动画)
- 最后总结(核心要点、易错点)
输入类型与工作流
类型 A:PDF / 教材 → 知识点讲解页面
- 读入 PDF,顺着 PDF 的页面顺序梳理章节
- PDF 从哪个概念开始讲 → 第一个章节;接着讲什么 → 第二个章节
- 有哪些图/例子 → 对应嵌入到相关章节
- 最后有"知识回顾"/"考点" → 最后的总结章节
- 章节编号用
<h2 id="sN">,页面开头用 .toc 列出目录
类型 B:主题描述 → 教学 + 可视化页面
用户说"给我做个队列的动画"或"解释一下快排"之类。
- 根据主题规划章节(按自然教学顺序)
- 每个关键概念配静态 SVG
- 核心操作配交互式动画(如:入队/出队、分区过程)
- 如果涉及代码,用
<pre> 展示,配合逐步执行动画
类型 C:代码 / 算法 → 逐步执行动画
用户给了一段代码或指定一个算法,要求可视化执行过程。
- 先用
<pre> 展示完整代码
- 设计 steps 数组,每一步反映数据的完整状态
- 每步只做一件事(比较/交换/移动)
- 配文字说明当前行在做什么
- 用数组视图(
.aw/.ar/.ac)或树视图(SVG)展示
类型 D:概念对比 / 原理解释
用户要求对比两个概念或解释某个原理。
- 用
.compare 并排展示
- 每个概念配 SVG 图示
- 共同点和差异用
<p> + <b> 说明
- 如有流程差异,配动画对比
套用模板(assets/)
assets/ 目录下有三个必用文件,它们是页面的"骨骼"。生成页面时用 Read 工具把对应文件读出来后原样嵌入,不要 paraphrase 重写——paraphrase 会丢失 CSS 变量名、类名和模板字符串结构,导致样式和动画出问题。
assets/base.css — CSS 骨架
包含颜色变量(含深色模式)、基础排版、所有 callout / compare / 动画容器 / 数组单元格 / 代码面板样式。
用法:读入后原样放入 <style> 标签,不做修改。如果需要调整字号或间距,在骨架后追加覆盖规则,不要改骨架本身——骨架改动会影响参考实现的视觉一致性。
assets/boilerplate.js — JavaScript 工具 + 渲染模板
内含六块内容,按需选取:
| 块 | 何时嵌入 |
|---|
工具函数(treePos / mkDots / D) | 所有动画场景必嵌 |
hlLines 代码高亮助手 | 当动画联动代码时嵌入(铁律三) |
| 模板 A:数组 + 完全二叉树 | 堆、堆排序——任何"数组 + 完全二叉树双视角"的演示 |
| 模板 B:自定义坐标树 | 哈夫曼森林合并、BST、图等需要手算坐标的场景(务必遵守铁律二) |
| 模板 C:纯数组 | 简单排序、队列、栈——没有树形结构时 |
| 键盘导航 | 所有动画页面都应加 |
只摘取对应模板块嵌入 <script>(按文件里的注释分割线取一段),不要把整文件复制进去——模板 A 和 C 都声明了顶层 var steps / function render / function go,两块一起嵌入会重复声明报错。正确的嵌入顺序:工具函数块 → 选定的渲染模板块 →(如需)hlLines 块 → 键盘导航块 → 你自己的 steps 数据。
使用模板 A 之前注意看文件里的注释:必须自行定义 clsFn(i)(决定数组单元格的高亮类),否则会抛错。模板 B 只提供 renderStep() 纯函数,需要自己写一小段 cur + go(d) + 初始化的驱动层(文件里有示例)。
assets/animation-html.html — 三种动画 HTML 骨架
| 骨架 | 对应场景 | 配套 JS |
|---|
| 结构 1:代码面板 + SVG 树 + 数组 | 涉及代码时必须使用(铁律三) | 模板 A + hlLines |
| 结构 2:SVG 树 + 数组 | 纯数据结构演示 | 模板 A 或 B |
| 结构 3:只有数组 | 简单排序 / 队列 / 栈 | 模板 C |
按场景选一个复制到对应章节,把所有 xx-* id 替换为你的实际前缀(如 heap-push-svg、heap-push-arr 等),避免同页多个动画互相冲突。
正文写法
<p> 为主
90% 的内容用 <p> 段落写,不要用彩色框。定义、公式、性质全部放在 <p> 中用 <b> 加粗关键词:
<h2 id="s1">1. 带权路径长度</h2>
<p>先搞清楚三个层层递进的概念。</p>
<p><b>结点的权</b>:有某种现实含义的数值(如:表示结点的重要性、字符出现的频次等)。</p>
<p><b>结点的带权路径长度</b>:从树的根到该结点的路径长度(经过的边数)与该结点上权值的<b>乘积</b>。</p>
注意:
- 没有
.def 框,没有 .formula 框,全是 <p> 段落
- 公式直接写在
<p> 里,不用特殊容器
- 关键术语用
<b> 加粗
彩色 callout 框 — 极其克制地使用
callout 框只在以下情况出现,整页总共不超过 3-4 个:
.info:讲完一个概念后,补充一个容易忽略的要点
.warn:一个极其容易犯的错
.ok:一个章节讲完后的核心结论
不要用 callout 框来写定义、公式、性质——这些是正文内容,用 <p> 写。
静态 SVG 图示
概念讲完后紧跟 SVG 图示。SVG 坐标规划规则:
viewBox 宽度通常 0 0 700 200(宽 700),高度按需调整
- 圆形节点半径 r=22,相邻节点圆心距 ≥ 56px
- 父子层 y 间距 ≥ 60px
- 颜色用 CSS 变量(
var(--gnb) 等),支持深色模式
- viewBox 高度 = max(节点 y + r) + 40(留出标注文字空间)
<svg width="100%" viewBox="0 0 700 200">
<circle cx="175" cy="58" r="22" fill="var(--gnb)" stroke="var(--gn)" stroke-width="1"/>
<text x="175" y="58" text-anchor="middle" dominant-baseline="central" font-size="14" font-weight="500" fill="var(--gn)" font-family="var(--sans)">1</text>
</svg>
表格 — 克制使用
整页最多 1-2 个表格,只在确实适合并列对比时使用。不要用表格来罗列步骤——步骤用 <p> 或编号步骤(.sb)写。
代码展示
用 <pre> 标签展示代码:
<pre>void HeadAdjust(int A[], int k, int len) {
A[0] = A[k];
for (int i = 2*k; i <= len; i *= 2) {
...
}
}</pre>
编号步骤
用 .sb + .sn 展示带编号的步骤:
<div class="sb"><div class="sn">1</div><div class="st">找到变量名:<code>a</code></div></div>
<div class="sb"><div class="sn">2</div><div class="st">往右看:<code>[3]</code> → a 是一个<b>长度为 3 的数组</b></div></div>
概念对比
用 .compare 并排展示两个概念:
<div class="compare">
<div>
<h4>方式 A</h4>
<p>说明...</p>
</div>
<div>
<h4>方式 B</h4>
<p>说明...</p>
</div>
</div>
总结章节
每个页面最后有一个总结章节,用 <p> 回顾核心脉络,最多加一个 .ok 做最终结论。
交互式动画(设计原则)
动画的 JS 模板和 HTML 骨架在 assets/ 里,本节只讲设计层面的约定——颜色语义、每个 step 里放什么数据、怎么选模板。
颜色约定
| CSS 类 | 语义 | 何时使用 |
|---|
hl / 蓝 | 当前关注 | 正在操作的节点 |
sw / 橙 | 交换中 | 两个元素正在交换 |
nw / 绿 | 新元素/成功 | 新插入、比较通过 |
pp / 红 | 问题/删除 | 需要调整、违规 |
ok / 绿 | 已完成 | 已确认满足条件 |
lk / 绿 | 已锁定 | 已排好的末尾 |
dim | 不参与 | 被忽略的元素 |
steps 数据设计
每个动画场景的 steps 是一个数组。每个 step 包含当前完整状态:
数组/堆类动画(完全二叉树 + 数组双视角,搭配模板 A):
{
vals: [...], // 当前数组状态
cap: "...", // 说明文字(支持 <b> <code>)
focus: number, // 当前关注下标(-1=无)
swap: [a, b], // 交换对(null=无)
lk: [...], // 已锁定的下标
hn: number, // 堆大小(当数组比堆大时)
line: number, // 当前高亮代码行号(从 0 开始,-1=无)
}
通用树/图动画(自定义坐标,搭配模板 B):
{
cap: "...",
nodes: [{v:"值", x, y, cf, cs, ct}], // 节点列表 + 颜色
edges: [{x1, y1, x2, y2, l?"0/1"}], // 边列表(可选标签)
arr: [...], // 可选:关联数组状态
ch: [...], // 可选:变化的数组下标
line: number, // 当前高亮代码行号(从 0 开始,-1=无)
}
原则:每步只做一件事(比较 or 交换);状态反映操作后的结果。当涉及代码时,每个 step 必须指定 line 字段,render 函数末尾调用 hlLines('codeId', s.line)。
模板选择速查
- 有完全二叉树 + 数组双视角 → 模板 A(
treePos 自动算坐标)
- 树结构不规则(合并、删除导致形状变化)→ 模板 B(手算坐标,务必遵守铁律二)
- 只有数组 → 模板 C
完整页面结构
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>标题</title>
<style></style>
</head>
<body>
<div class="c">
<h1>标题</h1>
<p class="sub">一句话概括</p>
<div class="toc">...</div>
<h2 id="s1">1. ...</h2>
<p>正文段落为主...</p>
<svg>图示...</svg>
<h2 id="s2">2. ...</h2>
<p>正文...</p>
<div class="w">交互动画(从 assets/animation-html.html 选一个骨架)</div>
<h2 id="sN">N. 总结</h2>
<p>回顾...</p>
</div>
<script></script>
</body>
</html>
常见陷阱
- 缺少图示:讲到可视化概念必须有 SVG 图,概念讲解后紧跟图示,不能只有纯文字
- SVG 节点重叠:相邻圆心距 ≥ 56px,父子 y 间距 ≥ 60px,不够就加大 viewBox
- viewBox 裁切:viewBox 高度 = max(节点 y + r) + 40,务必验证所有 step
- 彩色框泛滥:不要用
.def/.formula 框写定义和公式,用 <p> + <b>。callout 框整页 ≤ 4 个
- 表格泛滥:整页 ≤ 2 个表格,不要用表格罗列步骤
- 脱离来源脉络:有 PDF 时跟着 PDF 的教学顺序走,不要自己重新组织
- SVG 颜色硬编码:SVG 中必须用 CSS 变量
- 公式显示:不引入 LaTeX,用 Unicode 字符(Σ、×、≥、≤、⌊⌋)
- 只有动画没有静态图:静态 SVG 用来解释概念,交互动画用来演示过程,两者都要有
- 动画与代码割裂:涉及代码执行的动画必须用
.code-panel + .cl.on 高亮当前执行行,steps 里必须包含 line 字段。不能出现动画区域和代码区域互不关联的情况
- paraphrase 骨架文件:
assets/base.css 和 assets/boilerplate.js 里的代码不要手改或重写,读出来原样嵌入;需要定制在后面追加覆盖规则
- 忘替换 id 前缀:
assets/animation-html.html 里所有 xx-* id 必须全部替换为实际前缀,同页多个动画用不同前缀隔离
写入策略
由于单个 HTML 文件通常很大(300-600 行),一次性写入容易因网络断流导致全部丢失。必须分阶段写入:
- 先告知用户整体计划:列出页面将包含哪些章节、几个动画、预计总行数,让用户确认方向正确
- 分块写入:先写 HTML 骨架 + CSS(从
assets/base.css 读入)+ 前几个章节的静态内容,确认写入成功后,再用 Edit 追加后续章节和 JS
- 每完成一个阶段,告知用户进度(如"CSS + 前 3 节静态内容已写入,接下来写第 4 节动画和 JS")