产品场景图生成器 · v2 / v3
给一个「标题」,产出一张 1760×1120 的场景图。风格已定型,不要重新设计,只需要选版式 + 填内容。
两套取向,先选一个:
| v2 · 卡片 | v3 · 图形化 | |
|---|---|---|
| 主体 | 圆角矩形节点 + 短标签 | 大图标 / 圆形节点 / 图形装置 |
| 内容区 | 有整块白色 content 卡 | 没有,图形直接浮在淡蓝面板上 |
| 文字量 | 5–7 处 2–4 字 | 3–4 处 2–3 字 |
| 适合 | 需要逐条并列讲清 5–6 个概念 | 要点少、希望图形自己说话 |
| 模板 | template-b/c-* | template-d/e-* |
默认走 v3——这类图最终往往缩到 240px 宽,图形比文字扛得住缩放。只有当信息本身是"5 条并列、每条都要读字"时,才退回 v2。
为什么用 HTML/CSS 渲染而不是 AI 生图:这套图有精确文字与 1px 描边。扩散模型会把文字画糊、把描边画抖,且同样提示词每次结果都不同。HTML 渲染 → 截图,文字永远清晰、随时可改、可批量、可复现。
为什么结构必须简单:这些图最终的观看尺寸往往是 240px 宽(网页卡片),不是 1760。在 1/7 缩放下,"六节点 + 微缩图表 + 细骨架条"会全部糊成灰色噪点。v2 的硬指标是:缩到 240px,标题和每个标签的大意还能读出来。
缩放标尺(先记住这张表)
| 观看宽度 | 缩放 | 48px 文字实际显示 | 结论 |
|---|---|---|---|
| 1760(PPT 全屏) | 1:1 | 48px | 偏大但可接受 |
| 480(网页大图) | 1/3.7 | 13px | 舒服 |
| 240(网页卡片) | 1/7.3 | 6.6px | 设计验收尺寸 |
| 190(列表缩略) | 1/9.3 | 5.2px | 已到极限 |
所以:任何小于 40px 的文字都不该出现,任何小于 300px 宽的元素都撑不住细节。
铁律(违反任意一条,出来就不像)
- 画布 1760×1120(11:7)、纯白底,无渐变无暗角无边框。
- 外壳 + 面板两层坐标写死不要改,这是唯一的"深度"来源。第三层内容白卡只属于 v2;v3 不铺它,图形直接落在面板上。
- 全图有且仅有 1 个渐变图标瓦片,170–200px 见方,它是视觉主体。
- 内容区元素总数 ≤ 7(连线、手柄不计)。超过 7 个,缩略后必然变噪点。
- 文字:标题 76px、标签 48–50px、浮标 44px。不存在 20px 的字。
- 色相锁死 200°–250°。唯一暖色
#F58A8A只能用于"告警"。 - 无人物、无透视、无 3D、无照片、无环境背景。所有矩形严格轴对齐。
- 只输出 1760×1120 一个尺寸,不要再导出 660×420 之类的缩略衍生图。
- 所有文字必须是真实文字(HTML 文本),不能是图片或路径。
- 每根连线两端都必须落在元素边缘或另一根线上。交付前
render.py的连线检查必须通过(退出码 0)。
固定几何(照抄,不要改)
| 层 | 元素 | left | top | w | h | r |
|---|---|---|---|---|---|---|
| L0 | canvas | 0 | 0 | 1760 | 1120 | – |
| L1 | shell 外壳白卡 | 110 | 66 | 1520 | 968 | 62 |
| L2 | panel 淡蓝面板 | 140 | 96 | 1460 | 908 | 50 |
| L3 | content 内容白卡 | 180 | 240 | 1310 | 644 | 40 |
| L4 | badge 浮标 | 1312 | 自定 | 320 | 128 | 32 |
| – | title 标题 | 190 | 132 | – | – | 76px / 600 |
推导出来的边界(摆内容时用来对齐):
- 面板右缘 1600、下缘 1004;内容卡右缘 1490、下缘 884。
- 内容卡底边到面板底边留 120px 蓝带(
1004 − 884)。 - 浮标右缘 1632,越过面板 32px —— 这就是"破框",不要把它塞回卡片里。
- 内容区可用宽度 = 180→1490,减去左右各 60 内边距 = 1190,元素须装在 240–1430 之间。
- 浮标占据 1312 以后的空间,内容元素右缘不要超过 1230,否则会被压住。
面板渐变(必须止于 #F5FAFF,不能更淡):
background:linear-gradient(180deg,#E4F1FF 0%,#E9F4FF 34%,#F2F9FF 74%,#F5FAFF 100%);
元素尺寸下限(v2)
| 元素 | 尺寸 | 说明 |
|---|---|---|
| 渐变瓦片 | 170–200 见方 | 占宽 10–11%,全图最大的一块颜色 |
| 宽层条 | 910×152 | 一整层用一条,放"图标 + 层名" |
| 常规节点 | 330×132 | 一行三个,间距 35 |
| 输出小卡 | 360×120 | 一行三个,间距 40 |
| 浮标 | 320×128 | 图标 46 + 44px 文字 |
| 图标 | 50–54 | stroke-width 2.2,太细会被缩没 |
| 连线 | 4px | dasharray 12 10,箭头用等腰三角 |
| 选中手柄 | 20×20 | border 3px,中心对准节点角点 |
工作流
Step 1 · 长标题 → 短标题 + 浮标
- 取功能名,压到 4–6 个汉字:「技术文档与知识库可视化-…」→「文档配图生成」。
- 浮标文案 4 个字(320px 只放得下 4 个 44px 的字),要写"承诺":「一键插入」「仅改此块」「布局不变」「局部可改」。
- 例句写真实的一句话,不要写「示例文本」。
Step 2 · 选版式
| 标题特征 | 版式 | 模板 |
|---|---|---|
| 一个核心 → 多类产出、能力辐射、一中枢 N 场景 | D 核心分支(v3) | assets/template-d-orbit.html |
| A→B→C 三步、上传→解析→入库、构建→测试→发布 | E 圆形流水线(v3) | assets/template-e-pipeline.html |
| 输入→生成→多路产出、转换、整理(要文字标签才说得清) | B 上→下分叉(v2) | assets/template-b-flow.html |
| 既讲"一句话生成"又讲"生成后能改"(要界面感) | C-1 画布编辑态(v2) | assets/template-c-ui.html |
| 分层架构(接入 / 服务 / 数据)逐层讲 | C-2 分层选中态(v2) | assets/template-c-arch.html |
细节见 references/layouts.md。拿不准:要点 ≤ 4 个走 D 或 E;信息必须逐条排开才走 C-2(它缩略最清楚)。
Step 3 · 改模板
复制一份模板,只改这几处,壳层 CSS 一行都不要动:
.title文字;- 每条/每个节点/每张卡片里的短标签(2–4 字);
- 浮标
.badge的文字(4 字)+top(两个浮标纵向间距 ≥40px); - 输入条 / 气泡里的例句;
- 删元素时同步删掉它的连线与箭头,否则留下悬空线头;
- 改连线时必须按后文「连线怎么画才不会断」的「枢纽 + 独立段」写法,不要顺手加转弯。
Step 4 · 渲染
python <SKILL_DIR>/scripts/render.py <input.html> <output.png>
<SKILL_DIR> 是本 skill 的安装目录(SKILL.md 所在处),不是当前工作目录——
你的 cwd 通常是用户的项目,直接写 scripts/render.py 会找不到文件。
脚本把 HTML 复制到 ASCII 临时目录再调 headless 浏览器——中文路径会让 headless 静默失败、输出空白或旧图。它还会校验输出是不是 1760×1120,并自动检查每根连线的端点有没有悬空——退出码 3 表示有断线,不要交付。
Step 5 · 缩略自检(最重要的一步)
python <SKILL_DIR>/scripts/preview.py <output.png> --width 240
必须真的看一眼缩略图,按 references/checklist.md 核对。判断标准只有一句:
缩到 240px,还能读出标题、每个标签的大意、以及"哪一块是重点"吗?
做不到就减元素、放大字号,不要靠加细节解决。
v3 · 图形化(图标与图形元素驱动)
一句话:能画出来的,不要写出来。
v2 的每个元素都是「圆角矩形 + 图标 + 文字」,彼此同构,所以整图读起来像一堆流程块。 v3 只换三件事——去掉内容白卡、把图标放大三倍、让图形自己承担语义。
三条硬规则
- 不铺 content 白卡。图形直接浮在淡蓝面板上;白底只给徽章、浮标这类小件。边界靠阴影,不靠描边。
- 图标 ≥ 84px。视觉线宽 =
stroke × 显示尺寸 / 24,目标 7–9px(缩到 240px 时约 1px)。 - 标签 ≤ 4 处,每处 2–3 字。超过 4 处,说明你还在用文字讲事情——回去把那条信息画成图形。
图标库(50 枚)
assets/icons.svg 是 sprite。把整段内容内联到页面里才能用:
<body>
<!-- 把 assets/icons.svg 的全部内容粘在这里 -->
<svg><use href="#i-database"/></svg>
</body>
外部引用(<use href="icons.svg#i-database"/>)在 file:// 下会被浏览器按跨域拦掉,
headless 截图里图标会整片消失且不报错。
python <SKILL_DIR>/scripts/iconlib.py --list # 按分组列出全部 id
python <SKILL_DIR>/scripts/iconlib.py --preview p.png # 生成图标墙,挑图标用
分组:图表 / 图示 12 枚 · 技术元素 15 枚 · AI 与内容 18 枚 · 交互 5 枚。
symbol 内不写 stroke-width,按显示尺寸配:
| 显示尺寸 | stroke |
|---|---|
| 84–108 | 1.9–2.0 |
| 130–140 | 1.5 |
| 170–190 | 1.3 |
找不到合适的就换一枚近似的,不要临时手画新形状——线条风格一不统一,整图立刻露馅。
元素零件(15 件)
assets/parts.html 是一页零件墙,每件都有实物 + class 名 + 尺寸,直接抄 HTML + CSS:
渐变瓦片 · 白圆徽章 · 破框浮标 · 标签胶囊 · 窗口框 · 层堆叠 · 渐变箭头 · 虚线连接 · 选中手柄 · 指令气泡 · 环形进度 · 微柱图 · 点阵底纹 · 星芒 · 选中瓦片。
两套版式
- D 核心分支 → 一个核心 → 多类产出。中心是「三张错位叠页 + 星芒」,不是单个图标。
- E 圆形流水线 → A→B→C 三步。中间那块是唯一渐变体,也是读者第一落点。
两者都由上面这些零件拼成,改图只需换图标、换 2–3 字标签。
v2 版式的骨架
B 上→下分叉(template-b-flow.html)
输入胶囊 690×136 居中 → 竖线 → 渐变瓦片 200 → 竖线到总线 → 横总线分三路 → 三张输出卡 360×120。浮标放右上。
C-1 画布编辑态(template-c-ui.html)
左上瓦片 170 + 输入条 850×118 → 浅蓝画布底板 1160×352,内含三个节点 330×132,中间节点选中 → 下方指令气泡 430×112,用 4px 虚线连到选中节点。浮标放右上。
C-2 分层选中态(template-c-arch.html)
三条 910×152 层条竖排(间距 40,整组垂直居中),中间一条选中并带一个 104px 渐变小瓦片 → 右侧两个浮标。信息量最小、缩略可读性最好。
v2 元素零件(6 个,够用了)
- 渐变图标瓦片 —
170–200 / r44–52 / linear-gradient(135deg,#4A9DFC,#5E92F9 45%,#7C6BF5)+ 白色线性图标(84–100px, stroke-width 1.6)+ 下缘柔光0 18 40 rgba(74,157,252,.42), 0 0 40 8 rgba(124,107,245,.14)。 - 浮标 — 白底
320×128 / r32+0 20 48 rgba(31,71,141,.16)+ 46px 蓝图标 + 44px 文字。 - 层条 / 节点 — 白底 +
3px #C9DCF2描边 + 90px 淡蓝圆角图标块 +50px/500标签。不要放骨架条,直接写真文字。 - 选中态 —
5px #4A9DFC+0 0 0 12px rgba(74,157,252,.11)+ 四角 20px 手柄(中心对准角点)+ 可选内嵌渐变小瓦片。不要画虚线选择框(会被连线穿过)。 - 连线 —
4px / #A9C7EC / dasharray 12 10,箭头是等腰三角M827 716 h16 l-8 14 z。不能用直角三角形。 - 画布底板 —
#F8FBFF / 2px #DDEBFB / r36,把"节点 + 气泡"收成一组,避免画面散。
连线怎么画才不会断
连线是全图唯一需要手写绝对坐标的部分,也是最容易出事的地方。一段线少写 几百像素,整张图看着依然"像那么回事"——1760 原图上不放大看不出来,缩到 240px 更是完全看不见,直到图已经交出去才被人指出。
分叉必须拆成「枢纽 + 独立段」
错误——一条 path 中途转弯又分支,总线只覆盖到最左支线:
<path d="M835 652 V690 H435 V716"/> <!-- 竖 → 左横 → 竖,就断在这 -->
<path d="M835 690 V716"/>
<path d="M1235 690 V716"/> <!-- 起点悬在空白里 -->
正确——所有交点在端点级重合:
<path d="M835 652 V690"/> <!-- 竖线落到枢纽 (835,690) -->
<path d="M835 690 H435"/> <!-- 左半总线 -->
<path d="M835 690 H1235"/> <!-- 右半总线 -->
<path d="M435 690 V716"/> <!-- 三条支线,起点 y 都等于总线 y -->
<path d="M835 690 V716"/>
<path d="M1235 690 V716"/>
三条规则:
- 一条 path 只做一件事:要么直下,要么横穿。不在中途转弯后再分支。
- 总线两端必须等于最左、最右支线的 x,这三个数字要在代码里字面相同。改一侧,另一侧跟着改。
- 支线终点 y = 卡片 top − 14(14 是箭头高度),支线起点 y = 总线 y。
每次渲染都会自动检查
render.py 渲染完会自动调 linklint.py:让浏览器算出每条线的真实端点,
逐个判断它贴着某个元素边缘(≤8px)还是与另一条线相交(≤3px)。
不满足就是悬空,直接打印坐标:
[x] 发现 1 个悬空端点:
第6条线 起点 在 (1235,690),最近的物体还差 40px d="M1235 690 V716"
此时退出码为 3,不要交付。也可以单独检查:
python <SKILL_DIR>/scripts/linklint.py scene.html -v
箭头三角、关系菱形这类填充图形不参与检查(它们的底边本来就贴在线端点上), 但它们会被当作可连接目标——所以线接到箭头上是合法的。
这个检查只认几何,不认"看着差不多"。它抓到过一个真实事故: 三叉分叉的右支线整整少了一段 800px 的横线,而整张图肉眼完全正常。
常见错误(都是实际踩过的)
| 现象 | 原因 | 修法 |
|---|---|---|
| 缩到 240px 后糊成一片灰 | 元素太小、太多 | 元素减到 ≤7 个,字号抬到 48px,描边加粗到 3–5px |
| 骨架条缩略后像灰色噪点 | 用了装饰性骨架条 | 换成真实短标签(2–4 字) |
| 底部出现白带,面板像只有边框 | 渐变淡到 #FBFCFE | 止于 #F5FAFF |
| 浮标压住内容 | 内容元素越过了 1230 | 内容右缘控制在 1230 以内 |
| 手柄浮在角外 | 手写 top 未减半 | handle.left = 角点 x − 10,top = 角点 y − 10 |
| 虚线看不见 | 被选中节点的光晕盖住 | 给连线所在的 svg 加 z-index:6 |
| 箭头歪、像直角三角形 | 路径写错 | 用等腰三角,见零件 5 |
| 横总线压着卡片 | 分叉点太低 | 瓦片底→总线 ≥38px,总线→卡片 ≥40px |
| 三个卡片间距不等 | 手写 left | 等距排列并核对中心点是否对准箭头 |
| 渲染出来空白/旧图 | HTML 在中文路径下 | 用 scripts/render.py |
| 三张图疏密不一致 | 元素尺寸各写各的 | 全部按「元素尺寸下限」表取值 |
| 连线断在半路、支线悬空 | 一条 path 转弯后只覆盖到部分支线 | 拆成「枢纽 + 独立段」,见「连线怎么画才不会断」 |
| 气泡虚线离节点有一条缝 | 起点没落在元素边缘 | 起点 y = 元素 bottom,让 linklint 验到 0px |
文件索引
本 skill 自包含:下面的路径都相对于 SKILL.md 所在目录,不需要访问其他仓库或外部文档。
SKILL.md
├── references/
│ ├── style-tokens.md 色值、字号、圆角、投影的完整 token 表(含 v3 图形化 token)
│ ├── layouts.md 五种版式的骨架图、适用场景、元素配方
│ └── checklist.md 交付前逐条核对(含 240px 缩略验收、v3 专用项)
├── assets/
│ ├── icons.svg 50 枚线性图标 sprite(内联进页面后 <use href="#i-xxx"/>)
│ ├── parts.html 15 件图形零件墙,可看也可抄
│ ├── template-d-orbit.html D 核心分支(v3)
│ ├── template-e-pipeline.html E 圆形流水线(v3)
│ ├── _blank-shell.html 只有壳层,从零搭版式时用
│ ├── template-b-flow.html B 上→下分叉(v2)
│ ├── template-c-ui.html C-1 画布编辑态(v2)
│ └── template-c-arch.html C-2 分层选中态(v2)
├── scripts/
│ ├── render.py HTML → 1760×1120 PNG(路径处理 + 浏览器探测 + 连线检查)
│ ├── linklint.py 检查每根连线的端点是否悬空(render.py 会自动调用)
│ ├── preview.py 生成 240px 缩略图,用于"缩略自检"
│ └── iconlib.py 列图标 id / 生成图标墙
└── examples/ 5 张成品图 + 可渲染源文件,仅供参照,不参与生成
模板里的文字和图形都是可运行的真实例子,直接照着改比从空白页写更快。