首页/新闻资讯/正文详情

useNodeProps:OpenPencil 属性面板的底层多选与混合值工具箱

发布时间:2026/9/26 10:21:20 来源:云帆数科 栏目:资讯中心
useNodeProps:OpenPencil 属性面板的底层多选与混合值工具箱
前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载useNodeProps()是 OpenPencil 中属性面板Property Panel家族的底层助手组合式函数composableuseAppearance、useLayout、useTypography等高层组合式函数均建立在它之上。本文围绕它要解决的四个核心问题展开混合值mixed-value检测、多选节点批量更新、数组型属性fills / strokes / effects的条目编辑、以及支持撤销undo的预览 提交分离语义并结合open-pencil/vue源码剖析其底层实现。读完本文你将能够使用useNodeProps为自定义属性面板接入多选感知的状态与提交逻辑。为什么需要 useNodeProps在设计工具中属性面板总是要面对同一个复杂场景用户选中了一个节点或者同时选中了多个节点面板需要检测混合值——多个选中节点上同一属性取值不一致时面板应显示混合MIXED占位而不是某个节点的具体值批量更新——对多个选中节点同时应用同一个属性变更编辑数组属性——修改fills填充、strokes描边、effects效果数组中某一项或删除、切换某项的可见性撤销感知的提交——拖动数值时先实时预览不产生撤销记录松手时再统一提交为一条可撤销的历史条目。这些逻辑如果由每个面板重复实现会带来大量重复代码和一致性问题。OpenPencil 将它们集中到了packages/vue/src/controls/node-props/use.ts的useNodeProps()与packages/vue/src/controls/node-props/helpers.ts中并通过packages/vue/src/index.ts第 32 行对外导出useNodeProps与MIXED。使用场景判定原文档明确指出当你的自定义面板需要以下能力时应该使用useNodeProps()检测混合值mixed-value detection多选更新multi-selection updates数组条目编辑array-item editing撤销感知的属性提交undo-aware property commits。这些能力覆盖了几乎所有属性面板的底层需求。useNodeProps不关心具体是哪个属性域外观、布局还是排版它只负责选区状态 属性读写 撤销提交这一通用底座。API 速览useNodeProps()返回一组由选区派生的响应式状态与动作。以下是完整返回值列表对应 use.ts 的返回对象返回值类型/含义说明storeEditor编辑器实例来自useEditor()注入nodeRefSceneNode \| null当前激活节点单选时即选中节点nodesRefSceneNode[]当前选中的全部节点isMultiComputedRefboolean是否多选nodes.value.length 1activeComputedRefboolean是否存在可编辑选区有节点或多选activeNodeComputedRefSceneNode \| null单选的节点或多选时的第一个节点targetNodes() SceneNode[]数组动作实际作用的节点列表prop(key)ComputedRefMixedValueT某属性的合并merged值多选不一致时返回MIXEDmerged(key)MixedValueT非响应式的合并值读取函数updateAllWithUndo(patch, label)函数对全部选中节点批量打补丁并记入撤销updateArrayItem(key, index, patch, label)函数更新数组属性中某一项removeArrayItem(key, index, label)函数移除数组属性中某一项toggleArrayVisibility(key, index)函数切换数组条目visible标志isArrayMixed(key)boolean数组属性在多选中是否混合updateProp(key, value)函数实时更新scrub单属性不产生撤销记录commitProp(key, value, previous)函数提交属性变更写入撤销历史另外还导出了两个类型级能力MIXED哨兵符号表示多个节点取值不一致定义于 helpers.tsMixedValueTT | typeof MIXED的联合类型。混合值检测MIXED 哨兵与 merged混合值检测由createNodePropSelectionState实现。核心逻辑在 helpers.tsfunction mergedK extends keyof SceneNode(key: K): MixedValueSceneNode[K] { const all nodes.value if (all.length 0) return MIXED // 无选区 → 混合占位 const first all[0][key] for (let i 1; i all.length; i) { if (all[i][key] ! first) return MIXED // 任一节点不一致 → 混合占位 } return first }实现要点无选区时直接返回MIXED面板据此渲染占位状态多选时逐一比对第一个节点之后的每个节点只要有一处不一致就整体返回MIXEDprop(key)在此基础上包了一层computed()得到响应式的混合值引用可直接绑定到模板。数组属性的混合检测对于fills、strokes、effects这类数组属性普通的!比较无法捕获长度相同但内容不同的情况。isNodeArrayMixedhelpers.ts做了深度比较长度不同的数组直接判定混合长度相同的数组逐项调用areArrayItemsEqual递归比较支持嵌套对象与嵌套数组非数组属性则退回逐节点!比较。useNodeProps()将其暴露为isArrayMixed(key)面板可以据此决定是否禁用某项编辑或显示混合占位。多选批量更新updateAllWithUndoupdateAllWithUndo对nodes.value中每一个节点调用store.updateNodeWithUndo(n.id, patch, label)helpers.ts。底层实现位于 packages/core/src/editor/nodes.ts。updateNodeWithUndo的核心流程是通过styleDetachmentChanges、textAutoResizeChanges、pathTextEditChanges对补丁做二次处理例如路径文本的重排字形优先级pick出变更前每个被改动属性的旧值previousctx.graph.updateNode(id, nextChanges)应用新值并runLayoutForNode重排布局ctx.undo.push写入一条带label、包含forward/inverse的撤销记录ctx.requestRender()触发重绘。因此面板里一键把所有选中节点的不透明度设为 50%这类操作会自然产生一条可撤销的单一历史记录且撤销后布局会正确重排。数组条目编辑更新、删除与可见性切换createNodePropArrayActionshelpers.ts封装了三个数组操作全部作用于targetNodes()多选时为全部选中节点单选时为激活节点updateArrayItem更新第 index 项function updateArrayItem(key, index, patch, label) { for (const n of targetNodes()) { const arr [...n[key]] arr[index] { ...arr[index], ...patch } store.updateNodeWithUndo(n.id, { [key]: arr }, label) } }它通过不可变更新先拷贝数组再替换目标项保证不触发意外的响应式副作用例如修改填充颜色或描边线宽时可传入{ color: ... }这类局部补丁。removeArrayItem删除第 index 项用filter生成去掉目标项的新数组后提交同样经过updateNodeWithUndo因此删除操作可撤销。toggleArrayVisibility切换条目可见性对数组第index项翻转visible标志撤销标签固定为Toggle ${key} visibility。updateArrayItem与removeArrayItem的第三个/第二参数label会作为撤销记录的标签建议使用有语义的中文或英文描述例如Change fill方便用户在历史面板中识别。预览与提交分离updateProp / commitProp数值型控件拖动 scrub通常需要拖动过程中实时预览、松手时一次性提交为一条撤销记录。createNodePropScrubActionshelpers.ts实现了这套语义updateProp(key, value)只调用store.updateNode不带撤销记录用于拖动过程的实时预览多选时先用previousValuesMap 记录每个节点修改前的原始值避免后续提交时丢失各节点各自的起点commitProp(key, value, previous)调用store.commitNodeUpdate写入撤销历史多选时逐节点用各自记录的previous作为撤销逆操作的还原值提交后清空缓存。底层commitNodeUpdate定义于 packages/core/src/editor/undo.ts它会重新pick当前值若与还原值相等则跳过避免空撤销记录否则 push 一条forward/inverse成对的记录。注意undo.ts的commitNodeUpdate同时被 bridges/undo.ts 以undoActions.commitNodeUpdate的形式暴露给编辑器桥接层。因此一个典型的数值输入框可以这样接线const { updateProp, commitProp, prop } useNodeProps() // 拖动过程中实时预览不写撤销 updateProp(opacity, 0.6) // 松手时提交为一条可撤销记录 commitProp(opacity, 0.6, 0.5)多选场景下这套先记录旧值、再统一提交的设计保证每个节点都能正确回到各自的初始值而不是退回到某一个节点的旧值。在高层组合式函数中的应用useNodeProps是高层组合式函数的底座。例如useAppearancepackages/vue/src/controls/appearance/use.ts直接解构了nodes、node、active、isMulti、merged、updateProp、commitProp再叠加外观领域专属的createAppearanceState/createAppearanceActionsexport function useAppearance() { const editor useEditor() const { nodes, node, active, isMulti, merged, updateProp, commitProp } useNodeProps() const appearanceState createAppearanceState({ node, nodes, isMulti, merged, ... }) const appearanceActions createAppearanceActions({ editor, ... }) return { editor, nodes, node, active, isMulti, ...appearanceState, updateProp, commitProp, ...appearanceActions } }useLayoutpackages/vue/src/controls/layout/use.ts同样构建在选区状态之上只是它更多使用createLayoutSelectionState等布局专属 helper并在内部共享updateProp/commitProp的命名约定。从 SDK 架构文档 可以看出controls/目录中usePosition、useLayout、useAppearance、useTypography、useNodeProps、usePropScrub等组合式函数共同组成了属性面板的控制层open-pencil/vue只负责编辑器集成与无样式可复用的逻辑不持有编辑器模型本身。这种底层通用底座 领域专属动作的分层使得新增一个属性面板时只需关注领域逻辑多选、混合值、撤销等横切关注点全部由useNodeProps兜底。相关 APIuseAppearance——外观可见性、不透明度、圆角领域的面板组合式函数useLayout——布局flex/grid、尺寸、内边距、对齐、轨道领域的面板组合式函数useTypography——排版领域的面板组合式函数usePropScrub——更底层的拖动 scrub 提交辅助PropertyListRoot——属性列表的结构化根组件。赞分享前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载相关推荐open-pencil SDK 深度解析useNodeProps 属性面板 Composable 的混合值检测、多选更新与撤销感知提交open pencil SDK 深度解析useNodeProps 属性面板 Composable 的混合值检测、多选更新与撤销感知提交 useNodeProp前端桌面应用AI 应用MCP 服务PaddleSpeech s2t frontend utility 模块全解词典、Manifest、CMVN 与音频数值处理的底层工具箱PaddleSpeech s2t frontend utility 模块全解词典、Manifest、CMVN 与音频数值处理的底层工具箱 导读 PaddleS人工智能语音音频CADmium底部面板属性编辑与历史记录CADmium底部面板属性编辑与历史记录 概述 CADmium作为一款现代化的浏览器端CADComputer Aided Design计算机辅助设计软件3D建模前端图形学WebAssembly桌面应用上一篇Windows 11终极瘦身指南免费开源工具让你的系统性能飙升51%下一篇在Mac桌面打造沉浸式音乐体验LyricsX 2.0深度解析与实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

AI代码神器全解析:从50K星标到自主完成重构实战
AI代码神器全解析:从50K星标到自主完成重构实战

上个月我用AI代码神器做了一个原本需要三天的重构任务,最后半天就拿到了可运行的版本。当时第一反应是:这玩意儿为什么现在才火。GitHub上50K星标,一点水分都没有。市面上的AI编程助手我基本都摸过一圈,有的只能帮你补几个单词&am… · 2026/9/26 10:21:20

dsh-plugin-subscriptions安装指南:版本匹配与headless配置
dsh-plugin-subscriptions安装指南:版本匹配与headless配置

只要装过一次 dsh-plugin-subscriptions,你就知道这个看着不大的插件能卡掉多少人。明明核心服务已经起来了,插件却总是报版本不匹配;换一台机器再装,又可能栽在安装路径上;等你终于装好,想用 headless 模式… · 2026/9/26 10:21:14

Codex桌面版打不开?三层结构排查法解决启动失败与登录异常
Codex桌面版打不开?三层结构排查法解决启动失败与登录异常

1. 桌面版启动失败到底卡在哪一层Codex 桌面版打不开,绝大多数人第一反应是"重装"。我见过太多人把安装包删了又下、下了又装,折腾一下午还是卡在启动画面或者干脆闪退。问题在于,桌面版这类工具本质上是"外壳 本地服务 账号… · 2026/9/26 10:21:14

视频短剧SAAS系统源码实战:从多租户架构到小程序部署与避坑
视频短剧SAAS系统源码实战:从多租户架构到小程序部署与避坑

简介:一套2024年新版视频短剧SAAS系统源码,适用于影视短剧创业者、独立开发者及需要快速搭建小程序/公众号H5分销平台的运营团队。系统采用SaaS架构设计,核心功能覆盖微信小程序与公众号H5双端,支持分销商等级自定义、二级分销、V… · 2026/9/26 11:31:40

基于MediaPipe的浏览器端微笑举重体感游戏实现详解
基于MediaPipe的浏览器端微笑举重体感游戏实现详解

你是否在短视频或直播间里刷到过这样的画面:一个人对着镜头咧嘴笑,屏幕里的角色就吭哧吭哧把杠铃举了起来,笑得越开心,杠铃升得越高,脸一垮杠铃又落回地面。这种把表情变成游戏操作的设计,本质上就是一个“… · 2026/9/26 11:31:40

用表情识别做体感游戏:摄像头+AI实现“表情举重2026”
用表情识别做体感游戏:摄像头+AI实现“表情举重2026”

1. 这篇文章真正要解决的问题2025年前后,“体感游戏”这个词开始变味了。过去提起体感,第一反应是主机生态里的昂贵配件:能捕捉深度信息的设备、专门的主机、宽敞的客厅空间、动辄几百元的游戏卡带。这套方案的体验确实好,但门槛也… · 2026/9/26 11:31:40

CNN+Transformer+特征融合:从原理到PyTorch实验方法论
CNN+Transformer+特征融合:从原理到PyTorch实验方法论

这次我们直接聊一个学术写作中很实用的“组合方法论”:CNN Transformer 特征融合。这个组合不是某个特定开源项目的名字,而是一套高频出现在顶会论文里的研究范式。很多做计算机视觉、多模态、时序预测或者医学影像分析的读者,应该已经注意… · 2026/9/26 11:31:40

CNN+Transformer+特征融合:深度学习论文实验设计与PyTorch实现指南
CNN+Transformer+特征融合:深度学习论文实验设计与PyTorch实现指南

这次我们不聊某个开源模型的一键部署,而是聊一个更偏研究向的组合思路: CNN Transformer 特征融合 。最近两三年,这个组合在图像分类、目标检测、医学影像、遥感、时序预测里反复出现。你会发现很多工作并没有发明全新的网络结构&#xf… · 2026/9/26 11:31:40

共享办公工位毫米波雷达人体存在检测方案
共享办公工位毫米波雷达人体存在检测方案

1. 项目概述:为什么共享办公空间需要毫米波雷达做人体存在检测?“共享办公工位毫米波雷达实现人体存在检测方案设计”——这个标题里藏着三个关键信号:共享办公、工位级精度、毫米波雷达。它不是在讲一个泛泛的“有人/没人”开关,… · 2026/9/26 11:31:34

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码