HTML 代码绘画(html-code-painting)
目标
用代码在浏览器中"画出"一幅高度接近参照对象(原图或文字描述)的画作,输出一个自包含的
.html 文件。"高度还原"不靠运气,靠流程:先观察分析、再结构规划、然后分层绘制、
最后对比校验迭代。跳过分析直接动手是失败的首要原因。
技术选型决策树
收到绘画需求后,按下表选定主技术路线(可组合,但每幅画必须有一个主导技术):
| 场景 | 主技术 | 理由 |
|---|---|---|
| 名画临摹、写实/半写实插画、需要复杂质感(云雾、水面、绒毛、光晕) | SVG + 滤镜 | 路径精确可控,feTurbulence 可程序化生成纸纹/雾气/大理石纹理 |
| 平面插画、扁平风、卡通、图标式场景、UI 插图 | SVG 纯矢量 | 干净利落、缩放无损、代码量小 |
| 有机形态密集重复的元素(松针林、稻浪、星野、雨丝、颗粒、波光)、粒子系统 | Canvas 2D 程序化生成 | 几千个元素用循环生成,比手写路径快 100 倍且更自然 |
| 像素风 | Canvas image-rendering: pixelated |
天然契合 |
| 大面积背景氛围(天空渐变、暮色、水色) | CSS 渐变打底 + 上层绘画 | 省代码 |
硬性规则:
- 输出单个自包含 HTML 文件,内联所有 CSS/JS,不引用外部资源;若需参考原图供对比, 将原图以 base64 内嵌到专门的对比工作台页(见下方"校验模板"),不要污染作品本体。
- 深思熟虑后再写码:先在脑中/注释里列出构图分层清单(天空→远山→中景→近景→点睛细节), 再逐层实现。绝不把整幅画塞进一个函数。
工作流程(严格按顺序执行)
第 1 步:获取与分析参照
- 有原图:若有本地图,用
scripts/analyze_reference.py取九宫格主色、暗部/亮部均值与 饱和度分布(用法见脚本头部注释);无脚本环境时目视完成下述同款分析。 - 无原图(凭描述画):先在回复里写出 3–6 行"视觉设定"(主体、视角/构图、光源方向、 主色调与配色比例 60-30-10、时代/地域风格关键词),这相当于创作前的定稿草图。
- 无论哪种,都必须产出分析卡(写在作品 HTML 顶部注释里):
构图:三分法/对称/S形动线,视点落位于画面约 (x%, y%)
分层:<layer1 天空> <layer2 远山> <layer3 水面> <layer4 舟与人> <layer5 前景树>
色彩:<主色 #hex ~占60%> <辅色 #hex ~30%> <点缀 #hex ~10%>
光影:光源方向 __,最亮点 __,最暗部 __,整体明度基调 __
质感笔触:______(如:干擦皴 / 湿润晕染 / 厚涂刀触 / 平涂勾线)
第 2 步:网格定位(写实/临摹的关键)
把画布假想为 4×4 或 5×5 的网格,为每个关键对象记录"网格坐标 + 占格数",例如
"孤舟位于 G4 (x:75%, y:62%),长约画布宽 8%"。SVG 里可直接套一层透明 <pattern> 网格辅助
层调试,交付前删除。人物/动物遵循比例法则:站立人高 ≈ 7–7.5 头身,山水画中山与前景植物
遵循"丈山尺树寸马分人"。非正方画布需先确定宽高比(名画常为 3:2、4:3 或手卷 10:1 以上)。
第 3 步:技术分工与分层骨架
- 大形状/构图 → SVG path(贝塞尔曲线圆滑处用 S/T 镜像命令保证连续)。
- 密集自然纹理 → Canvas 循环 + 随机扰动(随机数必须带 seed,保证可复现)。
- 用
<g layer-name transform>组织图层;重叠区域考虑混合模式 (水面倒影mix-blend-mode: soft-light,云雾screen,阴影multiply)。 - 先铺大色块校对整体色调 → 再加中层形体 → 最后做 15 分钟的"细节 pass" (飞鸟、窗棂、芦苇尖上的鸟、屋瓦高光),细节密度决定还原度的上限。
第 4 步:风格配方
确定目标属于哪个画种后,必读对应风格手册 references/style-playbooks.md
(涵盖水墨/青绿山水、印象派油画、浮世绘、塞尔达式低多边形风景、像素风、扁平插画、
夜景霓虹、水彩),其中含调色板、笔触技法与滤镜参数起手值。
通用美术规律速记:大气透视=远景降低对比+混入天色;暖进冷退;
投影永远带一点点环境反光的补色;边缘有虚有实——视觉中心实、四周虚。
第 5 步:技术手册查阅时机
遇到以下情况时读取对应 references 文件(其余时间不必加载,控制上下文):
- 需要"看起来像手绘/介质质感"→ 读
references/svg-techniques.md的滤镜配方章节 (feTurbulence 各基频/八度实际效果对照、纸张纹理、湿边水彩、油画厚涂做法)。 - 需要 Canvas 程序化元素(森林/星空/水面波光/雨雪/粒子)→ 读
references/canvas-techniques.md。 - 分析方法不确定(如何拆解一张陌生的画)→ 读
references/analysis-workflow.md。
第 6 步:对比校验与迭代(不可省略)
- 写完后自查五问:色调一致?构图网格对位?明度大关系对(眯眼测试:模糊看是否同一节奏)? 细节密度分布合理?有没有一层不变的"平"?——逐项修正后才算第一版完成。
- 若用户提供了原图,把作品拷入
assets/artwork-studio.html对比工作台,base64 嵌入原图, 自查:滑块切换比对 → 记录 3 个最大偏差 → 回改代码 → 重复至偏差可接受。 - 沙盒无浏览器时的视觉自查(无 Chromium / playwright 下载卡死 >2 分钟即走此路):
用 Python(Pillow+numpy)把作品 HTML 的 Canvas 绘制逻辑逐笔复刻成 PNG 预览图再评估。
必读
references/python-preview.md(随机数精确复刻、rand 消耗顺序、Canvas→PIL/numpy 映射表、"真实问题 vs 复刻局限"甄别口诀);模板脚本scripts/preview_canvas.py已内置 mulberry32 精确复刻、渐变/圆头笔触/图层模糊合成工具,直接翻译各图层即可跑通。 - 向用户交付时展示作品文件本体(对比台只在需要精修时给用户看)。
常见失败模式(务必规避)
- 只铺渐变没有内容——天空不是一块 linear-gradient,要有云的形、色彩分段、晕染边界。
- 随机数无 seed——刷新就变样,无法迭代修复。统一
rand = mulberry32(seed)类固定种子发生器。 - 过度饱和——屏幕色彩天然艳于颜料,整体降 10–20% 饱和、拉开明度层次反而更像真画。
- 透视打架——同一画面只允许一个消失点体系;散点透视(国画)则遵守"高远/深远/平远"三远法。
- 滤镜叠加失控——多个 feTurbulence 叠加时性能急剧下降,一画布上存活的高开销滤镜 ≤2 个。
- 细节平均主义——四角和中心的精细度应不同,视觉中心多花 50% 以上的元素数量。
与其他表达形式的边界
用户要的是"AI 生成位图照片感图像"时改用 ImageGen 工具,不属于本技能范围; 但用户要"可缩放、可交互、代码即作品本身、离线可开"的画面时,本技能是正确选择。
Resources
scripts/
analyze_reference.py— 输入本地图片,输出九宫格平均色、暗/亮部代表色、宽高比建议。 用法:python analyze_reference.py <image> [--grid 4]。preview_canvas.py— 无浏览器环境的 Canvas 渲染管线 Python 复刻模板(mulberry32 精确复刻- 渐变/圆头笔触/图层合成工具 + 诊断图输出)。用法见
references/python-preview.md。
- 渐变/圆头笔触/图层合成工具 + 诊断图输出)。用法见
references/
analysis-workflow.md— 观察方法论:如何系统地拆解任一幅画的构图/色彩/光影/笔触。svg-techniques.md— SVG 滤镜质感配方库(纸纹、水彩晕染、油画肌理、雾气、辉光、腐蚀边缘)与性能红线。canvas-techniques.md— 程序化生成模式库:森林、星空银河、水面波光、山脊叠嶂、雨雪粒子,附可直接套用的循环骨架。style-playbooks.md— 八大画种风格手册:调色板 + 笔触 + 结构特征 + 完成判定标准。python-preview.md— 无浏览器环境视觉自查手册:Python(Pillow+numpy) 复刻 Canvas 渲染 管线做 PNG 预览。含 mulberry32 精确复刻、rand 消耗顺序规则、Canvas→PIL/numpy API 映射表、 诊断图组合与"真实问题 vs 复刻局限"甄别口诀、8 条实战踩坑清单。
assets/
artwork-studio.html— 对比校验工作台模板(并排/滑动/洋葱皮三种比对模式)。精修还原度时使用。
