OpenPencil Vue SDK 入门指南:从 createEditor 到画布渲染,搭建可嵌入的 AI 原生设计编辑器
发布时间:2026/9/26 2:24:59来源:尧图网络
前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载本指南以 OpenPencil 官方 SDK 文档SDK Getting Started为核心完整讲解如何把open-pencil/vue接入你自己的 Vue 3 应用安装依赖、创建编辑器实例、通过provideEditor()注入、用useCanvas()绑定渲染画布并在此基础上使用选择状态、编辑命令等组合式 APIComposables搭建属性面板与工具栏。读完本文你将掌握从空白页面到「带画布、可选中节点、可执行编辑命令」的最小设计器应用的完整落地路径。SDK 概览三层应用架构OpenPencil 的 Vue SDK 遵循「引擎与视图分离」的分层设计。以 SDK 为基础的应用由三个层次组成open-pencil/core—— 框架无关的编辑器引擎。它不依赖 Vue只负责场景图Scene Graph、选区、撤销、布局、文本、变量、视口等核心逻辑是整个 SDK 的「大脑」open-pencil/vue—— Vue 组合式 APIComposables与无外观headless结构原语。它把核心编辑器「适配」进 Vue 生态提供注入injection、响应式状态派生、画布与输入接线但不强加任何样式你的应用层—— 负责样式、路由、文件流和产品特有的 UI弹窗、菜单、通知等。open-pencil/vue自身不拥有编辑器模型它只是open-pencil/core之上的 Vue 适配层。官方 SDK Architecture 对此有更细致的职责划分SDK 负责编辑器集成、可复用的无头逻辑、无样式假设的 UI 结构、画布渲染接线而应用负责样式、布局外壳、路由、文件流与产品级 UX。判断某段逻辑是否应放进 SDK 的经验法则很实用如果一段逻辑换一个 OpenPencil 应用还能复用、且不带着应用样式它就属于open-pencil/vue。安装与依赖要求SDK 位于 OpenPencil 单体仓库monorepo中以open-pencil/vue包发布。使用 Bun 安装全部依赖bun add open-pencil/core open-pencil/scene-graph open-pencil/vue canvaskit-wasm需要同时引入四个包open-pencil/core无框架编辑器引擎提供createEditor等核心 APIopen-pencil/scene-graph场景图数据模型createEditor的默认与显式构造都依赖它open-pencil/vueVue 3 SDK本文的主角canvaskit-wasmCanvasKitSkia 的 WebAssembly 版本运行时用于画布渲染。版本要求当前开发版本要求 Vue^3.5.41使用可选的 CanvasKit peer 依赖时需要canvaskit-wasm 0.41.1。使用更早的发布版本时请以安装后包内的 peer 依赖声明为准。这一点可以直接在 packages/vue/package.json 中核实peerDependencies声明了open-pencil/core: workspace:*、canvaskit-wasm: 0.41.1与vue: ^3.5.41且canvaskit-wasm被标记为可选peerDependenciesMeta。安装完成后在入口代码中引入核心符号import { createEditor } from open-pencil/core/editor import { provideEditor, useCanvas } from open-pencil/vue说明德语版入门文档给出的安装命令为bun add open-pencil/core open-pencil/vue canvaskit-wasm英文版当前开发版本文档补充了open-pencil/scene-graph。以本仓库当前开发版本的英文文档为准同时安装open-pencil/scene-graph可保证示例代码中new SceneGraph()等用法直接可用。第一步创建编辑器实例createEditor()是引擎的入口。官方文档强调了一个重要事实width与height并不是EditorOptions的属性早期示例曾直接传入宽高当前开发版本已改为通过getViewportSize回调提供视口尺寸。下面是当前推荐的最小创建方式import { reactive } from vue import { createDefaultEditorState, createEditor } from open-pencil/core/editor import { SceneGraph } from open-pencil/scene-graph const graph new SceneGraph() const page graph.getPages()[0] if (!page) throw new Error(Expected an initial page) const editor createEditor({ graph, state: reactive(createDefaultEditorState(page.id)), getViewportSize: () ({ width: 1200, height: 800 }), })要点拆解graph显式传入一个SceneGraph实例。createEditor在未传graph时会内部新建一个见 packages/core/src/editor/create.ts但显式传入可以让你在创建编辑器之前准备页面数据、并在后续用replaceGraph切换文档state核心状态本身与框架无关但把reactive(createDefaultEditorState(page.id))传入后Vue 侧控件可以直接观察编辑器状态的变化。createDefaultEditorState内部由共享状态与视图状态合并而成见 packages/core/src/editor/state/index.ts它需要初始页面的page.id因此必须先new SceneGraph()并取出首页getViewportSize返回当前视口尺寸的回调。对于可缩放resizable的编辑器应返回画布容器的实时尺寸而不是写死一个常量。EditorOptions的完整字段定义在 packages/core/src/editor/types.ts除上面三个外还包括选项类型说明loadFont(family, style, characters?, signal?) PromiseArrayBuffer \| null自定义字体加载策略默认使用内置的fontManager.loadFontresolveFigmaClipboardImagesFigmaClipboardImageResolver解析 Figma 剪贴板图片的回调默认nullskipInitialGraphSetupboolean是否跳过初始的场景图事件订阅默认false用于替换文档等高级场景createEditor()返回的编辑器对象聚合了选区、页面、参考线、形状、结构、节点、对齐、矢量化、变量、文本、视口、撤销、剪贴板、组件等十余个领域模块的动作方法见 packages/core/src/editor/create.ts后面会看到useEditor()如何把它暴露给组件树。第二步通过 provideEditor 注入编辑器拿到编辑器实例后需要在 Vue 组件树顶层把它「提供」给所有后代组件。推荐的做法是封装一个 Provider 组件script setup langts import { provideEditor } from open-pencil/vue import type { Editor } from open-pencil/core/editor const props defineProps{ editor: Editor }() provideEditor(props.editor) /script template slot / /templateprovideEditor()把编辑器实例提供给其下所有组件。它的底层实现就是一次 Vue 注入EDITOR_KEY是一个类型为InjectionKeyEditor的Symbol(open-pencil-editor)provideEditor调用provide(EDITOR_KEY, editor)见 packages/vue/src/editor/context/index.ts。对应的读取端useEditor()直接inject(EDITOR_KEY)若在未调用provideEditor的子树中调用useEditor()它会主动抛错[open-pencil] useEditor() called without an injected editor. Call provideEditor(editor) near the top of your Vue subtree first.这是刻意设计——编辑器上下文缺失时应快速失败fail loudly而不是在静默的undefined上继续运行见 packages/vue/src/editor/context/index.ts。历史说明旧示例与旧错误信息中仍会提到OpenPencilProvider组件如仓库示例应用 packages/vue/example/src/App.vue 仍在使用它。但当前 SDK 的公开 API 面就是provideEditor()/useEditor()这套注入模型新代码应优先直接使用它们。第三步绑定画布编辑器的渲染目标是真实的canvas元素。用useCanvas()把它接上script setup langts import { ref } from vue import { useCanvas, useEditor } from open-pencil/vue const canvasRef refHTMLCanvasElement | null(null) const editor useEditor() useCanvas(canvasRef, editor) /script template canvas refcanvasRef classsize-full / /templateuseCanvas()负责一整条渲染管线CanvasKit 初始化、surface 创建、渲染调度、尺寸变化时重建 surface、可选的标尺显隐、以及渲染器就绪回调。它的源码实现在 packages/vue/src/canvas/surface/use.ts通过createCanvasSurfaceManager管理 surface编辑器、canvas 引用、选项、CanvasKit 实例、标尺显隐策略等通过useCanvasSurfaceLifecycle处理创建/销毁生命周期并在就绪时回调options.onReady返回render/renderNow手动触发重绘以及hitTestSectionTitle/hitTestComponentLabel/hitTestFrameTitle三个基于渲染器的命中测试函数供上层交互代码使用。如果不想手写canvas与上述接线也可以直接用 SDK 提供的无头结构原语CanvasRootCanvasSurface见 packages/docs/programmable/sdk/api/components/canvas-root.md 与 canvas-surface.md由 SDK 托管画布引用与渲染集成样式与布局仍归应用所有。useCanvas()的第三个参数options类型为UseCanvasOptions定义见 packages/vue/src/canvas/surface/types.ts常用选项如下选项类型说明showRulersboolean强制标尺显隐省略时回退到视口与 URL 参数逻辑preserveDrawingBufferboolean保留绘制缓冲供截图/像素回读工作流使用但可能增加内存占用onReady() void渲染 surface 就绪后的回调layerfull \| scene \| overlays该画布负责的渲染层用于多画布分层sceneRendererretained \| tiled启用实验性 tiled 场景渲染器shouldSuspendRender() boolean挂起渲染的条件判断onPresented(versions) void帧呈现后的版本信息回调onPresentation(colorSpace) void上报画布实际呈现的颜色空间含回退用于宽色域支持getRenderState() EditorState提供本画布渲染所用的视图状态默认editor.state多个画布可共享同一文档图与历史、但使用独立视图状态onViewportResize(width, height) voidsurface 创建与尺寸变化后的 CSS 视口尺寸回调使用 Composables 读取状态与执行命令provideEditor()之后所有后代组件都可以通过 SDK 的 composables 读取选区、执行命令。最常用的两个import { useEditorCommands, useSelectionState } from open-pencil/vue const selection useSelectionState() const commands useEditorCommands()useSelectionState()从当前编辑器派生响应式选区状态适合驱动依赖「是否选中、选中多少个、选中了什么类型」的 UI。返回的常用值包括selectedIds、hasSelection、selectedNode、selectedCount、selectedNodeType、isInstance、isComponent、isGroup、canCreateComponentSet。典型用法script setup langts import { useSelectionState } from open-pencil/vue const { hasSelection, selectedCount, isInstance } useSelectionState() /script template div classtext-xs text-muted span v-if!hasSelectionNo selection/span span v-else {{ selectedCount }} selected span v-ifisInstance· instance/span /span /div /templateuseEditorCommands()在编辑器动作之上提供一层「命令化」接口适合构建应用菜单、右键菜单、工具栏与快捷键适配层。常用导出包括commands、menuItem、runCommand、moveSelectionToPage、otherPagesconst { menuItem } useEditorCommands() const editMenu [ menuItem(edit.undo, ⌘Z), menuItem(edit.redo, ⇧⌘Z), { separator: true }, menuItem(selection.delete), ]也可以直接执行命令const { runCommand } useEditorCommands() runCommand(selection.duplicate)命令 ID 是受约束的字符串联合类型EditorCommandId包括edit.undo、edit.redo、selection.selectAll、selection.duplicate、selection.delete、selection.group、selection.ungroup、selection.createComponent、selection.createComponentSet、selection.createInstance、selection.detachInstance、selection.goToMainComponent、selection.wrapInAutoLayout、selection.bringToFront、selection.sendToBack、selection.toggleVisibility、selection.toggleLock、selection.moveToPage、view.zoom100、view.zoomFit、view.zoomSelection等完整类型见 use-editor-commands 文档。如果只想直接拿到编辑器做底层操作useEditor()同样可用例如读取选中节点或触发编辑器级动作const editor useEditor() const selected editor.getSelectedNodes() editor.zoomToFit() editor.undoAction()一个完整的可运行示例把上述三个步骤拼起来就是一个带状态栏的极简编辑器页面顶部状态栏实时显示选中节点数量画布渲染由useCanvas负责。script setup langts import { ref } from vue import { useCanvas, useEditor, useSelectionState } from open-pencil/vue const canvasRef refHTMLCanvasElement | null(null) const editor useEditor() const { selectedCount } useSelectionState() useCanvas(canvasRef, editor, { onReady: () { console.log(Canvas ready) }, }) /script template div classgrid h-full grid-rows-[1fr_auto] canvas refcanvasRef classsize-full / div classborder-t px-3 py-2 text-xs text-muted Selected: {{ selectedCount }} /div /div /template注意这里editor必须已经由祖先组件通过provideEditor提供如果useCanvas在未注入的子树中被调用useEditor()会直接抛错。仓库自带一个完整的示例应用展示了超出本文最小示例的集成工具栏ToolbarRoot/ToolbarItem、页面切换、图层树LayerTree、属性面板NodeProperties以及CanvasRootCanvasSurface的画布用法见 packages/vue/example/src/App.vue。本地运行它cd packages/vue/example bun install bun run dev在该示例中编辑器创建后直接调用editor.createShape(FRAME, 100, 100, 400, 300)、editor.createShape(RECTANGLE, 150, 150, 120, 80)等 API 预置图形再用editor.zoomToFit()适配视口——这验证了createEditor返回对象上形状创建与视口动作的可用性。从 v0.14.0 迁移到当前开发版本如果你正在维护一个基于 v0.14.0 或更早版本构建的应用官方文档列出了升级到当前开发版本时需要注意的六类破坏性变更详见 SDK Getting Started场景图覆盖Scene Graph overrides把SceneNode.overrides记录替换为instanceOverrides其中self与descendants两个映射分别表达「实例级覆盖」与「后代节点覆盖」。请直接使用open-pencil/scene-graph公开的覆盖辅助函数如hasNodeInstanceOverride、setInstanceOverride、clearInstanceOverrides见 packages/scene-graph/src/instances.ts而不是把它当作简单的字段改名派生几何Derived geometry重命名figmaDerivedLayout→derivedLayoutfigmaDerivedTextGlyphs→derivedTextGlyphs导出的FigmaDerivedTextGlyph类型 →DerivedTextGlyph绑定提供者Binding providers实现getBindingId()并处理unresolved状态对edit-variable策略用prepareEdit()替代setValue()——prepareEdit会捕获编辑键、值、setter 与恢复回调。相关组件见 BindableValue翻译Translations用按产品域拆分的 composables 与目录如useSettingsMessages()、useRenameMessages()替换useDialogMessages()与dialogMessages。目录键也发生了迁移不能只改 import 名。详见 useI18nCanvasKit可变构造使用PathBuilder不可变Path操作的结果需要保留返回值而不是期待就地修改in-place mutation自定义工具使用 Valibot 原生的input模式与执行元数据替代旧的params、ParamDef、paramToZod()编程式 MCP 集成改用 MCP SDK v2 的 server/client 类型参考 MCP Server。下一步至此你已经掌握了 OpenPencil Vue SDK 的最小闭环安装 →createEditor→provideEditor→useCanvas→ composables 状态与命令。继续深入可以阅读以下文档与源码SDK 架构open-pencil/vue的目录组织、公开 API 边界与组合模式API 参考全部 composables 与无头原语useEditor访问当前注入的编辑器实例useCanvas画布渲染接线的完整选项useI18nSDK 本地化消息与语言切换实现源码packages/vue/src/index.ts公开 API 出口、packages/vue/src/editor/context/index.ts注入实现、packages/vue/src/canvas/surface/use.ts画布接线、packages/core/src/editor/create.ts引擎构造示例应用packages/vue/example/src/App.vue含工具栏、图层树与属性面板的完整编辑器外壳赞分享前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载相关推荐OpenPencil 的 useCanvasInput把指针事件接入编辑器画布的 Vue ComposableOpenPencil 的 useCanvasInput把指针事件接入编辑器画布的 Vue Composable 在 OpenPencil开源 AI 原生设计前端桌面应用AI 应用MCP 服务OpenPencil open-pencil/vue CanvasSurface 实战指南应用自持布局下的 SDK 画布渲染OpenPencil open pencil/vue CanvasSurface 实战指南应用自持布局下的 SDK 画布渲染 本文以官方 SDK 文档中的前端桌面应用AI 应用MCP 服务OpenPencil Vue SDK 深入解析用 useVariablesTable 构建响应式变量编辑器表格OpenPencil Vue SDK 深入解析用 useVariablesTable 构建响应式变量编辑器表格 OpenPencil 的 Vue SDK 提供前端桌面应用AI 应用MCP 服务上一篇ThingsBoard告警通知渠道Email、SMS与WebHook集成下一篇Glimmer.js构建与部署Webpack配置和CI/CD流水线最佳实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网