ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Open-Pencil 中 useSelectionCapabilities:用响应式能力位构建菜单、工具栏与快捷键

Open-Pencil 中 useSelectionCapabilities:用响应式能力位构建菜单、工具栏与快捷键 前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载useSelectionCapabilities()是open-pencil/vueSDK 提供的选择驱动能力查询组合式函数它基于当前场景选择状态暴露一组响应式布尔值用于判断删除、复制、创建组件、移动到页面、跳转主组件、缩放至选区等常见编辑器操作当前是否可用。本文以 packages/docs/programmable/sdk/api/composables/use-selection-capabilities.md 为骨架结合 packages/vue/src/editor/selection-capabilities/use.ts 的完整实现、命令定义 与 组合式函数索引 的上下文讲解如何在菜单、工具栏、快捷键、操作按钮与上下文面板中正确使用它并剖析其底层原理与全部能力位。一、它解决什么问题在设计编辑器类应用中大量 UI 元素需要根据当前选中的对象决定某个操作是否可执行。例如没有任何选中对象时删除、复制按钮应当置灰选中了 2 个及以上节点时编组才可用选中实例INSTANCE时跳转到主组件才有意义只有选中组件COMPONENT时创建实例才允许执行。如果在每个组件里都手动读取场景图scene graph再逐条判断代码会重复、分散且容易漏判。useSelectionCapabilities正是为此设计的它把选择状态 → 操作是否可用的派生逻辑集中收敛向 UI 层暴露命令友好的布尔值。官方文档给出的典型用途覆盖菜单menus工具栏toolbars键盘快捷键keyboard shortcuts操作按钮action buttons上下文面板contextual panels它位于 SDK 的 Selection and commands 能力族中与 useSelectionState 和 useEditorCommands 一起构成了选择驱动 UI 的完整工具箱。二、基本用法与返回值2.1 导入与解构从包入口导入并调用即可import { useSelectionCapabilities } from open-pencil/vue const caps useSelectionCapabilities()SDK 在 packages/vue/src/index.ts 中公开导出该组合式函数底层实现位于 packages/vue/src/editor/selection-capabilities/use.ts。2.2 文档示例一个最小操作栏官方文档提供了一个可直接运行的 Vue 单文件组件示例三个按钮分别受canDuplicate、canDelete、canCreateComponent控制script setup langts import { useSelectionCapabilities } from open-pencil/vue const { canDelete, canDuplicate, canCreateComponent } useSelectionCapabilities() /script template div classflex gap-2 button :disabled!canDuplicateDuplicate/button button :disabled!canDeleteDelete/button button :disabled!canCreateComponentMake component/button /div /template在 Vue 模板中ref/computed会被自动解包因此:disabled!canDelete直接读取计算值即可无需.value。三、完整能力位速查表虽然文档正文只显式列出 6 个布尔值但源码实现packages/vue/src/editor/selection-capabilities/use.ts实际暴露了 30 余个能力位。下表整理了每个能力位的语义与判定依据可直接作为开发参考能力位可用条件源码依据典型用途canCopy有选中对象hasSelection复制菜单项canCut有选中对象剪切菜单项canPaste恒为true粘贴菜单项canDelete有选中对象删除按钮canDuplicate有选中对象复制/原位复制canExportSelection有选中对象导出菜单canGroupselectedCount 2编组命令canFrameSelection有选中对象用 Frame 包裹选区canUngroup选中节点类型为GROUP取消编组canCreateComponent有选中对象创建组件canCreateComponentSet选中项 ≥ 2 且全部为COMPONENT创建组件集canDetachInstance选中节点为INSTANCE分离实例canWrapInAutoLayout有选中对象包裹为自动布局canToggleMask有选中对象切换蒙版canBringToFront有选中对象置顶canSendToBack有选中对象置底canToggleVisibility有选中对象显示/隐藏canToggleLock有选中对象锁定/解锁canFlip有选中对象水平/垂直翻转canDistributeeditor.canDistributeNodes(选中节点)为真分布对齐canBooleanOperation选中 ≥ 2 且全部可参与布尔运算布尔并/减/交/排除canFlatten选中节点均可转换为布尔源节点合并为单一形状canOutlineText选中全部为TEXT且可转换文本转路径canOutlineStroke选中全部含可见描边且可转换描边转路径canGoToMainComponent选中节点为INSTANCE跳转主组件canCreateInstance选中节点类型为COMPONENT创建实例canMoveToPage有选中对象且页面数 1移动到其他页面canSetOpacity有选中对象设置不透明度canSelectAll当前页面有子节点全选/反选canUndo矢量编辑态存在或撤销栈可用撤销canRedo矢量编辑态存在或重做栈可用重做canZoomToSelection有选中对象缩放至选区关键判定逻辑解读基于选择的位canCopy、canCut、canDelete、canDuplicate等一律由hasSelection派生见 packages/vue/src/editor/selection-state/use.ts而hasSelection是selectedIds.size 0。基于类型的位canUngroup依赖isGroupcanDetachInstance/canGoToMainComponent依赖isInstancecanCreateInstance检查selectedNode.value?.type COMPONENT这些类型判定同样来自useSelectionState。基于场景图的位canDistribute、canBooleanOperation、canFlatten、canOutlineText、canOutlineStroke、canMoveToPage、canSelectAll使用useSceneComputed在场景图层计算例如canMoveToPage要求editor.graph.getPages().length 1canSelectAll要求当前页存在子节点。基于历史的位canUndo/canRedo订阅history:changed事件并读取editor.undo且矢量编辑态nodeEditState下保持启用以保证快捷键能到达会话级历史源码注释明确说明此设计见 packages/vue/src/editor/selection-capabilities/use.ts。恒真位canPaste恒为true原因是剪贴板状态与选区无关粘贴可用性由剪贴板内容在命令执行时另行判断。四、实战场景菜单、快捷键与上下文面板4.1 用能力位门控菜单项菜单条目按能力位启用/禁用与命令模型天然契合const { canMoveToPage, canGoToMainComponent } useSelectionCapabilities()例如移动到页面条目仅在canMoveToPage为真时显示或可点击要求有选中对象且存在第二个页面跳转到主组件仅在选中实例时可用。4.2 只在有用时启用缩放命令缩放至选区Zoom to selection在无选中对象时没有意义直接由canZoomToSelection门控const { canZoomToSelection } useSelectionCapabilities()4.3 在编辑器命令模型中的角色能力位不只是给按钮用的它们直接喂给命令系统。在 packages/vue/src/editor/commands/use.ts 中useEditorCommands()内部同时调用useSelectionState()与useSelectionCapabilities()将能力位注入createEditorCommandMapconst capabilities useSelectionCapabilities() const commands createEditorCommandMap({ editor, selection, capabilities, messages: t, otherPages, moveSelectionToPage, getOpacityTarget: () opacityTarget })随后在 packages/vue/src/editor/commands/selection.ts 中每个选择类命令都用对应能力位作为enabled判定selection.duplicate: { id: selection.duplicate, get label() { return t.value.duplicate }, enabled: capabilities.canDuplicate, run: () editor.duplicateSelected() }, selection.delete: { id: selection.delete, get label() { return t.value.delete }, enabled: capabilities.canDelete, run: () editor.deleteSelected() }, selection.createComponent: { id: selection.createComponent, get label() { return t.value.createComponent }, enabled: capabilities.canCreateComponent, run: () editor.createComponentFromSelection() }命令定义由createEditorCommandMap汇总自edit、selection、view三组packages/vue/src/editor/commands/definitions.ts能力位因此统一驱动了菜单模型、快捷键与命令面板的可用状态——这也是文档推荐用命令而非裸调用构建 UI 的原因。4.4 与相关组合式函数的协作useSelectionState提供原始选择状态selectedIds、selectedNode、hasSelection、isInstance、isGroup等是能力位的输入基础useEditorCommands在能力位之上构建命令级接口供菜单/工具栏/快捷键直接调用。三者构成原始状态 → 能力位 → 命令执行的完整链路。五、实现原理从选择状态到能力位5.1 数据来源useSelectionCapabilities()内部首先获取选择状态const selection useSelectionState() const { editor, selectedIds, selectedNode, selectedCount, hasSelection } selectionuseSelectionState()的实现packages/vue/src/editor/selection-state/use.ts基于useEditor()获取编辑器实例并通过useSceneComputed订阅场景图变化const selectedIds useSceneComputed(() editor.state.selectedIds) const hasSelection computed(() selectedIds.value.size 0)因此只要选区变化所有依赖它的能力位都会自动重算并触发 UI 更新无需手动刷新。5.2 响应式与撤销历史的联动撤销/重做能力位需要感知历史状态变化源码通过shallowRef与编辑器事件实现const history shallowRef(editor.undo) useEditorEvent(history:changed, () triggerRef(history)) canUndo: useSceneComputed(() editor.state.nodeEditState ! null || history.value.canUndo), canRedo: useSceneComputed(() editor.state.nodeEditState ! null || history.value.canRedo)useEditorEvent由 SDK 公开导出packages/vue/src/index.tshistory:changed事件触发后通过triggerRef强制刷新引用从而联动更新canUndo/canRedo。5.3 场景图级能力位canBooleanOperation、canFlatten、canOutlineText、canOutlineStroke这类需要逐节点检查的位统一基于canMakeBooleanSourceNode判定——即节点能否作为布尔运算的源。例如canOutlineStroke还额外要求节点含可见描边canOutlineStroke: useSceneComputed(() { const nodes editor.getSelectedNodes() return ( nodes.length 0 nodes.every( (node) hasVisibleStrokeSourceNode(node, editor.graph) canMakeBooleanSourceNode(node, editor.graph) ) ) })canDistribute则直接调用编辑器能力判定canDistribute: useSceneComputed(() editor.canDistributeNodes([...editor.state.selectedIds]))这些实现展示了能力位的通用设计模式简单位走选区派生复杂位走场景图查询统一以computed/useSceneComputed暴露为响应式布尔值。六、配套资源与延伸阅读组合式函数总览Composables 索引原始选择状态useSelectionState命令级接口useEditorCommands命令定义能力位的消费方packages/vue/src/editor/commands/selection.ts菜单模型useMenuModelVue SDK 架构说明packages/vue/ARCHITECTURE.md 与 packages/vue/README.md七、使用要点小结选择后即用useSelectionCapabilities()必须在提供编辑器上下文的子树内调用其内部依赖useEditor()/useSelectionState()解构即用返回的每个布尔值都是响应式的直接绑定:disabled、v-if或命令的enabled即可优先走命令层菜单、工具栏、快捷键尽量复用useEditorCommands的命令体系能力位已自动接入命令的enabled判定无需手动同步选区、场景图、撤销历史变化会自动触发能力位重算UI 始终保持一致。赞分享前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载相关推荐open-pencil useEditorCommands 详解用命令层驱动菜单、工具栏与快捷键交互open pencil useEditorCommands 详解用命令层驱动菜单、工具栏与快捷键交互 本文围绕 open pencilAI native 设前端桌面应用AI 应用MCP 服务open-pencil open-pencil/vue 中的 ToolbarRoot为设计编辑器构建 Headless 工具栏原语open pencil open pencil/vue 中的 ToolbarRoot为设计编辑器构建 Headless 工具栏原语 ToolbarRoot前端桌面应用AI 应用MCP 服务NodeGui QAction 完全指南用 Node.js 与 CSS 构建跨平台桌面应用中的菜单、工具栏与快捷键动作NodeGui QAction 完全指南用 Node.js 与 CSS 构建跨平台桌面应用中的菜单、工具栏与快捷键动作 QAction 是 NodeGui 中桌面应用跨平台上一篇一张消费级4090跑Qwen3-235B-A22B-Thinking-2507这份极限“抠门”的量化与显存优化指南请收好下一篇突破2350亿参数模型的实时交互瓶颈Qwen3-235B-A22B-Thinking-2507-FP8的KV缓存与PagedAttention优化实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表