Loading... # AI + Excalidraw 自然语言绘图技术分析 # 一、概述 ## 1. 项目背景 ### A. 核心问题 技术文档创作过程中,绘制流程图、时序图、架构图等手绘风格图表往往需要手动操作绘图工具,耗时且不直观。 ### B. 解决方案 结合 Excalidraw 开源手绘风格白板与大语言模型,实现通过自然语言描述自动生成手绘风格图表的工具。 ## 2. 技术亮点 ### A. 流式渲染 AI 生成 JSON 元素后实时解析并渲染到画布,边生成边画图。 ### B. 多端适配 支持桌面端和移动端布局,移动端采用上下布局设计。 ### C. 数据隐私 所有画布数据和对话历史保存在浏览器 localStorage,不上传服务器。 ## 3. 技术栈 - 前端:Next.js + @excalidraw/excalidraw - 后端:Vercel AI SDK - AI 服务:支持 OpenAI、智谱、阿里百炼等兼容接口 # 二、系统架构 ## 1. 整体架构 ```mermaid graph TD A[用户输入描述] --> B[AI 服务端] B --> C[流式生成 Excalidraw JSON] C --> D[前端流式解析器] D --> E[Excalidraw 画布渲染] F[localStorage] --> D F --> E ```  ## 2. 组件交互 ```mermaid sequenceDiagram participant U as 用户 participant F as 前端界面 participant A as AI 服务 participant E as Excalidraw 画布 participant L as localStorage U->>F: 输入绘图描述 F->>A: 发送对话请求 A-->>F: 流式返回 JSON 元素 F->>F: 实时解析 JSON loop 每解析一个元素 F->>E: 添加元素到画布 E-->>U: 实时渲染更新 end F->>L: 保存对话历史和画布数据 ```  # 三、核心技术实现 ## 1. Excalidraw JSON 规范 ### A. 元素类型 Excalidraw 通过 JSON 描述图形元素,支持以下类型: | 类型 | 说明 | 特有属性 | |------|------|---------| | rectangle | 矩形 | - | | ellipse | 椭圆 | - | | diamond | 菱形 | - | | text | 文本 | text, fontSize, fontFamily | | arrow | 箭头 | points, endArrowhead | | line | 线条 | points | ### B. 基础元素结构 每个元素包含以下基础属性: - id:元素唯一标识 - type:元素类型 - x, y:位置坐标 - width, height:尺寸 - backgroundColor:填充颜色 - strokeColor:边框颜色 ### C. 元素示例 ```json { "type": "excalidraw", "version": 2, "source": "https://excalidraw.com", "elements": [ { "id": "rect-1", "type": "rectangle", "x": 100, "y": 100, "width": 150, "height": 80, "backgroundColor": "#a5d8ff", "strokeColor": "#1971c2" } ] } ``` ## 2. AI 提示词设计 ### A. 输出格式要求 - 先简要说明要画什么,然后连续输出所有 JSON 元素 - 禁止在 JSON 元素之间穿插说明文字 - 每个元素直接输出纯 JSON 对象 - 禁止使用代码块标记(避免反引号) - 必须使用标准 JSON 格式 ### B. 文字处理规则 - 中英文宽度计算 - 形状内文字双向绑定 - fontSize 和 fontFamily 设置 ### C. 箭头规范 - points 使用相对坐标写法 - 支持各方向箭头 - endArrowhead 箭头样式设置 ### D. 颜色规范 使用 Excalidraw 内置调色板,确保颜色一致性。 ## 3. 流式 JSON 解析 ### A. 核心挑战 AI 返回流式内容,需要: 1. 追踪花括号深度处理嵌套 JSON 2. 正确处理字符串内的花括号 3. 记录已处理位置避免重复解析 ### B. 解析算法 ```javascript function extractJsonObjects(text) { const results = []; let i = 0; while (i < text.length) { const startIndex = text.indexOf('{', i); if (startIndex === -1) break; // 追踪花括号深度 let depth = 0; let inString = false; for (let j = startIndex; j < text.length; j++) { const char = text[j]; // 处理转义字符 if (char === '\\' && j + 1 < text.length) { j++; continue; } // 处理字符串边界 if (char === '"') { inString = !inString; continue; } // 在字符串内不计算花括号 if (inString) continue; if (char === '{') depth++; else if (char === '}') { depth--; if (depth === 0) { // 找到完整的 JSON 对象 results.push(text.slice(startIndex, j + 1)); i = j + 1; break; } } } } return results; } ``` ## 4. 实时渲染 ### A. 元素添加流程 通过 Excalidraw API 的 updateScene 方法将解析的元素添加到画布: ```javascript useImperativeHandle(ref, () => ({ addElements: (newElements) => { const api = excalidrawAPIRef.current; const currentElements = api.getSceneElements(); // 处理 id 冲突 const existingIds = new Set(currentElements.map(el => el.id)); const elementsToAdd = newElements.map(el => { if (existingIds.has(el.id)) { return { ...el, id: generateNewId() }; } return el; }); // 更新画布 api.updateScene({ elements: [...currentElements, ...elementsToAdd], }); }, })); ``` ### B. ID 冲突处理 - 检查现有元素的 ID - 发现冲突时生成新 ID - 确保每个元素唯一标识 ## 5. 元素默认值补全 ### A. 降级策略 AI 可能只生成必要字段,需要补全 Excalidraw 需要的其他字段: ```javascript function getDefaultElementProps() { return { angle: 0, strokeColor: '#1e1e1e', backgroundColor: 'transparent', fillStyle: 'solid', strokeWidth: 2, roughness: 1, // 手绘粗糙度 opacity: 100, seed: Math.random() * 100000, // 随机种子,产生手绘效果 version: 1, versionNonce: Math.random() * 1000000000, isDeleted: false, groupIds: [], boundElements: null, }; } ``` ### B. 字段说明 - roughness:控制手绘效果的粗糙程度 - seed:随机种子,产生自然的手绘变化 - opacity:透明度设置 - groupIds:元素分组支持 # 四、后端服务设计 ## 1. AI 服务兼容层 ### A. 多服务支持 封装统一的 AI 服务接口,支持: - OpenAI - 智谱 AI - 阿里百炼 - 其他 OpenAI 兼容服务 ### B. 调用方式 使用 Vercel AI SDK 对接大模型,实现流式响应。 ## 2. 安全设计 ### A. API 密钥保护 - AI 调用在服务端进行 - 不向客户端暴露 API 密钥 ### B. 日志记录 记录每次对话的信息: - IP 地址 - User-Agent - 对话内容 - 响应时间 # 五、前端功能设计 ## 1. 数据持久化 ### A. localStorage 存储 - 对话历史保存在 localStorage - 画布数据保存在 localStorage - 刷新页面不丢失数据 ### B. 隐私保护 - 所有数据仅存储在浏览器本地 - 不上传到服务器 - 用户完全控制自己的数据 ## 2. 移动端适配 ### A. 布局设计 - 桌面端:左右布局 - 移动端:上下布局(画布在上方,输入框在底部) ### B. 功能限制 移动端核心功能: - AI 生成图表 - 查看渲染效果 - 基础画布操作 # 六、实现方式对比 ## 1. AI 辅助实现 ### A. 适用场景 - 已清楚实现思路 - 需要快速原型 - 减少重复劳动 ### B. 操作方式 将详细需求整理为 prompt,使用 AI IDE 的 Plan 模式生成代码。 ### C. 优缺点 优点: - 开发速度快 - 核心逻辑可靠 缺点: - 对实现细节了解不深 - 可能需要调整代码 ## 2. 手动实现 ### A. 适用场景 - 学习技术思路 - 理解实现细节 - 掌握核心技术 ### B. 学习价值 - 深入理解流式解析 - 掌握 Excalidraw API - 熟悉 AI 集成方案 # 七、技术评估 ## 1. 当前状态 ### A. 技术可行性 流程已打通,核心功能可用。 ### B. 实际效果 作者评价:流程是通的,效果是拉胯的。 ### C. 应用定位 目前仅适合作为玩具体验,距离生产可用还有差距。 ## 2. 技术挑战 ### A. AI 生成质量 - JSON 格式准确性 - 元素布局合理性 - 箭头连接准确性 ### B. 复杂图表支持 - 大规模元素渲染 - 元素关系自动布局 - 美观性优化 ## 3. 改进方向 ### A. 提示词优化 - 更精确的格式约束 - 更好的布局指导 - 更丰富的示例 ### B. 后处理增强 - 自动布局算法 - 元素对齐优化 - 美观度调整 ### C. 多轮对话 - 支持修改已有图表 - 增量添加元素 - 智能调整布局 # 八、相关资源 ## 1. 官方文档 - Excalidraw 集成文档:https://docs.excalidraw.com/docs/@excalidraw/excalidraw/integration - GitHub 仓库:113k+ star ## 2. 技术栈 - Next.js:React 框架 - @excalidraw/excalidraw:Excalidraw 官方包 - Vercel AI SDK:AI 集成工具 ## 3. 在线体验 - 工具地址:https://www.lzkz.top/tool/excalidraw - 作者:松柏 *** ## 参考资料 1. [AI+Excalidraw,用自然语言画手绘风格技术图](https://mp.weixin.qq.com/s/EZVJrtHJTeSt3Y1XOy4VPw) 最后修改:2026 年 01 月 15 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏