Community图像github.com

涂鸦线稿

用代码把任何对象画成有尺寸的钢笔线稿:先完成轮廓,再上排线、点绘和颜色。

涂鸦线稿 是什么?

涂鸦线稿把一个物件、地方或一段镜头,画成纯 HTML 与 JavaScript 渲染的手绘线描。每张图先交一张完整轮廓,再按笔尖类型加上排线、交叉线和点绘,可用透视或轴测。它覆盖产品、人物、动物、植物、建筑、室内、风景和小组分镜,不需要构建步骤。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/vishlbhardwaj/doodle/tree/HEAD

Installed? Explore more 图像 skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

在你喜欢的 AI 中提问

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

文档

涂鸦

一种代码绘制的插画系统。主体通过几何构建,经由相机投影,并由一个带有种子的“手”渲染,使其看起来像是手绘的。纯 HTML + JS,无需构建,无依赖:在浏览器中打开一个页面即可。

设置:你的工作环境

引擎位于本技能的 engine/ 目录中(与本文件同级)。切勿在此处编辑;技能更新会覆盖它。

  1. 如果本文件旁边存在 LOCAL.md,请先阅读它:它指定了本机的工作区和工具,并会覆盖下面的默认值。
  2. 否则,工作区是当前项目中的 ./.doodle(隐藏目录)。如果不存在,请创建它:cp -R "<本技能文件夹>/engine" ./.doodle。
  3. 下面的每个路径(src/…,bin/…)都是相对于工作区的。渲染需要 Chrome 或 Chromium(可设置 CHROME=/路径 覆盖),以及 python3;无需其他东西。

一幅画 = bin/new.sh <名称>,它会创建 drawings/<名称>.js(在 draw(S) 内部绘制,包含完整工具包,自动添加画框)和用于渲染的页面。一幅图中的多个物体算作一幅画;多幅独立的图算作多个名称。

示例是代码,而不是页面。 src/ 中的模块(things.js,people.js,trials.js,scapes.js …)包含已构建好的主体:阅读它们并将它们的构造复制到你的画作中;切勿添加或编辑它们。下面的路由表指明了从哪个模块开始。

交付的是图像,而不是页面。 当一幅画完成后,运行 bin/render.sh <名称>:它会在项目中写入 doodles/<名称>/<名称>.png(彩色)和 <名称>-line.png(仅线条),并为用户打开该文件夹。告知用户文件夹路径。除非用户要求,否则不要构建、打开或指向 HTML 页面、画布或控制面板。

这个文件是整个合约,而且故意写得很短以便完整加载。 详细信息存在于 references/ 中(直接移入,未遗漏任何内容)。下面的路由表说明了要为当前任务阅读哪个参考文件。阅读它是任务的一部分,而非可选:这些文件中的每条规则都是用被拒绝的图画换来的。

每次的流程

  1. 确定“形式”和“类别”(下表)。形式决定了页面、取景和细节预算;类别决定了笔、笔尖、填充和色调。
  2. 路由。 读取路由表为你的主题命名的参考文件,并打开它命名的模块作为起点。如果已有对应的工具包,切勿从空白文件开始一个主题。
  3. 绘制前测量。 如果对照参考图:探测比例和调色板,而非凭记忆。如果没有参考图:将主体的比例作为数字写在模块头部(鞋子需要八个数字;没有它们的三次渲染都失败了)。references/hand-and-craft.md § 测量。
  4. 先构建线条。 在颜色之前用 ?outline=1 判断。每个值都承载两次,一次作为填充,一次作为线条。细节从焦点到中间区域再到纸张逐渐减少。references/line-first.md。
  5. 以最终尺寸渲染并观察,同时观察线条和颜色。 用小样图查看构图,用大单帧查看线条质量。每一轮都要做这两件事。
  6. 如果问题出在辅助函数上,修复工具包,而非主体。 循环直到每个主体都能正确读取。
  7. bin/check.sh drawings/<名称>.html(无参数 = 检查所有画作):它会渲染,确保没有 NaN、控制台错误、类别漂移。
  8. 交付:bin/render.sh <名称> — doodles/<名称>/ 中的 PNG 文件,并打开文件夹。
  9. 在同一个回合中将学到的内容回馈到本技能中(§ 演化)。

路由:要读什么,从哪里开始

主题从何开始阅读什么
首次使用此技能的任何涂鸦无references/line-first.md,references/forms-and-classes.md
日常物品(手机、钥匙、瓶子、布料、眼镜……)src/things.js(最接近的 20 个;cam,S.prism,S.on,S.dash)things.md
产品、设备、小工具、电器src/retro.js (Retro._kit)products.md,geometry.md
圆形物体(杯子、花瓶、水果、瓶子)src/stilllife.js 舞台(lathe,ball)或 src/still.jsstill-life.md,geometry.md(路径构建)
静物 / 布置 / 来自照片src/stilllife.jsstill-life.md
家具src/furniture3.js,src/kitchen.jsproducts.md
日常物品(笔记本电脑、剪刀、眼镜、牙刷、吹风机、T 恤、肥皂、笔记本、挂锁、泰迪熊、衣架、背包、瓶子……)src/things.js def(...)products.md,geometry.md
人物、人群、场景中的任何人src/people.js People.figure;切勿使用 Trials._figure(已废弃)people.md
动物src/trials.js(cat)figures-and-trials.md
玻璃、液体、透明物体src/trials.js(glass)figures-and-trials.md
自行车、框架、任何细管状物体src/trials.js(bicycle),S.limbfigures-and-trials.md
鞋子、服装、布料src/trials.js(sneaker,fruit cloth)figures-and-trials.md
植物、花朵、叶子src/plants3.js,src/flowers.js;带孔叶子:trials.js monsteraplants.md,figures-and-trials.md
建筑、房屋、立面src/houses.js,src/arch.js,src/arch2.jsarchitecture.md,geometry.md
风景、户外景观src/scapes.js(场景工具包)landscapes.md
夜晚、黑暗、天气、雨src/trials.js(night,rain)基于场景工具包figures-and-trials.md,landscapes.md
街道、立体模型、咖啡馆src/cafe.js,src/scenes.jslandscapes.md,geometry.md
房间 / 室内src/kitchen.js,src/deskscene.jsgeometry.md,landscapes.md(保真度)
钢笔和墨水,无颜色src/pen.jsline-first.md(色调),forms-and-classes.md(ink)
故事板 / 序列src/board.jsstoryboards.md
字母、标志src/letter.jspages-and-files.md
屏幕、UI、终端(深色背景上的浅色文字)src/letter.js + 色调着色线条pages-and-files.md(letter.js 条目)
让它动起来(Rive)Rive 导出器(未打包;请查看文件)animation.md
观察其绘制、底图?draw=<key>,?sketch=1hand-and-craft.md
干净 / 矢量 / 非涂鸦风格无如果安装了 clean-illustration 技能
集合、压力测试以现有的集合页面为模板checking.md
必须与渲染对齐的涂鸦(草图 → 最终清除)描摹其轮廓,绘制内部registration.md
哪个页面 / 文件做什么无references/pages-and-files.md

所有 references/ 路径都相对于本技能文件夹。

形式

他们说形式开始的示例细节预算
“给我画一个杯子 / 一把椅子”主体src/things.js,src/retro.js一切,一个物体全保真度
“给我做 N 个”集合每个项目一个 bin/new.sh 画作,共享辅助函数一套工具包,细节存在于工具包中
“一栋房子 / 一个店面”立面src/houses.js,src/arch.js三个开间,55% 纯黑色填充
“一条街道 / 一个景观 / 一个风景”场景src/scapes.js,规定的画框 + 裁剪三层深度阶梯
“整个街区 / 一个小世界”立体模型src/cafe.js街区的边缘保持在画面内
“一个房间”室内src/kitchen.js,src/deskscene.js前景完整,后墙有特征
“把这个做成故事板”画板src/board.js由镜头大小决定,而非主体
“钢笔和墨水 / 无颜色”注册 inksrc/pen.js色调通过线条呈现,完全没有填充

集合不是场景(同一页上的物体除了纸张没有共享任何东西),画板不是集合(相同保真度会丢失序列)。判断标准:物体是否必须共享同一个空间?如果是,那就是场景。

类别(src/spec.js;完整文本在 references/forms-and-classes.md)

类别笔笔尖适配度填充色调
object0.30坚实.84/.84平面,按面法线着色阴影是更深的填充,加上对应的线条
ink0.26钢笔.90/.88无,纸张就是物体仅线条;禁止使用点阵
product0.30坚实.84/.84一种材质 = 一种颜色仅折痕 > ~35°
elevation0.30坚实.86/.8455% 纯黑色窗格屋顶用排线,背光面
plant0.30坚实.84/.88平面;浅色 .96,其他 .84仅用涂鸦表示大片叶子
flower0.26坚实.92/.90平面无
scene0.30坚实.96/.94平面;阴影是更深的填充仅在没有前景物体处用排线
diorama0.22坚实.94/.92平面无
panel0.26坚实.94/.94平面,比单个主体少一些地面一种色调,天空一种
furniture,interior0.16 / 0.15钢笔—旧版权重;新作品使用 object—

声明类别,永远不要重新输入数字: Spec.wrap(cls, label, build)。bin/check.sh 会审计每个页面的漂移。类别控制手部风格;页面控制纸张。仅当填充或色调策略确实不同时才添加类别。

硬性规则(每一条都对应一个被拒绝的图画)

线条优先和保真度

  • 仅线条(?outline=1)必须是一幅完成的画。每个页面都支持 ?outline=1;检查你复制的页面(其中一个硬编码了 outline: false)。
  • 每个值都承载两次:深色材质 = 排线;转折 = 随着表面弯曲的肋条;投影 = 没有轮廓的排线;命名物体的标记 = 有轮廓的标记,永远不要用 w: 0 填充。审计所有的 w: 0。
  • 焦点获得全部细节,中间区域是轮廓加 2-3 条线,背景是纸张(唯一的色调是物体投射的阴影)。眯眼看:如果墙壁和主体一样繁忙,就削减墙壁。
  • 排线作为线条队列(S.hatch),永远不要使用 k.T 色调;后续填充会覆盖它。gap 是值:浅色 2.4,中间 1.5,深色 1.1。仅对焦点中最暗的物体使用交叉排线。
  • 阴影面是由曲线界定的月牙形,曲线随形状弯曲,永远不要是直线的一半平面切割(这会被解读为物体被切成两半)。

几何和路径构建

  • 你未创建的直线是路径错误:将两半以错误方向连接产生的弦,或是未闭合的形状被描边为 closed。打印点坐标。
  • 不透明体上的带状物仅是其近半部分;只有张开的嘴才是完整的椭圆。
  • 孔洞是切割出来的(keyhole),永远不要用背景色绘制。孔洞在线条中可见但在颜色中不可见 = 其环绕方向问题。
  • 薄的东西(肢体、管子、茎)是通过关节的单一带状物;勾勒侧面,让末端插入后续绘制的内容。
  • 容器:内部 → 远侧边沿 → 内容物 → 前壁。内容物沉到边沿下方。
  • 在绘制已知物体前,将比例作为数字测量出来。 拉伸错误的形状会一直保持错误(鞋子)。
  • 根据使用家具的人体尺寸决定家具大小,反之则不对。
  • 必须与图像对齐的涂鸦:从图像的 alpha 通道描摹其轮廓,绘制内部,将画框固定到图像,并在导出时裁剪掉类别的适配度(registration.md)。
  • 人物:仅使用 People.figure。 细节前先画姿态(一只腿承重,臀部和肩部向相反方向倾斜);姿势是角度,所以比例是固定的;家具和手持物品从返回的关节派生。背部的头发在身体之前绘制。
  • 跨过柔软形状的长直虚线 = 月牙包裹错误(在 S.soft 中修复);波浪形车床件 = 节点少 + 每段缓动:使用密集轮廓和 steps: 1。
  • { dash: true } 无效:请使用 S.dash。根据内容边界框调整物体,而非凭目测。
  • “凌乱” = 结构,而非细节:以完整尺寸判断单个主体;轮廓必须连接(关节处不能有开口端),色调紧密且规则或不存在,笔触宽度适合形状的宽度。

取景

  • 画框是派生的,而不是手动输入的:在画面平面工具包中,它是第一个区域的边界,所以第一个调用是 S.panel(<画框>);如果有相机,则来自投影。某物不可见?在将其画得更大之前,先检查它是否在画框内。clip = true 会裁剪到指定的画框。
  • 每个地面层都延伸到画框底部(FOOT),否则在较近层凹陷的地方会露出天空。一条地面规则应延伸到纸张的两边,而不是超过它们。

场景、夜晚、天气

  • 深度是一个数字 d(0 近,1 远),笔、排线间隙、颜色和细节都读取它。将山画成和长凳一样的权重是平面景观的失败。
  • 夜晚反转值:天空是最密集的排线,每个光点都是一个切割出来的间隙;发光比天空更亮。逆光的人物是排线剪影。
  • 雨最后绘制,伞下没有;倒影是翻转、压扁的物体,以破碎的带状呈现,没有轮廓。

页面和调色板

  • 页面必须声明其主体使用的每个调色板键;未知键在渲染时会静默变为黑色。
  • 并行的无头 Chrome 运行需要单独的 --user-data-dir,否则截图会返回空白。

验证

cd <工作区>                                     # 参见设置
bin/check.sh drawings/<名称>.html                  # 渲染,无 NaN,无控制台错误,无类别漂移
bin/shot.sh "drawings/<名称>.html?outline=1" out.png [1120x700]   # 查看效果;去掉 ?outline=1 获取彩色版本
bin/render.sh <名称>                               # 交付:doodles/<名称>/*.png,打开文件夹

Chrome/Chromium 由 bin/chrome.sh 查找(可通过 CHROME=/路径 覆盖);每次截图都会获得自己的 --user-data-dir,因此并行运行是安全的。查看每个 PNG 文件(打开它,或者如果你能看图像就读它)。check.sh 通过证明它已渲染,而非证明它可读。

演化此技能

当你修复了一个缺口时,将其写在一个新的会话能发现的地方(如果此技能是只读安装的,将这些笔记保存在工作区并说明):

  1. 主题的参考文件(references/<主题>.md):规则,附带其症状,作为指令陈述。

…

[因翻译目的而截断]

相关技能