# CodePic AI 图形创建指南

> 本文档供 AI 模型参考，用于生成符合 CodePic 平台格式的流程图/图形 JSON。版本：`$schema: "codepic/beta"`, `$version: "0.1.0-beta"`

## 一、文档格式

`Store.toJSON()` / `editor.toJSON()` 导出的结构：

```json
{
  "$schema": "codepic/beta",
  "$version": "0.1.0-beta",
  "document": {
    "id": "string",
    "name": "string"
  },
  "pages": [
    {
      "id": "string",
      "name": "string",
      "elementIds": ["id1", "id2"],
      "backgroundColor": "#f8f9fa"
    }
  ],
  "elements": [
    { /* Element 对象 */ }
  ]
}
```

- `document`：文档元信息
- `pages`：页面列表，`elementIds` 为该页顶层元素 ID（有序）
- `elements`：所有元素的扁平数组，`parentId` 为 null 的为顶层元素，其 id 需出现在某页的 `elementIds` 中

## 二、图形类型清单

| type | 用途 |
|------|------|
| rect | 矩形，流程图节点、卡片 |
| ellipse | 椭圆/圆，开始/结束节点 |
| diamond | 菱形，判断/决策节点 |
| parallelogram | 平行四边形，输入/输出、数据节点 |
| document | 文档形状，文档/报告节点 |
| text | 纯文本块 |
| line | 直线/曲线/自由手绘 |
| connector | 连接器，连接两个图形 |
| image | 图片 |
| frame | 画框容器 |
| table | 表格（含 table-head、table-row、table-cell 子结构） |

## 三、必填字段（所有元素）

每个 Element 必须包含：

- `id`：唯一标识（建议 `crypto.randomUUID()` 或唯一字符串）
- `type`：上述类型之一
- `x`, `y`：画布坐标（左上角）
- `width`, `height`：宽高
- `parentId`：父元素 ID，顶层为 `null`
- `childrenIds`：子元素 ID 数组，无子则为 `[]`
- `strokeColor`, `strokeWidth`, `fillColor`, `fillStyle`, `opacity`, `roughness`, `seed`, `corners`
- `text`, `fontSize`, `fontFamily`, `fontColor`, `fontWeight`, `fontStyle`, `textAlign`, `verticalAlign`, `lineHeight`, `wordWrap`
- `containable`, `containableFilter`, `connectable`, `textEditable`, `sizable`, `movable`, `locked`, `visible`
- `constraints`, `tags`, `data`
- `name`, `description`：可选，供 AI 理解语义

## 四、类型专用字段

| type | 专用字段 | 说明 |
|------|----------|------|
| connector | `sourceId`, `targetId`, `sourceAnchor`, `targetAnchor`, `points`, `lineType` | sourceId/targetId 引用已存在元素 ID |
| parallelogram | `data.parallelogramSkew` | 0.2 表示左右边倾斜 20% |
| document | `data.documentWaveAmpRatio` | 0.25 表示底部波浪幅度 |
| line | `points`, `lineType` | points 为 `[[x1,y1],[x2,y2],...]` |
| image | `src`, `originalWidth`, `originalHeight` | src 为 URL 或 base64 |
| frame | `clipContent` | 是否裁剪子元素 |

## 五、约束规则

1. **connector**：`sourceId`、`targetId` 必须引用 `elements` 中已存在的元素 ID
2. **table**：需先创建 table、table-head、table-row，再创建 table-cell，并正确设置 `parentId`、`childrenIds`
3. **父子一致**：若 A 的 `parentId` 为 B，则 B 的 `childrenIds` 必须包含 A 的 id
4. **页面引用**：顶层元素的 id 必须出现在某页的 `elementIds` 中

## 六、最小示例

### 完整文档示例（矩形 + 椭圆 + 连接器）

```json
{
  "$schema": "codepic/beta",
  "$version": "0.1.0-beta",
  "document": { "id": "doc-1", "name": "示例流程" },
  "pages": [
    {
      "id": "page-1",
      "name": "Page 1",
      "elementIds": ["rect-1", "ellipse-1", "conn-1"],
      "backgroundColor": "#f8f9fa"
    }
  ],
  "elements": [
    {
      "id": "rect-1",
      "type": "rect",
      "name": "步骤",
      "description": "",
      "x": 100,
      "y": 100,
      "width": 160,
      "height": 80,
      "rotation": 0,
      "parentId": null,
      "childrenIds": [],
      "strokeColor": "#000000",
      "strokeWidth": 2,
      "fillColor": "#ffffff",
      "fillStyle": "solid",
      "opacity": 1,
      "roughness": 1,
      "seed": 42,
      "corners": [0, 0, 0, 0],
      "text": "处理",
      "fontSize": 16,
      "fontFamily": "pigtruman, sans-serif",
      "fontColor": "#333333",
      "fontWeight": "bold",
      "fontStyle": "normal",
      "textAlign": "center",
      "verticalAlign": "center",
      "lineHeight": 1.2,
      "wordWrap": true,
      "containable": false,
      "containableFilter": "",
      "connectable": true,
      "textEditable": true,
      "sizable": "free",
      "movable": "free",
      "locked": false,
      "visible": true,
      "constraints": [],
      "tags": [],
      "data": {}
    },
    {
      "id": "ellipse-1",
      "type": "ellipse",
      "name": "开始",
      "description": "",
      "x": 100,
      "y": 250,
      "width": 140,
      "height": 100,
      "rotation": 0,
      "parentId": null,
      "childrenIds": [],
      "strokeColor": "#000000",
      "strokeWidth": 2,
      "fillColor": "#ffffff",
      "fillStyle": "solid",
      "opacity": 1,
      "roughness": 1,
      "seed": 42,
      "corners": [0, 0, 0, 0],
      "text": "开始",
      "fontSize": 16,
      "fontFamily": "pigtruman, sans-serif",
      "fontColor": "#333333",
      "fontWeight": "bold",
      "fontStyle": "normal",
      "textAlign": "center",
      "verticalAlign": "center",
      "lineHeight": 1.2,
      "wordWrap": true,
      "containable": false,
      "containableFilter": "",
      "connectable": true,
      "textEditable": true,
      "sizable": "free",
      "movable": "free",
      "locked": false,
      "visible": true,
      "constraints": [],
      "tags": [],
      "data": {}
    },
    {
      "id": "conn-1",
      "type": "connector",
      "name": "",
      "description": "",
      "x": 0,
      "y": 0,
      "width": 0,
      "height": 0,
      "rotation": 0,
      "parentId": null,
      "childrenIds": [],
      "strokeColor": "#000000",
      "strokeWidth": 2,
      "fillColor": "transparent",
      "fillStyle": "none",
      "opacity": 1,
      "roughness": 0,
      "seed": 42,
      "corners": [0, 0, 0, 0],
      "text": "",
      "fontSize": 16,
      "fontFamily": "pigtruman, sans-serif",
      "fontColor": "#333333",
      "fontWeight": "bold",
      "fontStyle": "normal",
      "textAlign": "center",
      "verticalAlign": "center",
      "lineHeight": 1.2,
      "wordWrap": true,
      "containable": false,
      "containableFilter": "",
      "connectable": false,
      "textEditable": false,
      "sizable": "none",
      "movable": "free",
      "locked": false,
      "visible": true,
      "constraints": [],
      "tags": [],
      "data": {},
      "points": [[180, 140], [180, 300]],
      "lineType": "straight",
      "sourceId": "rect-1",
      "targetId": "ellipse-1",
      "sourceAnchor": [0.5, 1],
      "targetAnchor": [0.5, 0]
    }
  ]
}
```

### 各类型最小元素（可替换上述 elements 中对应项）

**diamond（菱形）**：与 rect 类似，`type: "diamond"`，`width: 120`, `height: 80`

**parallelogram（平行四边形）**：`type: "parallelogram"`，`data: { "parallelogramSkew": 0.2 }`

**document（文档）**：`type: "document"`，`data: { "documentWaveAmpRatio": 0.25 }`

**text（纯文本）**：`type: "text"`，`strokeWidth: 0`，`fillColor: "transparent"`，`fillStyle: "none"`

**frame（画框）**：`type: "frame"`，`containable: true`，`clipContent: true`

**line（直线）**：`type: "line"`，`points: [[x1,y1],[x2,y2]]`，`lineType: "straight"`，`connectable: false`

## 七、Schema 与默认值

- **JSON Schema**：https://codepic.cc/schemas/document.json ，可用于校验输出
- **类型默认值**：https://codepic.cc/type-defaults.md ，各 type 的默认 width/height 等

## 八、API 与导入

- **保存**：`PUT /api/documents/:id`，body `{ data: editor.toJSON() }`
- **加载**：`GET /api/documents/:id`，返回的 `data` 可直接 `editor.fromJSON(data)`
- **导入**：编辑器内 ⌘K 搜索「从 JSON 导入」，粘贴完整 JSON 即可全量替换画布
