⚡

等轴测技术图解Skill anatomy

把算法、系统或组件的技术概念转译成一台可识别的等轴测物理机器(测试台架、千分表、抽屉柜、绘图仪、锁),用数十到上百个精细实体零件、四段色调与正确的画家绘制顺序生成可交互 SVG 图解;不依赖框架(TypeScript/JS 直接输出 SVG+HTML),也支持 React/Next.js,可叠加与等轴测相机同一世界空间的 WebGL 着色器(火焰、排气、水、焦散、灯光)以及可选 3D 旋转模式,并附带几何审计、线端检查、无头浏览器截图与录制的验证工具链。关键词:等轴测插画, isometric SVG, 技术图解, 可交互解说图, 数据可视化, 前端可视化, WebGL 着色器, React/Next.js, SVG 绘图套件, 画家算法, 几何审计, 3D 转盘, Linear 风格技术绘图, 文档配图, 博客插图, 落地页插图

前端开发 0 次安装 9 次浏览 更新于 10/31/2026
名称 anatomy
描述 构建精心雕琢、高度精细、可交互的等轴测 SVG 图形,把技术想法解释为一件真实的物理对象(测试台架、千分表、抽屉柜、绘图仪、锁),其中包含大量细小而精确的实体零件、四段色调明暗、正确的绘制顺序(画家算法)、带标题/提示/实时读数的画框卡片,以及平缓的缓动运动。只要有人想要等轴测插图、说明性图表或图示(用于文档、博客文章、落地页或文章)、"Linear 风格"或"高级感"的技术绘图、可交互解说图,或一张展示系统/算法/组件如何工作的 SVG,即使他们从未说出"等轴测"这个词,都应使用本技能。它不依赖框架(用 TypeScript/JS 生成 SVG 和 HTML),也可用于 React/Next.js,并能加入逼真的 WebGL 着色器(火焰、排气、水、焦散、灯光),这些效果以同一等轴测透视存在于图中。当被要求时,还可把完成的图发布到 Anatomy 社区画廊。
开源协议 MIT compatibility: 为 Claude Code 编写;也可在 Antigravity、OpenCode、Codex 和 MiniMax Code 中运行。需要 Node.js 20.10+,以及用于各项检查的 Chrome 或 Chromium。 metadata: opencode/slash: “true”

Anatomy

此技能让图形看起来像工作台上的一台小仪器:带脚的厚重底座、带刻度尺的导轨、装在轴套上的滑架、滚花旋钮、螺旋弹簧、指针会动的千分表、作为小点的螺钉。读者之所以能看懂这个想法,是因为他们认出了这台机器。图中显示的每一个数字都来自驱动其零件运动的同一个模型。

技能自带八个完整示例。开工前先打开最接近的一个。每个不依赖框架的示例都用 node examples/<name>/build.mjs 构建,生成的独立 HTML 页面就写在脚本旁边;加 --light 得到浅色主题。

  • examples/dial-indicator/ 是最小的一个:支架上的千分表,总共约 300 行。
  • examples/desk-computer/ 是不依赖框架的 SVG:一台带可敲击键盘的台式电脑。输入的那一行显示在机箱正面平面内绘制的 CRT 屏幕上,关机时画面坍缩成一条线和一个点。它约有 85 个实体和 850 条路径。
  • examples/arcade-cabinet/ 是一台竖直街机柜,侧板已拆下,Hero 规模,约 240 个实体和 15 根线缆。一枚 25 美分硬币飞入投币口,以 30° 斜面上滚盘能达到的速度沿币道滚下,碰到投币开关的线,落入钱箱;开关的脉冲沿其线缆一段一段传到电路板,CRT 预热、自检并运行吸引模式(在倾斜显示器平面内绘制)。摇杆倾斜并闭合面板下的微动开关。它展示了如何放置相机让剖面机构始终可见、如何把凹形电路板画成沿任意轴的棱柱、如何在页面中用构建时同一个模块重建运动零件,以及在已确定顺序的保留槽位中绘制实时硬币和线缆。node build.mjs --audit 可证明几何正确。
  • examples/raptor-engine/ 是一台吊在测试台架上的火箭发动机。它的圆形零件来自 kit/lathe.mjs,它的管线与线束来自 kit/tube.mjs。它可拆成 11 个装配体,带错峰弹簧和逐帧深度重排序。每个零件都记录自己的真实形状,node build.mjs --audit(kit/audit.mjs)证明:在任何静止、拆解状态以及爆炸动画回放的每一帧中,没有任何东西穿透任何东西,每个端点都坐在真实支座上,没有弯折被夹扁、折叠或压在另一条线上,没有曲线轮廓的斜率抖动,并且每个重叠都按深度顺序绘制。WebGL 羽流、激波、飞溅和蒸汽渲染在后层 SVG 与前层 SVG 之间。它是密集管线、平滑着色和淡出的参考。
  • examples/ripple-tank/ 是一所学校的波纹水槽,高腿架在纸屏上方,从上方 44° 观察。两个 WebGL 层(灯光、阴影和纸上的焦散,以及水的反射和玻璃)对齐到等轴测平面,并由一个纯色散与光学模型(model.mjs)驱动;频率变化通过历史纹理从振子向外传播。
  • examples/test-rig/ 是一张来自真实站点的生产图(React/Next):弹簧安装滑架上的一颗玻璃按钮、导轨上按压并拉动的指状探头,以及读取倾斜量的千分表。它有 53 个实体和约 470 条路径。
  • examples/spot-plate/ 是来自同一站点的第二张生产图:凹点板上的六对玻璃水滴,每对由一个距离场绘制,因此比 merge 相距更近的一对会融合成一块玻璃。一扇塞尺片设定了 merge,每个间隙对应一片。它是形状互相变形、以及一个控制驱动多个零件的参考。
  • examples/turning-dial/ 是可选的 3D 模式:一个在真正 3D 中旋转的密码拨盘,上面有一只小机器人手。它有约 90 个金属材质的实时零件、第二个旋转组、一个铰链、一个会抬起的三铰链手指,以及一个作为自由体断开的舱体。WebGL LED、它的光斑和火花跟随运动零件。它旁边的 stress.mjs 是一只约 380 个零件的密集手,位于杂乱车间中,用于测量性能。

测试台架是绘图本身的质量标杆。Raptor 是着色器工作的标杆:WebGL 效果必须达到它世界空间、无跳变、无缝渲染的水准。

唯一重要的理念

物体就是解释。 不要画方框、箭头和标签。去发明一件真实的、做工精良的物理事物,它的运作就是那个概念。以下是此前的图如何映射的:

概念 物体
一个共享 GPU 上下文服务多个画布 龙门绘图仪:一个打印头访问 16 个井
内容不变时跳过工作的缓存键 弹子锁:当每颗弹子都匹配时,锁芯转动,什么也不用重绘
七个渲染目标,每个 texel 的字节数不同 七层抽屉柜,每层深度等于它的字节数
可分离模糊(49 × 49 次采样 vs 49 + 49) 钉床印章旁边是导轨上的两把梳子
一个按压并倾斜的弹簧 带弹簧、探头和千分表的测试台架
高度轮廓 轮廓(仿形)规压在边缘上
取决于朝向的光 小型摄影棚:转盘周围的钥匙灯和补光灯

两种失败方式在实践中都见过:

  • 过于抽象。 堆叠的平板、漂浮的板块或贴标签的方框,读起来什么都不像。
  • 过于扁平平淡。 一块大板加几条线,没有体积、没有零件、没有可发现的东西。

两者的解法相同:一台可识别的机器,由许多细小、精确、有目的的零件构成。

每一件作品都高度精细。 这对每张图都成立,无论想法或需求多小:一张快速解说图仍是一台密集、真实的机器,绝不是几块板。随规模(工作流第 1 步)变化的只是你推进的深度:Figure 对其主题和机构做 4× 扫描,Hero 或 Epic 扫描整张图。

  • 读真实的东西。 按真实物体的建造方式去建:每颗螺钉、每条缝、每个倒角、轴套、标签板、带连接器的线缆、带刻度的标尺,以及支撑零件的零件。
  • 两种看法。 在 1× 下它读作一台清晰的机器。在 4× 下每个区域仍有真实的东西可发现;光秃的表面或空角是未完成的活,而非宁静。
  • 有目的,绝不喧闹。 细节来自属于机构的零件。每个零件都坐在另一个零件上,结束在边缘上,并且是渐隐而不是陡然停止。
  • 最后检查。 完成前放大到 4×(Figure 看主题和机构,Hero 或 Epic 看整张图),在区域平淡处补上缺失的真实零件。

工作流

按这个顺序工作。在写任何几何之前先写下概念和零件清单。大部分质量在那里就已决定。

  1. 开工前先定规模。 在做任何其他工作之前先说出规模,并在下述分级要求估算时大致告诉用户需要多久。
    • Figure:一个机构,40–80 个零件,SVG 最多一个 WebGL 层。说出规模并直接构建,不必询问。不要向用户报时间,因为 Figure 常常不到一小时就完成。对下面的进度检查,按最多一小时预算。
    • Hero:一个密集物体,多个 WebGL 层或一个 3D 主体,80–150 个零件。约 2–4 小时。先说明,然后构建,除非用户要求做个快的。
    • Epic:整个车辆、建筑或带许多运动系统的工厂,或在多个主体上使用 3D 模式。6 小时或更多。不要开始。给出估算,提出一个保留想法核心的 Hero 版本,并列出完整版本会增加什么。只有当用户选择时才构建 Epic。
    • 无论规模如何,第一个小时内都要有一个能在浏览器中打开的可用页面,然后从那里加深。开始时和每一步运行 date,当某一步超过其估算份额的两倍时,告诉用户进展到哪、还剩什么。
  2. 真实优先。 收集被解释事物的真实数字和行为:尺寸、数量、阈值、曲线。读数、运动和说明文字都必须为真。如果可以,把模型写成一个小的纯模块,如 test-rig 示例中的 rig.ts,并让一切由它驱动。
  3. 发明物体。 选择一台机器、工具、仪器或家具,其机构与概念一一对应。用一句话说明什么在动、这个运动意味着什么。绝不要复制参考图:取其质感,而非其物体。
  4. 零件清单。 写至少 40 个零件(Figure 40–80,Hero 80–150,Epic 更多),分组:底座(板、脚、槽、角螺钉、标签板、标尺条)、结构(立柱、导轨、框架杆、端挡)、机构(滑架、轴套、弹簧、柱塞、指针)、控制(滚花旋钮、拇指螺钉、表冠)以及主体本身,即唯一被点亮的零件。每个零件坐在另一个零件上。references/craft.md 有零件词汇表和配方。
  5. 规划世界。 使用约等于实物 1 px 的世界单位:x 和 y 在地面,z 向上。用圆角矩形 {x, y, w, d, r} 和圆来布局平面图。选择相机:默认方位角 45°,35–60° 用于展示长边,仰角 30°(更高,如波纹水槽的 44°,用于看清开阔内部)。然后用 fitProjection(points, width, height, { pad, azimuth }) 适配。
  6. 几何只构建一次。 用套件(slabOf、cylinder、extrude、planOutline、topTicks、knurl、coil、radialTicks 等)在几何模块中预计算每条静态路径。任意轴上的圆形零件(钟形罩、法兰、阀门、执行器)来自 kit/lathe.mjs,管线和线缆来自 kit/tube.mjs。运动零件在静止位置构建一次,并用 translateAlong 移动。只有形状会变的零件才每帧重建。
  7. 从后到前、从下到上绘制。 用 depthOf 对重复零件排序。把包裹另一零件的任何东西拆成后半和前半:绕杆的弹簧、绕滑架的框架杆。运动零件画在它物理所在的槽位。见 references/craft.md 的"画家顺序"。一旦图有了管线、线缆和圆形零件,就不要再凭眼睛调键:把绘制每个物品的真实形状记录到 A.recorder(P, { order, spring }),让 A.settle(R, P) 在任何两个物品重叠处测量真实深度并设置键,最后用 A.auditOrExit(R, P) 结束构建。画之前先布线:两端有真实端口、腿沿结构走、航线在直段相交、套环在管的缺口处(references/craft.md 第 8 节)。记录你绘制内容的真实形状:用替身形状让审计静默是一个 bug,审计会失败。从压盖中滑出的杆是由 G.rodOut 生成的一根杆,用 A.slide 记录。
  8. 装框。 把图放进卡片:左上 Fig n,右上简短标题,左下交互提示,右下实时读数。图例键和真实说明放在卡片下方,除至多一个极小的雕刻标签外,图内不出现文字。
  9. 让它活起来。 使用平缓的基于时间的运动:指数跟随或真实弹簧。无人触碰时,空闲巡游循环。图响应指针和键盘,离开屏幕时停止,在减弱运动(reduced motion)下静止。在 refs 上写属性,不要每帧重新渲染。见 references/motion.md。
  10. 像评论家一样验证。 业主会放大找毛病,所以你先放大。读你做的每张 PNG。
  • 用 scripts/capture.mjs 捕获桌面、手机(宽 390)、悬停和若干运动瞬间;用 scripts/drive.mjs 做序列、拆解姿态和 --no-webgl 回退。
  • 把审计跑到零。 有管线、线缆或圆形零件时,node build.mjs --audit 必须以 audit passed 结束,每一行失败项都为 0:静止、拆解和飞行中的间隙、端子、松散端、折叠、自重叠、拥挤(也包括与细长实体的)、替身形状、支撑、抖动、鞍座和深度顺序。在几何中修复干涉,绝不用键偏置。
  • 把线段检查跑到零。 审计从来看不到线条标记。node scripts/lines.mjs page.html --out shots/lines.png(以及在 -light 页面、以及在 drive.mjs 的 ["lines"] 动作下每个静止姿态)必须打印 line ends: 0:每条缝、规则线、肋、刻度和指针都结束在一条描边、一个点或一个轮廓上。读带圈的 PNG。
  • 两种主题下每个接合处的 4× 特写(也构建 --light),装配与拆解状态:每个法兰、三通、弯头、卡箍、阀门、波纹管、箍带、鞍座、球接头和交叉处,每个弯曲体(无色调阶梯),纹理结束的每个位置(在边缘上或渐隐中),带缝的平面盒面,每根纹理软管在块接缝处,每根滑动杆在静止与全行程时,以及每个含文字或着色器内容的窗口。
  • 着色器: 用 ["slow", 0.05] 在每个过渡上放慢的接触表;不能有跳变,不能有颜色突变,边缘读数为 0。浅色主题中,还要在每个过渡中逐帧记录墨量(必须随光单调变化),并在墨与描边相接处以 8–16× 裁切(references/verify.md 的 “Light-theme shaders”)。
  • 把你的 PNG 放到示例旁边问:它是否一眼就是真实物体,充满小零件且有体积,每条线都结束在某个东西上?它在 1× 时是否高度精细,在 4× 时仍值得探索,没有光秃表面或空角?迭代直到是。清单:references/verify.md。

安装

套件位于 kit/:

文件 用途
kit/iso-kit.ts 整个核心在一个文件里:相机、实体、零件库、SVG 字符串渲染器、卡片和页面构建器,以及 CSS(ISO_CSS)。复制到 TypeScript 项目中。
kit/iso-kit.mjs 同一核心编译为纯 ESM,供 Node 脚本使用。直接导入。
kit/iso.css 写出的 ISO_CSS。导入一次,并在包裹器或 <body> 上加 class="iso"(浅色再加 data-theme="light")。
kit/react/draw.tsx 服务端安全的 React 组件:Solid、Line、Wire、Dots、FaceText、IsoFigure、Plate。
kit/react/live.tsx "use client" hooks:useReadout、useLoop、useEased、useInView、useStillness,以及 spring 和 follow。
kit/lathe.mjs 沿任意轴的圆形零件:frameAlong、lathe(任何带平滑节点的轮廓会自动开启平滑着色)、solidOf、disc、ringBand、sphereOf、saddleOf、bandsOf(把一个弯曲体切成可深度排序的带,共用一个表面,轮廓由 sidesOf 给出)、可见弧线、圆面上的肋和螺栓圈(ribsOf 和 dotsOf 接受 fade,ribsOf 接受 seams)、用于从压盖中滑出的杆的 rodOut,以及管道走线的 fillet。
kit/tube.mjs tubePieces 把 3D 管或线缆拆成可深度排序的块(带 breaks、套环和卡箍下的 gaps、椭圆端盖,以及沿横截面穿过每个接头的编织/波纹/缠绕 rings),tubeSvg 绘制其中一块;crossingsOf 找出一条路径穿过卡箍的位置,runsOf 找出绘制的行程。.tb-* 填充在 ISO_CSS 中。
kit/audit.mjs 证明几何。recorder(P, { order, spring }) 在辅助函数绘制时收集物品、形状(车削体、板、棱柱、盒、球、管、被其宿主切出的垫)和走线;settle(R, P) 对每个重叠对做光线投射求真深度,在静止、拆解和重放的爆炸动画中,并设置绘制键(overlapsOf、orderKeys);auditOrExit(R, P) 是 --audit 钩子,运行所有检查(clearances、solidClearances、terminals、looseEnds、supports、folds、selfOverlaps、crowding(把细长实体视为线)、coverage(替身形状)、wobble、seats、depthOrder),有任何问题就以非零退出。A.slide 记录从压盖中滑出的杆。references/kit.md 第 12 节。
kit/gl.mjs 图中着色器的 WebGL 层:GLSL_ISO(GLSL 中的相机,含 rayOf 和 pixelOf)、glCamera(P)、glLayer(...),以及 JS 包络 smooth、burst 和 settle。对 3D 图,GLSL_TURN 和 glslPose(name) 把世界点带入运动组,并用 coverOf 遮罩前层画布。
kit/turn.mjs、kit/turn-build.mjs、kit/turn-audit.mjs 可选的 3D 模式。turn-build.mjs 有 turning(P, { recorder }):组(turn、slide、hinge、free)、实时层、带材质的凸零件,以及 T.build。turn.mjs 是运行时:TURN.mount、控制器、TURN.cover、TURN.poseUniforms 和 TURN_CSS。turn-audit.mjs 有 orbitOrExit,对每个转角与运动片段做环绕审计。references/3d.md。
scripts/capture.mjs 无头 Chrome 截图、特写和 console 检查,开启 WebGL。用 node 运行。
scripts/drive.mjs 带 WebGL 的脚本化无头 Chrome:move、click、key、slow motion、wait-until、eval、shots 和能捕捉跳变的接触表;--no-webgl 和 --preload。
scripts/lines.mjs 对已构建页面的线端检查,在无头 Chrome 中:每条纹理线都必须结束在描边、点或轮廓上。用 --out 给失败项加圈;任一处失败就以 1 退出。
scripts/inline-kit.mjs kitScript()、glScript() 和 turnScript() 把套件、WebGL 层和 3D 运行时作为源码返回,可内联到独立页面。
scripts/turn-check.mjs、scripts/turn-bench.mjs 3D 图:对照套件构建器的保真度、z 缓冲顺序检查、像素跳变、24 个角度的线端和浏览器中的帧计时;Node 中每种零件类型的 CPU 时间。

选择适合项目的路径:

  • 独立 HTML、静态 SVG、博客文章或任何非 React 站点。 写一个像 examples/dial-indicator/build.mjs 的 Node 构建脚本。它导入 kit/iso-kit.mjs,用 solidSvg、lineSvg、dotsSvg、wireSvg 和 faceTextSvg 组装字符串,用 figureSvg 和 plateHtml 包裹,并用 pageHtml({ script: kitScript() + live }) 写出页面,有着色器时用 kitScript() + glScript() + live。对于单个 .svg 文件,用 figureSvg({ standalone: "dark" | "light" }),它会内嵌样式。
  • React 或 Next.js。 把 kit/ 复制到项目中(例如 components/iso/)。把几何保留在普通 .ts 模块中,在服务端组件里用 draw.tsx 组件构建静态图,并作为 element props 传给一个 "use client" 的实时组件来移动东西。references/react.md 解释这个拆分以及大页面下的一个陷阱。

工艺规则(简版)

这些规则把工艺图与示意图区分开。references/craft.md 给出完整推理和配方。

  • 实体,不是线框。 每个零件都用纸色填充并按顺序绘制,所以前面的东西遮住后面的。没有透视边,没有虚线隐藏线。
  • 让套件着色。 extrude 返回四个侧面色调(按朝向)外加更浅的顶面。任何有高度的东西都保留它,仅在底面和薄于 1 单位的内嵌中使用 flat。
  • 色调层级。 底座和脚用 lo,结构用 mid,主体用 hi。恰好一个强调色用 lit(深色中为白,浅色中为黑):读者应注视的零件。槽用 faint,次刻度 lo,主刻度 mid,零刻度 hi。只有当颜色本身是主题(如红、绿、蓝通道)时才使用颜色。
  • 细小精确的细节,绝不喧闹。 使用 0.4–1.6 的倒角、距边缘内缩 3–5 的槽、板角上带环的 0.4–0.55 点螺钉、旋钮上的滚花、每 4–5 单位一个刻度且每第 5 个为主刻度的标尺,以及带三条规则线的标签板。每个细节都属于某个零件。
  • 线条要收束。 每条线都结束在某个东西上:一个面、另一条线或一个端子点。连接器是 Wire,其端子点落在物体上。没有引线、气泡标注、尺寸箭头或漂浮在空中的标签。
  • 没有管线或线缆穿过任何东西。 不在静止、拆解或爆炸动画的任何帧中穿过另一根管、线缆或实体。除线自身连接外,与其他一切保持约 1.5 个半径的间隙;沿结构走线而不是横穿主体正面;凡法兰、箍带、波纹管、卡箍或阀门包裹管道处都要留缺口。零件要齐平、相切或边缘贴面相接,绝不沉入:法兰的背面落在其端口上(端口为曲面时落在鞍座垫 G.saddleOf 上),分支从球三通引出,每个端点(拆解时也是)都收在法兰、联轴器、连接器外壳或端子点上。
  • 每个交叉都按真实深度顺序绘制。 两个物品在屏幕上重叠处,近者绘于其上,由 A.settle 和审计证明,而非凭眼调。线条在直段、深度差足够处相交:一个弯、端点或卡箍落在另一条线的轮廓上会被读作接头(杆、拉杆、立柱或导轨都算作线:管道的最后一段绝不在屏幕上沿着它们走),一条腿先指向观察者再转向会夹成 V 形(这类端口通过弯头球出去),一条走线绝不在屏幕上折返。无法排序的一对必须互锁,修复办法是切分或相切接触,绝不是偏置。
  • 曲面平滑着色,绝不成阶梯。 把曲线节点标为平滑([s, r, 1]),lathe 会从一条同时绘制轮廓的单调曲线为其着色;任何大于接头的弯曲体都要用带 smooth: { slope } 的解析轮廓,长体用 G.bandsOf 切分,球用 G.sphereOf。色调带渐隐至无,而不是止于直切口,接缝放在轮廓之下(inner)。
  • 纹理结束在真实边缘上或渐隐。 肋、螺栓圈、规则线、接缝和槽绝不在平面或曲面中间停止:ribsOf 和 dotsOf 接受 fade(渐隐的肋用 fadedSvg 绘制),一排肋结束在其接缝上(ribsOf(…, { seams: true })),盒上的接缝或焊缝绕其角(k.sideSeam,如板的 inner),一个面上的线从边到边,通风口是闭合槽,刻度悬挂在标尺条的边缘,一条必须停止的单线用 fadeLineSvg 渐隐退出,朝上的特征行(环顶部的孔)要四周都可见(all: true)。管上的纹理(编织、波纹、缠绕)沿其横截面并在每个块接缝处连续:用 tubePieces(…, { rings }),绝不用沿中心线的虚线描边。管的光泽与阴影要延伸到其端盖并穿过每个块接缝。只有代表印刷文字的规则线、指针的尾部和指示器的尖端可以停在光秃表面上,标为 free。
  • 着色器绝不跳变或截断。 每个 uniform 都沿带上升和衰减的包络运行,相位变化是由物理量驱动的交叉淡化,每一项都在任何边界或画布边缘之前归零,效果存在于图自身相机的世界空间中(见下文)。
  • 面上的东西要适配它们。 机器显示的文本在其最宽字符串处适配其窗口并被裁剪到窗口;透过开口看到的内容既被开口裁剪也被其自身平面裁剪,并绘制凹槽壁。
  • 体积。 给东西真实厚度,让它们站在别的东西上,并在底座下和任何被抬起的东西下放柔和光晕。
  • 构图。 让图居中并填充卡片的约 55–65%。在一组图中保持一致的尺度,并确保在 390 px 宽时仍能读懂。

绘制中的 WebGL

只在线条画不出来的地方使用着色器:火焰与排气、水与焦散、真实的灯光、辉光、蒸汽。零件仍是 SVG。核心规则来自第一张着色器图——它在相位之间的颜色变化看起来像被切开的,而不是交叉淡化的:

  • 三层。 后层 SVG 承载效果所覆盖的东西,canvas 承载效果(pointer-events: none),前层 SVG 承载覆盖效果的东西。当一个零件或效果同时位于两侧时,将其拆分。
  • 世界空间,同一相机。 用 onFloor、onWallX 和 onWallY 构建每个着色器点,或步进像素的射线 rayOf(vb) + t·towardViewer()。一切以世界单位乘以 uK 计量。任何位于平面上的东西都与该平面的 SVG 线精确重合。
  • 绝不跳变。 每个 uniform 都遵循带上升与衰减的包络(套件的 burst 用于事件,settle 用于电平)。相位变化是交叉淡化,颜色随物理量连续变化,淡出只会变暗。
  • 没有硬截断。 每一项都在任何 if、边界或画布边缘之前,以及任何单元噪声的单元边缘之前归零。
  • 透过开口看,遮罩两次。 窗口或凹槽后面的内容在其自身平面内被遮罩,也被面平面内的开口遮罩,两者相乘(references/webgl.md 第 5 节)。
  • 混合。 使用 tonemap() 和抖动。深色主题中,只加光的画布用预乘输出配 mix-blend-mode: screen,而必须同时变暗的(波纹水槽的水)保持正常混合。
  • 浅色主题必须交付,其着色器为纸张设计。 使用正常预乘 alpha,绝不用 screen。写出纸张应显示的颜色,并反解出墨水。辉光是饱和的主体配苍白的核心、有色边缘和 alpha 下限,绝不是变暗的深色主题颜色:那曾导致 Raptor 的"红墨水烟雾"。
    • 光照到的物体带上一层色调,容纳它的空腔得到更暗的物理底色(烟灰、耐火材料、水深)。
    • 高温物体遵循与回退方案共用的一张黑体墨水表。
    • 墨水只随光增长:把完成的墨水淡化一次,绝不逐项淡化。
    • 墨水在每条描边的内边缘处结束。
    • 逐帧测量墨水。references/webgl.md 第 8 节有配方和审阅者发现的缺陷。
  • 克制。 设备像素比上限 1.5,仅在效果活动且在屏时渲染。减弱运动只得到一帧静止画面,且 SVG 在没有 WebGL 时仍必须可读。

编写任何着色器之前先读 references/webgl.md。

3D:会转动的图(beta)

3D 像 WebGL 一样是一个选项。当零件在深度中运动就是想法时使用它:旋转的表盘或转盘、弯曲的手指、断裂掉落的物件。图的其余部分保持静态套件艺术。

它是 beta:引擎已在其示例和一张测试图上得到验证,尚未用于生产图。一次只旋转一个主体,并让周围杂物保持静止。小图以 60 fps 运行;一只密集的 380 零件弯曲手在 1440 下测得约 20 fps,在负荷沉重的机器上以手机配置(390 px、4× CPU 节流)测得 13–15 fps。

  • 实时零件就是套件自己的画面。 每帧,凸的套件基元(棱柱、圆体、穹顶、带平面的球、车削体、管)都按套件的规则重新投影和重新着色。转角 θ 就是套件在方位角 a − θ 处绘制。
  • 顺序来自分离平面。 同组对获得一个在组内固定的平面,不同连杆上的对获得一个在其共同坐标系中固定的平面,其余的每帧求解。审计证明在任何角度或任何片段帧中都没有环。
  • 接触是齐平、相切或边缘贴面。 关节是子组上的同轴指节盘,接触父级的连杆,否则审计会称整个子组是松的。没有实时线跨越两个运动组:线缆通过两侧的线夹跨过关节,或通过轮毂处的滑环到达转盘。
  • 实时管在近水平面内或在配件内弯曲,绝不沿视线方向。 一个弯需要 R ≥ 2r / sin²(e − θmax),其中 θmax 包括它所依附的每个铰链的俯仰范围:平坦时边界为 8r,在 ±12° 铰链上为 21r。每条走线从安装面到安装面,其端口在 gaps 中。这在每个角度和每个姿态都成立。
  • 材质重映射明暗阶梯。 金、铬、钢、枪金属、橡胶、黄铜和铜各有明暗两套;色调仍来自朝向。
  • 自由组断开时无跳变。 同轴零件是带转动纹理的固定画面。
  • 着色器跟随运动。 用 controller.anchor 或 toGroup 把它们锚定到组,用 coverOf 遮挡前层画布,并让世界效果(烟雾、下落火花、工作台上的油)留在组空间之外。
  • 用 --audit 验证(turn audit passed)和 scripts/turn-check.mjs(--fidelity、--order、--pops、--lines、--perf)。用 --quick --only=… 迭代。只有完整运行才能证明图,30 个零件需 15–20 分钟,所以放到后台运行。

先读 references/3d.md。

参考

按需阅读:

  • references/craft.md:外观深入,包括带代码的零件词汇、色调表、画家顺序模式、圆形零件、管线与线束、爆炸图、面上的屏幕,以及被拒图的那些反模式。设计前阅读。
  • references/kit.md:API,带签名和示例。
  • references/motion.md:实时行为(循环、弹簧、巡游、指针、键盘、可访问性、减弱运动),以及一次性事件、爆炸图、深度重排序和布防的包络,含 vanilla JS 和 React。
  • references/react.md:React/Next.js 服务端/客户端拆分、element props,以及大负载的 key 警告陷阱。
  • references/verify.md:capture.mjs 和 drive.mjs 命令、审查清单(含着色器)和常见缺陷。
  • references/webgl.md:绘制中的着色器:何时值得、层堆栈、相机契约、在等轴测相机中光线步进、带最小页面的完整 API、带教训 bug 的工艺规则、浅色主题(纸上的墨水、逐现象配方、审阅者的缺陷),以及如何验证。
  • references/walkthrough.md:测试台架如何被设计,从概念到代码,一步步。
  • references/3d.md:可选的 3D 模式:组与姿态、实时层、凸零件及其规则、材质、自由组、铰链链、画家顺序、转盘周围的静态杂物、跟随转动的着色器、环绕审计、浏览器检查、性能和限制。
  • references/publish.md:用 scripts/publish.mjs 在社区画廊分享完成的图,仅在用户要求时;不会替他们推送任何东西。