Appearance
Design JSON 最小可读完整示例
盒型取验证工作台的默认值 120 × 260 × 90 mm、胶舌 15 mm,展开 435 × 350 mm(公式见 四摇盖胶封盒几何)。 这份样例通过 node docs-site/check.mjs 的内置结构检查,字段全部对得上 packages/design-json 的 zod schema。
为可读性做了两处删减,都写在下面,不是省略真相:
aux层各只保留 1 条代表线;真实生成结果是 cut 22 条 / crease 12 条 / glue 1 条(上面那条命令的实跑输出)。image素材省略了dataUrl(真实导出必须是内嵌 base64)。
json
{
"schemaVersion": 1,
"designId": "ds_demo120x260x90",
"name": "四摇盖胶封盒 · 120×260×90 · 最小可读示例",
"canvasMm": { "width": 435, "height": 350 },
"bleed": { "top": 3, "right": 3, "bottom": 3, "left": 3 },
"safeAreaInsetMm": 5,
"dieline": {
"dielineId": "dl_rect120260",
"boxType": "rectangular",
"paramsMm": { "width": 120, "height": 260, "depth": 90, "glueMm": 15 },
"material": { "name": "四摇盖胶封折叠纸盒;未补偿纸厚" }
},
"layers": [
{
"id": "ly_cut000001",
"name": "cut",
"kind": "aux",
"auxKind": "cut",
"locked": true,
"visible": true,
"paths": [{ "closed": false, "points": [{ "x": 15, "y": 0 }, { "x": 135, "y": 0 }] }]
},
{
"id": "ly_crease0001",
"name": "crease",
"kind": "aux",
"auxKind": "crease",
"locked": true,
"visible": true,
"paths": [{ "closed": false, "points": [{ "x": 15, "y": 45 }, { "x": 135, "y": 45 }] }]
},
{
"id": "ly_glue00001",
"name": "glue",
"kind": "aux",
"auxKind": "glue",
"locked": true,
"visible": true,
"paths": [{ "closed": false, "points": [{ "x": 7.5, "y": 47 }, { "x": 7.5, "y": 303 }] }]
},
{
"id": "ly_kvimage01",
"name": "主视觉(AI 提取素材)",
"kind": "image",
"panelId": "front",
"assetId": "as_kvfront01",
"opacity": 1,
"blendMode": "normal",
"sizeMm": { "width": 80, "height": 176 },
"colorSpaceOverride": "preserve",
"transform": { "x": 35, "y": 82, "rotationDeg": 0, "scaleX": 1, "scaleY": 1 }
},
{
"id": "ly_brandtext",
"name": "品名(真实文字层,非 AI 图内文字)",
"kind": "text",
"panelId": "front",
"text": "青云酱香",
"fontId": "ft_songti001",
"sizeMm": 14,
"leadingMm": 18,
"trackingEm": 60,
"align": "center",
"writingMode": "horizontal",
"color": { "mode": "cmyk", "c": 74, "m": 22, "y": 0, "k": 12 },
"source": "manual",
"transform": { "x": 45, "y": 268, "rotationDeg": 0, "scaleX": 1, "scaleY": 1 }
}
],
"assets": [
{
"id": "as_kvfront01",
"storageKey": "assets/demo/kv-front.png",
"mimeType": "image/png",
"widthPx": 1024,
"heightPx": 2253,
"dpi": 325,
"bytes": 917504,
"checksumSha256": "0000000000000000000000000000000000000000000000000000000000000000",
"extraction": {
"source": "assets/demo/client-image1.jpg",
"resultSource": "assets/demo/kv-front.png",
"selection": { "x": 412, "y": 96, "width": 1024, "height": 2253, "pixels": 1840512 },
"mask": "assets/demo/client-mask.png",
"createdAt": "2026-10-01T02:00:00.000Z",
"instruction": "只取右上礼盒主体,保留金色浮雕,去掉背景与左侧酒瓶"
}
}
],
"fonts": [
{
"id": "ft_songti001",
"family": "Songti SC",
"style": "Medium",
"storageKey": "fonts/STHeiti-Medium.ttc",
"licenseStatus": "pending",
"embeddable": true,
"hasCjk": true
}
],
"brandTokens": {
"colors": [
{
"name": "品牌蓝",
"color": {
"mode": "spot",
"spotName": "PANTONE 286 C",
"tint": 100,
"cmykFallback": { "c": 100, "m": 74, "y": 0, "k": 14 }
}
}
],
"fontIds": ["ft_songti001"],
"logoAssetIds": [],
"forbidden": [{ "kind": "word", "value": "治疗", "note": "保健类禁用词" }],
"fixedCopy": [{ "key": "净含量", "text": "500ml" }]
},
"mappings": [
{
"panelId": "front",
"dielineRectMm": { "x": 15, "y": 45, "width": 120, "height": 260 },
"faceIndex": 0,
"uvRect": { "x": 0.034483, "y": 0.128571, "width": 0.275862, "height": 0.742857 },
"uvRotateQuarter": 0,
"mirrorU": false
},
{
"panelId": "right",
"dielineRectMm": { "x": 135, "y": 45, "width": 90, "height": 260 },
"faceIndex": 3,
"uvRect": { "x": 0.310345, "y": 0.128571, "width": 0.206897, "height": 0.742857 },
"uvRotateQuarter": 0,
"mirrorU": false
},
{
"panelId": "back",
"dielineRectMm": { "x": 225, "y": 45, "width": 120, "height": 260 },
"faceIndex": 6,
"uvRect": { "x": 0.517241, "y": 0.128571, "width": 0.275862, "height": 0.742857 },
"uvRotateQuarter": 0,
"mirrorU": false
},
{
"panelId": "left",
"dielineRectMm": { "x": 345, "y": 45, "width": 90, "height": 260 },
"faceIndex": 9,
"uvRect": { "x": 0.793103, "y": 0.128571, "width": 0.206897, "height": 0.742857 },
"uvRotateQuarter": 0,
"mirrorU": false
}
],
"provenance": {
"model": "codex-image-gen",
"promptVersion": "kv-front-v3",
"mode": "inpaint",
"affectedLayerIds": ["ly_kvimage01"],
"aiGenerated": true,
"labeled": true
}
}逐段解释(为什么是这个值)
| 片段 | 为什么 |
|---|---|
canvasMm 435 × 350 | W = 2(W+D) + glue = 2(120+90)+15,H = H + D;由几何生成器写回,不允许手填 |
paramsMm.glueMm: 15 | 必须显式写。zod 包装器默认 10、rectangular.mjs 默认 15,两者不一致 → 约定"显式传参" |
bleed 全 3、safeAreaInsetMm 5 | zod 默认值(bleedSchema / design.ts);验证版编辑器暂未画出血框(P2-01/P2-02) |
aux 线坐标 | 直接来自 rectangularGeometry:front_top 顶边 y=0 是 cut;front 上折线 y=45 是 crease;glue 在 x = glue/2 = 7.5,上下各内缩 min(2, H/4) |
| 图层顺序 | 引导层(aux)在前、印刷内容在后,这是 applyGeometry 的实际写入顺序 |
transform.x/y | 画布绝对 mm(对象左上角),不是面板内相对值;改盒型尺寸时 applyGeometry 会按面板位移平移它们 |
mappings | uvRect = 面板 bbox / sheet,faceIndex 与面板生成顺序一致(front=0, front_top=1, front_bottom=2, right=3 …);完整 13 条由 geometryMappings 生成 |
licenseStatus: "pending" | 系统里有字体 ≠ 拿到商用授权;PE-05 未清前保持 pending,blocked 会让整份设计 parse 失败 |
provenance.mode: "inpaint" | 只有主视觉被重绘,affectedLayerIds 只列它;文字层是人工重建的,不参与 AI 生成 |
省略 costUsdEstimate | 内置 image-gen 未返回金额 → 宁可不写,也不填 0 |
怎么自己验一遍
零依赖(站点内置检查:结构 + 单位后缀 + 引用 + mm 公式一致性):
sh
node docs-site/check.mjs真实 zod 校验(复用仓库里已有的 schema bundle,仍然不装新依赖):
sh
node tools/build-runtime.mjs # 生成 workers/ai/runtime/design-schema.mjs
node docs-site/check.mjs --zod # 内置结构检查 + 用真实 zod 再 parse 一遍--zod 在 bundle 不存在时打印跳过提示,不改变退出码判定逻辑之外的行为。
验证工作台里,image 图层还必须带内嵌 dataUrl(tools/validate-design.mjs 会拒绝只有本地路径的素材), 画布尺寸上限 2500 mm。