春节期间我们开源了一个 AI-Native 的矢量设计工具,对标 Pencil.dev,让 AI Agent 直接画 UI

开源了一个 AI-Native 的矢量设计工具,对标 Pencil.dev,让 AI Agent 直接画 UI

先说结论

我做了一个开源矢量设计工具叫 OpenPencil ,对标商业产品 Pencil.dev,核心差异点:

  1. 完全开源,MIT License,不是又一个套壳 SaaS
  2. AI-Native,不是"设计工具 + AI 插件",而是从架构层就为 AI 设计的
  3. Agentic Design,自带 MCP Server,Claude Code / Cursor / Windsurf 等 AI Agent 可以直接操作设计稿,不需要人打开 GUI
  4. Design-as-Code.op 文件就是结构化 JSON,能进 Git、能 diff、能 code review

如果你用过 Pencil.dev,你应该知道它的 AI 生成设计能力很强。但它是闭源的、付费的,而且设计稿锁在它的平台里。OpenPencil 想做的事情是------把同样的能力开源出来,同时让设计稿真正属于你的代码仓库。

GitHub 地址 → github.com/ZSeven-W/op...

为什么现在做这个有意义?

2025 年之后,AI 写代码已经不稀奇了。但你有没有发现一个断层------

AI 能帮你写出一个完整的后端服务,却画不好一个登录页面。

原因很简单:现有的设计工具(Figma、Sketch)都是为人类设计的。它们的文件格式是二进制或私有协议,API 有限,AI 想操作它们只能通过插件间接控制,效率极低。

而 Pencil.dev 看到了这个机会------它的 .pen 格式是结构化的,天然对 AI 友好。但问题是它是闭源商业产品。

OpenPencil 的思路是:如果设计稿本身就是一份 JSON,那 AI 读写设计稿就跟读写代码一样自然。 不需要插件,不需要 API 转换,直接操作数据结构。

这才是 AI 时代设计工具该有的样子。

Agentic Design:让 AI Agent 成为你的设计师

这是我最想展开讲的部分,也是 OpenPencil 和传统设计工具最大的区别。

什么是 Agentic Design?

简单说:设计稿不再只是人用鼠标拖出来的,AI Agent 可以自主读取、理解、修改、生成设计稿。

内置的 AI 设计生成

除了外部 Agent 调用,OpenPencil 自己也内置了 AI 设计生成。在编辑器的聊天面板里,你可以用自然语言描述需求:

"帮我设计一个 SaaS 定价页面,三个档位,支持年付/月付切换"

背后的架构是一个 Orchestrator + Sub-Agent 的编排系统:

graph TD A["用户输入需求"] --> B["Orchestrator
空间分解:Header / Pricing Cards / Footer"] B --> C1["Sub-Agent 1"] B --> C2["Sub-Agent 2"] B --> C3["Sub-Agent 3"] C1 --> D["流式插入画布(带淡入动画)"] C2 --> D C3 --> D D --> E["Vision 校验
截图 → Vision API → 自动修复视觉问题"] style B fill:#6366f1,color:#fff style E fill:#f59e0b,color:#fff

几个关键设计决策:

  • 空间分解而非语义分解:Orchestrator 按空间区域拆分任务,而不是按"标题、文案、按钮"拆分。因为设计本质上是空间排布问题,空间分解更符合直觉,子 Agent 之间的依赖也更少。
  • 流式插入:节点不是生成完才一次性渲染,而是边生成边插入画布,用户可以实时看到 AI 在"画"。
  • Vision 自校验 :生成完成后,自动截图发给 Vision API 检查,如果发现明显的视觉问题(文字溢出、对齐偏移、颜色对比度不够),自动修复。AI 不光会画,还会自己检查作业。

生成出来的不是图片,是真正的矢量节点树------每个元素都可以选中、编辑、调整属性、导出代码。

技术实现:React + Fabric.js 做设计工具有多难

下面聊点硬核的,给同样想做图形编辑器的同学一些参考。

最大的挑战:声明式 vs 命令式的双向同步

技术栈是 React 19 + Fabric.js v7 + Zustand v5

React 是声明式的,Fabric.js 是命令式的。你用 Zustand store 管理数据,用 Fabric 渲染画布,两者之间的同步是整个项目最难的部分。

数据流架构:

graph TD A["React 组件
工具栏 / 属性面板 / 图层面板"] -->|"Zustand hooks"| B["canvas-store
UI 状态:工具/选区/视口"] A -->|"Zustand hooks"| C["document-store
PenDocument · CRUD / 树操作"] B --> D["Fabric.js Canvas
命令式渲染"] C --> E["canvas-sync-lock
防止循环同步"] E -.->|"锁保护"| D style C fill:#6366f1,color:#fff style E fill:#f59e0b,color:#fff

核心原则:document-store 是唯一数据源,Fabric.js 只负责渲染。

但双向同步意味着:

  • 用户在画布上拖对象 → Fabric 内部状态先变 → 事件回调写入 store
  • 用户在面板改数值 → store 更新 → 需要同步到 Fabric 对象

A 更新 B,B 又更新 A,循环了。

解决方案是一个 canvas-sync-lock------谁在写入,就锁住另一方的监听。听起来简单,但批量操作、undo/redo、动画中间态、组内级联更新......每个场景的同步时序都不一样,调了很久。

Fabric.js v7 的坑

v7 把默认原点从 left/top 改成了 center/center。你写 left: 100, top: 100,对象中心点在 (100,100) 而不是左上角。

在做父子变换、自动布局、对齐吸附的时候,坐标系不统一会直接爆炸。解决方案就一行:

js 复制代码
{ originX: 'left', originY: 'top' }

每个对象都显式声明,永远不信默认值。一行代码省了三天 debug。

另一个坑是默认 strokeWidth: 1,不要描边的时候必须显式设 strokeWidth: 0,否则你会看到每个对象都有一条若有若无的边框,排查起来很抓狂。

父子节点变换传播

Fabric.js 没有原生的父子层级,对象模型是扁平的。但设计工具里 Frame 嵌套子元素是基本操作。所以需要:

  1. document-store 维护树形结构
  2. 渲染时拍平成绝对坐标
  3. 操作时换算回相对坐标
  4. 父节点变换时手动传播给后代

缩放传播还好,旋转传播涉及三角函数和矩阵运算,单独抽了一个 parent-child-transform.ts 处理。

设计变量系统

支持设计变量(类似 CSS Custom Properties),关键决策:$variable 引用在 store 里原样保留,只在渲染时解析。

ts 复制代码
// store 里存引用
{ fill: { color: '$color-primary' } }

// 渲染前解析为具体值
{ fill: { color: '#6366f1' } }

// 生成代码时输出 CSS 变量
{ fill: 'var(--color-primary)' }

好处:改变量值全局生效、多主题切换只需换变量集、代码生成零硬编码。支持多维度主题轴(Light/Dark × Compact/Comfortable = 4 种变体)。

完整技术栈

层级 技术
前端框架 React 19 + TypeScript(严格模式)
样式 Tailwind CSS v4 + shadcn/ui
画布引擎 Fabric.js v7
状态管理 Zustand v5
路由 TanStack Start(文件路由)
服务端 Nitro
桌面端 Electron 35(macOS / Windows / Linux)
AI Claude / OpenAI,Orchestrator + Sub-Agent 编排
Agent 协议 MCP Server(兼容 Claude Code / Cursor / Windsurf)
运行时 Bun

最后

我做 OpenPencil 的初衷很简单:

2025 年了,AI 能写出整个应用的代码,却还是画不好一个 UI。 不是 AI 不够强,是现有的设计工具不给 AI 机会。文件格式是二进制的、API 是受限的、生态是封闭的。

Pencil.dev 证明了 AI-Native 设计工具这条路走得通,OpenPencil 想做的是把这条路开源出来------让每个开发者都能用上 Agentic Design,让设计稿真正成为代码仓库的一部分。

GitHub → github.com/ZSeven-W/op...

如果你对这些方向感兴趣,欢迎一起交流:

  • Agentic Design --- AI Agent 自主操作设计稿的工作流
  • Design-as-Code --- 设计稿版本管理、CI/CD、代码生成
  • 图形编辑器开发 --- Canvas 2D / Fabric.js 踩坑经验
  • AI 编排架构 --- Orchestrator + Sub-Agent 的任务分解

项目还在活跃开发中,欢迎 Star、欢迎 PR、欢迎 Issue。开源不易,你的每一颗 Star 都是继续做下去的动力。

相关推荐
没想好d1 小时前
通用管理后台组件库-6-头部导航组件
前端
linux_cfan1 小时前
打造智慧校园视听新基建:高校与在线教育平台 Web 视频播放器选型指南 (2026版)
前端·学习·音视频·教育电商
JYeontu1 小时前
实现一个超萌的柯基交互输入框
前端
天蓝色的鱼鱼2 小时前
Vite 8:从“混动”到“纯电”,构建性能提升10倍+
前端·vite
dreams_dream2 小时前
XSS类型
前端·xss
wuhen_n2 小时前
副作用的概念与effect基础:Vue3响应式系统的核心
前端·javascript·vue.js
张3蜂2 小时前
Vue.js-知识体系
前端·javascript·vue.js
Cache技术分享2 小时前
333. Java Stream API - 按年份找出合作最多的作者对:避免 Optional.orElseThrow() 的风险
前端·后端
用户600071819102 小时前
【翻译】元素与 Children 属性
前端·react.js