|
| 1 | +# 图片展示 (Photo Showcase) |
| 2 | + |
| 3 | +适用于:用户**显式要求使用图片/配图/插图**的场景(如"画一个带配图的旅行路线"、"做一个有图片的产品展示")。 |
| 4 | + |
| 5 | +> **注意**:仅当用户明确说了「图片/配图/插图/照片」等词时才进入本场景。单纯说"旅行路线图"、"产品展示"等不触发。 |
| 6 | +
|
| 7 | +> **前置条件**:进入本场景前,必须已完成 SKILL.md 的"图片资源处理 → Step 0",拿到所有 file_token。 |
| 8 | +
|
| 9 | +## Content 约束 |
| 10 | + |
| 11 | +- 图片 3-6 张,每张配标题(必需)+ 简短描述(可选,15字内) |
| 12 | +- **每张图必须是不同的真实图片**(不同 file_token),下载时用不同关键词/URL |
| 13 | +- 下载后用 `md5` 校验确保每张图不重复 |
| 14 | +- 文字仅作辅助说明,图片是信息主体 |
| 15 | + |
| 16 | +## Layout 选型 |
| 17 | + |
| 18 | +| 模式 | 适用条件 | 特征 | |
| 19 | +|------|---------|------| |
| 20 | +| **卡片网格(默认)** | 多图平级展示(产品墙、团队介绍、美食推荐) | horizontal frame 内放等尺寸图文卡片 | |
| 21 | +| **路线时间线** | 有先后顺序(旅行路线、团建路线、项目演进) | 图文卡片 + connector 串联 | |
| 22 | +| **中心辐射** | 有一个核心主题 + 周围子项 | 中心标题 + 周围图文卡片 | |
| 23 | + |
| 24 | +## Layout 规则 |
| 25 | + |
| 26 | +- **图文卡片结构**:vertical frame(图上文下),image 宽度 = 卡片宽度,height 按 3:2 比例 |
| 27 | +- **卡片统一尺寸**:所有卡片宽高一致(推荐 240×280 或 200×250) |
| 28 | +- **图片统一尺寸**:所有 image 节点用相同 width/height(推荐 240×160 或 200×133) |
| 29 | +- **卡片间距**:gap: 24(比纯文字图表间距更大,让图片呼吸) |
| 30 | +- **卡片样式**:白色底 + 圆角 12 + 细边框,image 无圆角(紧贴卡片顶部) |
| 31 | +- **有序路线时**:卡片间用 connector 连接,connector 放顶层 nodes 数组 |
| 32 | + |
| 33 | +## 骨架示例 |
| 34 | + |
| 35 | +### 卡片网格(产品展示/团队介绍/美食推荐) |
| 36 | + |
| 37 | +```json |
| 38 | +{ |
| 39 | + "version": 2, |
| 40 | + "nodes": [ |
| 41 | + { |
| 42 | + "type": "frame", "id": "grid", "layout": "vertical", "gap": 24, "padding": 32, |
| 43 | + "width": 840, "height": "fit-content", |
| 44 | + "children": [ |
| 45 | + { "type": "text", "id": "title", "width": 776, "height": 36, |
| 46 | + "text": "图表标题", "fontSize": 24, "textAlign": "center" }, |
| 47 | + { |
| 48 | + "type": "frame", "id": "row", "layout": "horizontal", "gap": 24, "padding": 0, |
| 49 | + "width": "fit-content", "height": "fit-content", |
| 50 | + "children": [ |
| 51 | + { |
| 52 | + "type": "frame", "id": "card-1", "layout": "vertical", "gap": 8, "padding": [0, 0, 12, 0], |
| 53 | + "width": 240, "height": "fit-content", |
| 54 | + "fillColor": "#FFFFFF", "borderWidth": 1, "borderColor": "#E0E0E0", "borderRadius": 12, |
| 55 | + "children": [ |
| 56 | + { "type": "image", "id": "img-1", "width": 240, "height": 160, "image": { "src": "<token_1>" } }, |
| 57 | + { "type": "text", "id": "t-1", "text": "标题", "fontSize": 14, "width": 216, "height": 20 }, |
| 58 | + { "type": "text", "id": "d-1", "text": "简短描述", "fontSize": 11, "color": "#666666", "width": 216, "height": 16 } |
| 59 | + ] |
| 60 | + } |
| 61 | + ] |
| 62 | + } |
| 63 | + ] |
| 64 | + } |
| 65 | + ] |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +每张图文卡片结构相同,复制并替换 `<token_N>`、标题和描述即可。3 张卡片一行,超过 3 张换行(嵌套第二个 horizontal frame)。 |
| 70 | + |
| 71 | +### 路线时间线(旅行路线/团建路线) |
| 72 | + |
| 73 | +```json |
| 74 | +{ |
| 75 | + "version": 2, |
| 76 | + "nodes": [ |
| 77 | + { |
| 78 | + "type": "frame", "id": "route", "layout": "vertical", "gap": 24, "padding": 32, |
| 79 | + "width": 1100, "height": "fit-content", |
| 80 | + "children": [ |
| 81 | + { "type": "text", "id": "title", "width": 1036, "height": 36, |
| 82 | + "text": "路线标题", "fontSize": 24, "textAlign": "center" }, |
| 83 | + { |
| 84 | + "type": "frame", "id": "stops", "layout": "horizontal", "gap": 32, "padding": 0, |
| 85 | + "width": "fit-content", "height": "fit-content", |
| 86 | + "children": [ |
| 87 | + { |
| 88 | + "type": "frame", "id": "stop-1", "layout": "vertical", "gap": 8, "padding": [0, 0, 12, 0], |
| 89 | + "width": 240, "height": "fit-content", |
| 90 | + "fillColor": "#FFFFFF", "borderWidth": 1, "borderColor": "#E0E0E0", "borderRadius": 12, |
| 91 | + "children": [ |
| 92 | + { "type": "image", "id": "img-1", "width": 240, "height": 160, "image": { "src": "<token_1>" } }, |
| 93 | + { "type": "text", "id": "t-1", "text": "第1站:地点名", "fontSize": 14, "width": 216, "height": 20 } |
| 94 | + ] |
| 95 | + }, |
| 96 | + { |
| 97 | + "type": "frame", "id": "stop-2", "layout": "vertical", "gap": 8, "padding": [0, 0, 12, 0], |
| 98 | + "width": 240, "height": "fit-content", |
| 99 | + "fillColor": "#FFFFFF", "borderWidth": 1, "borderColor": "#E0E0E0", "borderRadius": 12, |
| 100 | + "children": [ |
| 101 | + { "type": "image", "id": "img-2", "width": 240, "height": 160, "image": { "src": "<token_2>" } }, |
| 102 | + { "type": "text", "id": "t-2", "text": "第2站:地点名", "fontSize": 14, "width": 216, "height": 20 } |
| 103 | + ] |
| 104 | + } |
| 105 | + ] |
| 106 | + } |
| 107 | + ] |
| 108 | + }, |
| 109 | + { "type": "connector", "id": "c1", "connector": { "from": "stop-1", "to": "stop-2", "fromAnchor": "right", "toAnchor": "left" } } |
| 110 | + ] |
| 111 | +} |
| 112 | +``` |
| 113 | + |
| 114 | +注意:connector 必须放在**顶层 nodes 数组**,不能嵌套在 frame.children 内。connector 的属性须包裹在 `connector` 字段中。 |
| 115 | + |
| 116 | +## 图片准备检查清单 |
| 117 | + |
| 118 | +生成 DSL 前确认: |
| 119 | + |
| 120 | +- [ ] 所有 image 节点的 `image.src` 都是已上传的 file_token(非 URL) |
| 121 | +- [ ] 每个 file_token 不同(对应不同的真实图片) |
| 122 | +- [ ] 所有图片尺寸一致(同一画板内统一 width×height) |
| 123 | +- [ ] 图片宽高比合理(推荐 3:2,即 240×160) |
0 commit comments