前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载useTextEdit()是 OpenPencilAI-native 设计编辑器、开源 Figma 替代品Vue SDK 中连接 DOM 文本输入与画布文本编辑模型的组合式 APIcomposable。它在画布所有者组件中配合useCanvas()与useCanvasInput()使用统一管理隐藏textarea输入、IME 组合、光标闪烁、删除/退格行为、加粗/斜体/下划线格式化命令以及将文本与样式运行style runs的变更写回 SceneGraph。读完本文你将掌握该组合式的调用方式、内部实现链路源码级证据、快捷键与 IME 兼容原理以及如何在自定义编辑器壳中正确集成它。概览它解决什么问题在网页环境中CanvasKit 渲染的画布本身无法接收系统键盘输入也无法直接运行中文、日文等输入法IME的组合流程。OpenPencil 的useTextEdit()正是这座桥梁它通过一个隐藏的textarea承接真实 DOM 输入事件再把文本变更转换为对编辑器模型的操作最后同步回场景图SceneGraph中的文本节点。它在 packages/vue/src/index.ts 中作为 Vue SDK 的公开 API 导出export { useTextEdit } from #vue/canvas/text-edit/use文档明确其定位use-text-edit.md 指出它协调以下职责基于 textarea 的文本输入textarea-backed text inputIME 组合composition光标闪烁caret blinking删除/退格行为delete/backspace behavior加粗/斜体/下划线等格式化命令formatting commands将文本变更同步回场景图syncing text changes back into the graph同时文档强调这是画布/编辑器集成类组合式而不是通用文本域组合式“a canvas/editor integration composable, not a generic text-field composable”。它不应被用来驱动普通的表单输入框。用法在画布所有者组件中调用基础调用签名与英文版文档 use-text-edit.md 及德文原文档一致useTextEdit(canvasRef, editor)它应当在包含画布canvas的组件中使用通常与useCanvas()和useCanvasInput()搭配。最小示例script setup langts import { ref } from vue import { useCanvas, useCanvasInput, useEditor, useTextEdit } from open-pencil/vue const canvasRef refHTMLCanvasElement | null(null) const editor useEditor() // 1) 将 Editor 绑定到真实 canvas 元素CanvasKit 渲染、surface 创建、resize 调度 useCanvas(canvasRef, editor) // 2) 绑定指针/鼠标交互选择、拖拽、缩放、旋转、平移、笔刷、文本编辑交互、命中测试 useCanvasInput( canvasRef, editor, editor.hitTestSectionTitle, editor.hitTestComponentLabel, editor.hitTestFrameTitle, ) // 3) 绑定 DOM 文本输入与画布文本编辑模型 useTextEdit(canvasRef, editor) /script template canvas refcanvasRef classsize-full / /templateuseCanvas()负责 CanvasKit 初始化、surface 创建、渲染调度、resize 处理与可选的标尺显示详见 use-canvas.mduseCanvasInput()负责指针输入、选择、拖拽、缩放、旋转、平移、钢笔/绘制流程、文本编辑交互与作用域感知的命中测试详见 use-canvas-input.md。三者共同构成一个完整的画布编辑器壳。类型签名与可选参数从源码 use.ts 可以确认实际签名export function useTextEdit( canvasRef: RefHTMLCanvasElement | null, store: Editor, options?: { isEnabled?: () boolean } )第三个可选参数options.isEnabled是一个返回布尔值的函数用于控制文本编辑会话是否启用。从 textarea.ts 的useTextEditingSession可以看到它会在每次会话建立时被读取当isEnabled()返回false时即使存在editingTextId也不会创建隐藏 textarea。在哪里使用参考实现位于packages/vue/src/canvas/text-edit/use.ts。这是组合式的唯一实现入口内部将职责拆分为多个模块textarea.ts—— 隐藏 textarea 的创建/聚焦与会话生命周期editing.ts—— 文本编辑动作插入、删除、IME 组合草稿、光标闪烁keyboard.ts—— 键盘事件处理导航、元键快捷键、Enter、Backspace/Deleteformatting.ts—— 加粗/斜体/下划线格式化动作clipboard.ts—— 复制/剪切/粘贴input.ts、navigation.ts—— 输入与导航辅助深入原理useTextEdit 的内部实现链路组合式在挂载时完成以下装配对应 use.ts创建textareaRefshallowRefHTMLTextAreaElement | null创建光标闪烁控制器createCaretBlink(store)返回resetBlink与stopBlink创建文本编辑动作createTextEditActions(store)返回getEditingNode、insertText、replaceComposedText、restoreComposition、finishComposition、deleteText创建格式化动作createTextFormattingActions(store)返回toggleBold、toggleItalic、toggleUnderline创建剪贴板动作createTextClipboardActions(...)返回handleCopy、handleCut、handlePaste创建 IME 组合处理器createTextCompositionHandlers(...)返回isComposing及各 composition/input 回调创建键盘处理器createTextKeyDownHandler(...)注册事件监听textareaRef上的input、compositionstart、compositionupdate、compositionend、keydown以及canvasRef上的mousedown用于在画布指针按下时重新聚焦 textarea启动useTextEditingSession监视editingTextId变化以建立/销毁编辑会话。隐藏 textarea 与编辑会话createHiddenTextArea()textarea.ts创建一个不可见的辅助元素const textarea document.createElement(textarea) textarea.setAttribute(aria-hidden, true) textarea.tabIndex -1 textarea.className fixed left-0 top-0 h-px w-px opacity-0 document.body.appendChild(textarea)关键点aria-hiddentrue与tabIndex -1保证辅助技术屏幕阅读器和 Tab 导航都不会感知到它fixed left-0 top-0 h-px w-px opacity-0使它占据 1 像素、完全透明不会干扰布局与视觉它直接挂载到document.body独立于组件 DOM 树。useTextEditingSessiontextarea.ts通过watch监听store.state.editingTextId当进入文本编辑态存在editingTextId且isEnabled未禁用时创建隐藏 textarea、赋值给textareaRef、调用el.focus()抢焦点、resetBlink()启动光标闪烁注册清理函数stopBlink()停止闪烁、el.remove()移除 textarea、textareaRef.value null、resetComposition()清空 IME 组合状态。画布上的mousedown处理则保证交互不中断只要当前处于文本编辑态且 textarea 存在就在下一帧requestAnimationFrame重新聚焦 textareatextarea.ts避免用户点击画布后键盘事件丢失。文本动作与 SceneGraph 同步createTextEditActionsediting.ts是所有文本写操作的统一出口getEditingNode()通过store.state.editingTextId从store.graph.getNode(id)取当前编辑节点syncText(nodeId, text, runs?)构造{ text, styleRuns? }变更调用store.updateTextEditNode(nodeId, changes)写回编辑器模型随后用更新后的节点重建段落store.textEditor?.rebuildParagraph(updated)并触发重渲染store.requestRender()insertText(text, node)读取当前选区先对styleRuns做删除/插入区间调整adjustRunsForDelete/adjustRunsForInsert来自open-pencil/core/text再执行editor.insert(text, node)并同步文本deleteText(node, forward)按选区或光标位置调整 runsforward 时调用editor.delete(node)Delete 键否则调用editor.backspace(node)Backspace 键。这里的关键设计是文本内容的修改和样式运行style runs的区间调整是同步完成的。也就是说当用户在一个加粗选区中间插入字符时插入点前后的粗体 runs 会被正确拆开、扩展而不是丢失格式。光标闪烁createCaretBlinkediting.ts使用useIntervalFn来自 vueuse/core以530ms为周期切换store.textEditor.caretVisible并调用store.requestRepaint()触发画布重绘const CARET_BLINK_MS 530resetBlink()在每次文本变更后执行先将caretVisible置为truepause()后立刻resume()从而重置闪烁周期——保证输入时光标保持可见停顿后才开始闪烁。IME 组合中文、日文输入法的兼容机制IME 兼容是网页画布编辑器最容易翻车的环节。createTextCompositionHandlersediting.ts实现了完整的组合生命周期compositionstart置isComposing true清空“提交后跳过输入”标记compositionupdate在组合中每次候选词变化都会用replaceComposedText(e.data)把当前候选文本渲染到画布即时预览compositionend读取 textarea 的最终值作为提交文本若非空则replaceComposedText后finishComposition()并设置skipCommittedInput { text: finalText, until: Date.now() 250 }若为空则restoreComposition(node)恢复组合前的原文input事件处理onInput若处于组合中直接更新组合文本否则将 textarea 值作为普通输入插入。关键的去重逻辑是250ms 的skipCommittedInput窗口——有些浏览器在compositionend之后还会补发一个input事件若不跳过会导致文本被重复插入。组合草稿CompositionDraft记录组合开始时的baseText、baseRuns、光标位置与选区editing.ts。组合期间每次候选变化都在草稿基础上重算baseText.slice(0, start) text baseText.slice(end)同时用adjustRunsForDeleteadjustRunsForInsert维护样式运行。若组合被取消restoreComposition将文本、光标、选区与 runs 完整还原。同时键盘处理器在组合期间会直接短路if (options.isComposing()) returnkeyboard.ts避免方向键、退格等快捷键干扰输入法状态。键盘编辑行为与格式化快捷键createTextKeyDownHandlerkeyboard.ts在keydown上实现完整的编辑键盘行为按键行为Escape提交文本编辑store.commitTextEdit()焦点还给画布Enter插入换行符\n多行文本Backspace/Delete先按导航逻辑扩展删除选区extendSelectionForDeletion再删除文本方向键等导航键交给handleNavigationKey(e, editor)来自navigation.ts处理光标移动与选区扩展Meta/Ctrl 组合匹配metaKeyActions表元键动作表metaKeyActions以e.code为键const metaKeyActions: PartialRecordstring, MetaAction { KeyA: () options.store.textEditor?.selectAll(), // 全选 KeyC: () options.handleCopy(), // 复制 KeyX: (node) options.handleCut(node), // 剪切 KeyV: (node) void options.handlePaste(node), // 粘贴 KeyB: (node) options.toggleBold(node), // 加粗 KeyI: (node) options.toggleItalic(node), // 斜体 KeyU: (node) options.toggleUnderline(node), // 下划线 }文档特别指出这些格式化快捷键在文本编辑激活时由useTextEdit()直接处理无需额外接入“useTextEdit()already handles keyboard formatting actions like bold, italic, and underline while text editing is active”。格式化动作的两种模式createTextFormattingActionsformatting.ts展示了编辑器对选区与整体状态的统一处理当存在文本选区时调用open-pencil/core/text的区间工具toggleBoldInRange、toggleItalicInRange、toggleDecorationInRange只修改选区覆盖的 style runs并通过store.updateNodeWithUndo(nodeId, changes, label)进入撤销栈无选区时则切换节点级默认样式fontWeight 700 ? 400 : 700、italic取反、textDecoration在UNDERLINE/NONE间切换。三个动作的撤销标签分别为Toggle bold、Toggle italic、Toggle underline保证用户可以在历史记录中逐条回退。每次格式化后同样执行rebuildParagraphrequestRender刷新画布。同步保证文本与样式运行实时写回场景图文档强调的核心承诺是在用户输入或编辑格式化区间的过程中实时更新图的文本与样式运行“It updates graph text and style runs as the user types or edits formatted ranges”。从源码看这一承诺由两层保证编辑器模型层syncText调用store.updateTextEditNode(nodeId, { text, styleRuns })将新文本与调整后的 runs 一次性写入编辑器状态editing.ts渲染层每次同步后调用store.textEditor?.rebuildParagraph(updated)重建段落布局含换行、字形排版并store.requestRender()调度画布重绘。这意味着画布上的字形是跟着按键即时更新的而不是在退出编辑态时一次性提交。同时syncText走updateTextEditNode而非updateNodeWithUndo说明编辑过程中的每一次中间状态都不进入撤销栈——只有通过格式化动作或commitTextEdit()提交的变更才形成可撤销的历史记录。这一细节对于理解编辑器历史undo/redo语义很重要。与 useCanvas、useCanvasInput 的分工useTextEdit()是三层画布集成中最内层的一环useCanvas(canvasRef, editor, options?)是渲染层负责 CanvasKit 初始化、surface 创建、渲染调度、resize 处理、可选标尺与渲染器就绪回调onReady。实践提示嵌入式预览可设showRulers: false截图场景可设preserveDrawingBuffer: true见 use-canvas.mduseCanvasInput(canvasRef, editor, ...hitTestFns, onCursorMove?)是交互层负责选择、拖拽、缩放、旋转、平移、钢笔/绘制流程、文本编辑交互与作用域感知命中测试见 use-canvas-input.mduseTextEdit(canvasRef, editor, options?)是文本编辑层负责 DOM 输入桥接、IME、光标、删除、格式化与 SceneGraph 同步。典型装配顺序先useCanvas()绑定渲染再useCanvasInput()绑定指针交互最后useTextEdit()接通文本输入。三者共享同一个canvasRef与同一个Editor实例通过useEditor()从组件上下文获取见 index.ts。注意事项与最佳实践定位是画布集成而非通用输入框文档明确useTextEdit()是 canvas/editor integration composable不适用于普通表单文本域。需要真实canvas元素canvasRef必须指向实际渲染的canvasuseCanvas()完成 CanvasKit surface 绑定后文本编辑会话才能正确建立。isEnabled用于条件禁用如果需要按应用状态如只读模式、预览模式关闭文本编辑传入options.isEnabled返回false即可会话 watcher 会在禁用时跳过 textarea 的创建textarea.ts。IME 输入时避免干预组合期间键盘处理器会短路外部不应在compositionstart–compositionend之间注入文本或快捷键。格式化走撤销栈中间输入不进历史updateNodeWithUndo用于格式化动作updateTextEditNode用于编辑中的中间同步理解这一区别有助于设计自定义撤销/重做逻辑。不要重复监听 textarea 事件useTextEdit()内部已通过useEventListener注册了input、composition*、keydown外部再监听同一元素会触发双重处理use.ts。相关 APIuseCanvas —— 渲染层将 Editor 绑定到canvas元素useCanvasInput —— 交互层指针、选择、拖拽、缩放、旋转、平移与文本编辑交互useEditor —— 从 Vue 上下文获取共享 Editor 实例参考实现路径组合式入口use.ts隐藏 textarea 与会话生命周期textarea.ts编辑动作、IME 组合与光标闪烁editing.ts键盘处理keyboard.ts格式化动作formatting.ts剪贴板动作clipboard.tsSDK 公开导出index.ts官方 API 文档use-text-edit.md另有 德文版、法文版 等多语言版本赞分享前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载相关推荐OpenPencil Vue SDK 画布文本直编详解useTextEdit 组合式函数的工作原理与集成指南OpenPencil Vue SDK 画布文本直编详解useTextEdit 组合式函数的工作原理与集成指南 useTextEdit 是 OpenPencil前端桌面应用AI 应用MCP 服务OpenPencil Vue SDK 的 useCanvasDrop为画布接入文件与组件拖放导入OpenPencil Vue SDK 的 useCanvasDrop为画布接入文件与组件拖放导入 useCanvasDrop 是 OpenPencil 的 前端桌面应用AI 应用MCP 服务OpenPencil 的 useCanvasInput把指针事件接入编辑器画布的 Vue ComposableOpenPencil 的 useCanvasInput把指针事件接入编辑器画布的 Vue Composable 在 OpenPencil开源 AI 原生设计前端桌面应用AI 应用MCP 服务创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
免费商用字体大合集整理:10 大分类 1061 个字体,再也不怕版权侵权 附下载 为什么需要一份免费商用字体合集
你有没有过这样的经历:熬夜赶完一份 PPT,满心欢喜发给甲方,结果对方一句「这个字体有版权,不能用」直接打回重做,甚至还要赔侵权费。做设计、做 PPT、做海报、开发网页或者做自媒体的… · 2026/9/27 2:36:17
用Kindel看微信读书(3)---KOreader安装微信读书插件 阅读器KOreader的微信读书插件安装,主要分三个步骤:
一是下载并安装微信插件,二是Kindle微信读书登录认证,三是使用KOreader阅读微信读书。
一、下载并安装微信插件
Kindle微信读书主流的插件有2个:weread 插件… · 2026/9/27 2:36:17
BP神经网络空中目标航迹预测:从数据预处理到训练验证的工程实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 2:35:52
Visual C++ 14.0 以上版本安装包:解决 Python 包编译失败与运行时缺失 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 3:23:56
RK3566泰山派LVGL深度适配:硬件驱动、交叉编译与DCU直驱实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 3:23:50
瑞芯微RV1126B SDK移植实战:从DDR配置到USB调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 3:23:50
消费品BI选型PoC设计:贴合核心业务场景的验证方案 导语
消费品行业正在从增量竞争转向存量竞争,越来越多企业希望通过BI搭建敏捷数据能力支撑精细化运营,但在选型过程中,PoC(概念验证)环节往往容易走形式,要么只测通用功能不贴合核心业务,要么没… · 2026/9/27 3:23:38
告别拖延症:网站优化知识速查手册,3步搞定核心瓶颈 告别拖延症:网站优化知识速查手册,3步搞定核心瓶颈 改个需求建站公司拖一周,后台数据跌得你心惊肉跳,这种憋屈感创业团队负责人最懂。别急着换供应商,很多时候不是人不行,是你没给对“说明书”。今天这份 网站优化知识… · 2026/9/27 3:23:38
朱雀仿宋笔形细节大赏:重心、中宫、撇捺与粗细对比的仿宋设计逻辑 朱雀仿宋笔形细节大赏:重心、中宫、撇捺与粗细对比的仿宋设计逻辑 【免费下载链接】朱雀仿宋 开源仿宋字库计划 项目地址: https://gitcode.com/TrionesType/zhuque
朱雀仿宋(Zhuque Fangsong)是璇玑造字推出的开源仿宋字体࿰… · 2026/9/27 3:23:38
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01