
前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载useNodeFontStatus是 Open-Pencil Vue SDK 提供的一个轻量级响应式 composable用于检查文本节点text node当前引用的字体家族在运行时是否已经加载并返回缺失字体的家族列表。它主要服务于字体属性面板Typography 面板与“缺失字体”警告类 UI是 Open-Pencil 作为 AI 原生设计编辑器在「字体异步加载 属性面板实时反馈」场景下的关键工具。读完本文你将掌握该 composable 的签名、返回值、底层实现原理、与useTypography/TypographyControlsRoot的集成方式以及如何基于FontManager自己实现缺失字体检测与加载触发。1. 为什么需要“缺失字体检测”在 Open-Pencil 这类浏览器内渲染的设计编辑器中字体尤其是用户导入、远端注册的字体是异步加载的节点可以引用某个字体家族但该家族的字形数据可能尚未到达运行时。此时文本渲染可能使用替代字体substitute兜底用户在字体面板里看到的家族并不代表它真正可用导出、协作预览等流程需要感知字体状态避免结果与设计稿不符。useNodeFontStatus(node)正是为这一需求设计的接收一个文本节点 getter响应式地返回该节点所引用、但尚未加载完成的字体家族集合。官方文档明确指出它应被用于排版面板typography panels以及需要暴露不可用字体家族的警告场景见 use-node-font-status.md。2. 接口签名与返回值依据源码 packages/vue/src/shared/font-status/use.ts其类型签名可归纳为export function useNodeFontStatus( node: () SceneNode | null | undefined ): { missingFonts: ComputedRefstring[] hasMissingFonts: ComputedRefboolean }关键点成员类型含义node参数() SceneNode \| null \| undefined一个返回目标节点的getter 函数而不是节点本身。这是响应式设计的关键composable 内部基于该 getter 建立computed当选中节点变化时缺失字体状态自动重新求值missingFontsComputedRefstring[]缺失的字体家族名数组已去重非 TEXT 节点时为[]hasMissingFontsComputedRefbooleanmissingFonts.length 0的布尔快捷值便于模板中直接驱动警告条显隐返回值是两个computed引用意味着你可以直接在 Vue 模板中绑定无需手动订阅更新。3. 底层实现逐行解析useNodeFontStatus的实现非常精简完整源码仅 30 行packages/vue/src/shared/font-status/use.ts但背后涉及三条核心链路节点类型判定 → 字体家族收集 → 加载状态查询。3.1 类型守卫只关心 TEXT 节点const missingFonts computed(() { const n node() if (n?.type ! TEXT) return [] // ... })SceneNode场景图中存在多种节点类型矩形、椭圆、路径等只有TEXT节点才携带字体信息。因此当 getter 返回null、undefined或非文本节点时直接返回空数组避免对其他节点产生无效计算。3.2 家族收集节点级 富文本 run 级const families new Setstring() families.add(n.fontFamily || DEFAULT_FONT_FAMILY) for (const run of n.styleRuns) { if (run.style.fontFamily) families.add(run.style.fontFamily) }字体家族来自两个层级节点级fontFamilyTEXT 节点的默认字体属性若为空则回退到DEFAULT_FONT_FAMILY其值为Inter见 packages/core/src/constants.ts这也是 Open-Pencil 内置的默认界面字体之一run 级styleRuns文本节点支持富文本分段style run每一段可以覆盖不同的style.fontFamily。遍历所有 run 即可把“一段文字混排多种字体”的情况全部覆盖。使用Setstring去重避免同一个家族被节点级与 run 级重复报告。3.3 加载状态查询FontManager.isLoadedreturn [...families].filter((f) !fontManager.isLoaded(f))最终过滤掉所有“已加载”的家族剩下的即为missingFonts。这里的fontManager是来自open-pencil/core/text的全局单例FontManagerpackages/core/src/text/fonts.ts其判定逻辑为isLoaded(family: string): boolean { return [...this.loadedFamilies.keys()].some((k) k.startsWith(${family}|)) } isStyleLoaded(family: string, style: string): boolean { return this.loadedFamilies.has(${family}|${style}) }packages/core/src/text/fonts.tsloadedFamilies以${family}|${style}为键缓存已注册字体的字形数据因此isLoaded(family)只要发现该家族任意样式已注册即视为“已加载”。与之配套的还有markLoaded(family, style, data, source)packages/core/src/text/fonts.ts用于在字体加载完成后登记缓存以及loadedFontSource/isStyleLoaded用于更细粒度的样式级查询。值得注意的边界useNodeFontStatus返回的是去重后的家族名列表粒度到“家族”而非“家族样式”。若需要样式级明细例如区分「家族已加载但某字重缺失」可以基于FontManager.isStyleLoaded(family, style)自行扩展。4. 在 Typography 面板体系中的集成useNodeFontStatus并非孤立存在它是 Open-Pencil 字体属性控制体系的数据源头之一。4.1 与 useTypography 的关系useTypography()是文本属性面板的核心 composable见 use-typography.md在其状态构造器createTypographyState内部直接调用了useNodeFontStatusconst node useSceneComputedSceneNode | null(() editor.getSelectedNode() ?? null) const { missingFonts, hasMissingFonts } useNodeFontStatus(() node.value)packages/vue/src/controls/typography/actions.ts也就是说useTypography()返回的missingFonts/hasMissingFonts正是由useNodeFontStatus提供的选中节点变化时useSceneComputed驱动 getter 重新求值缺失字体列表随之实时刷新完整返回值见 actions.ts。4.2 与 TypographyControlsRoot 的关系TypographyControlsRoot是无头headless根组件将useTypography()的状态与操作以 slot props 的形式暴露给自定义 UI见 typography-controls-root.md其中就包含字体状态slot :nodectx.node :weightsctx.weights :missing-fontsctx.missingFonts :has-missing-fontsctx.hasMissingFonts :active-formattingctx.activeFormatting :actionsactions /packages/vue/src/primitives/TypographyControls/TypographyControlsRoot.vue因此一个基于TypographyControlsRoot的自定义字体面板可以直接从 slot 中拿到missingFonts与hasMissingFonts在模板里渲染“缺失字体”警告并在用户选择缺失家族时触发加载。4.3 公共导出useNodeFontStatus已作为公共 API 从open-pencil/vue导出packages/vue/src/index.ts并在 packages/vue/README.md 的 composable 清单中列出可直接import { useNodeFontStatus } from open-pencil/vue。5. 实战示例5.1 直接使用自定义缺失字体警告条不经过useTypography直接对任意文本节点 getter 使用script setup langts import { computed } from vue import { useNodeFontStatus } from open-pencil/vue import type { SceneNode } from open-pencil/scene-graph const props defineProps{ node: SceneNode | null }() const { missingFonts, hasMissingFonts } useNodeFontStatus( computed(() props.node) ) /script template div v-ifhasMissingFonts classfont-warning rolestatus 以下字体尚未加载{{ missingFonts.join(, ) }} /div /template注意这里传给useNodeFontStatus的是一个返回节点引用的函数computed(() props.node)恰好满足 getter 签名且保证props.node变化时缺失列表自动重算。5.2 基于 TypographyControlsRoot字体面板 缺失提示 按需加载script setup langts import { TypographyControlsRoot } from open-pencil/vue async function loadFont(family: string, style: string) { // 由你的应用实现请求远端字体并调用 fontManager.markLoaded(family, style, data) } /script template TypographyControlsRoot :font-loader{ load: loadFont } v-slot{ missingFonts, hasMissingFonts, actions } select changeactions.setFamily(($event.target as HTMLSelectElement).value) option v-forf in fonts :keyf :valuef{{ f }}/option /select div v-ifhasMissingFonts classwarning 缺失字体{{ missingFonts.join(, ) }} — 切换家族时将自动加载 /div /TypographyControlsRoot /template这里的fontLoader会被useTypography的createTypographyActions在setFamily/setWeight之前调用见 packages/vue/src/controls/typography/actions.ts实现“先加载、再改属性”的防白屏体验async function setFamily(family: string) { if (!node.value) return await doLoadFont(family, currentWeightLabel.value) // 先加载 editor.updateNodeWithUndo(node.value.id, { fontFamily: family }, Change font) }5.3 与文档级字体状态 API 对照如果需要对整个文档而非单个节点做字体体检Open-Pencil 还在核心层提供了documentFontStatus(graph, rootIds, manager)packages/core/src/text/font/status.ts它扫描场景图并给出每个字体字形的状态available精确的「家族 样式」已加载substituted家族已加载但指定样式缺失或整体回退到DEFAULT_FONT_FAMILYInterunresolved连默认字体都不可用。两者定位不同useNodeFontStatus是节点级、响应式、面向面板 UI的轻量方案documentFontStatus是文档级、扫描式、面向导出/诊断的批处理方案。在面板场景优先使用前者在导出前校验等场景可以使用后者。6. 使用建议与注意事项入参必须是 getter 而非节点值这是响应式更新的前提传普通值会导致选中节点切换后状态不刷新。粒度是字体家族missingFonts是去重后的家族名数组样式级字重/斜体细分需结合FontManager.isStyleLoaded。非文本节点返回空数组无需在调用方额外做类型判断。默认回退 Inter节点未显式设置fontFamily时按DEFAULT_FONT_FAMILYInter判定Inter 属于内置字体正常情况下不会被报告为缺失。配合fontLoader使用在面板中把“检测缺失 → 用户选择 → 自动加载”串成闭环能显著改善多字体文档的编辑体验。7. 相关 API 与源码索引本 API 文档use-node-font-status.md实现源码packages/vue/src/shared/font-status/use.ts上层 composableuseTypography、packages/vue/src/controls/typography/use.ts无头组件TypographyControlsRoot、packages/vue/src/primitives/TypographyControls/TypographyControlsRoot.vue字体加载与判定packages/core/src/text/fonts.ts文档级字体状态packages/core/src/text/font/status.ts默认字体常量packages/core/src/constants.ts公共导出packages/vue/src/index.ts赞分享前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载相关推荐open-pencil SDK:useNodeFontStatus 深入解析——在 Vue 编辑器中检测文本节点缺失字体open pencil SDK:useNodeFontStatus 深入解析——在 Vue 编辑器中检测文本节点缺失字体 本文围绕 open pencil o前端桌面应用AI 应用MCP 服务OpenPencil 缺失字体检测指南useNodeFontStatus 组合式 API 解析OpenPencil 缺失字体检测指南useNodeFontStatus 组合式 API 解析 useNodeFontStatus 是 OpenPencil前端桌面应用AI 应用MCP 服务open-pencil SDK 深度解析useNodeProps 属性面板 Composable 的混合值检测、多选更新与撤销感知提交open pencil SDK 深度解析useNodeProps 属性面板 Composable 的混合值检测、多选更新与撤销感知提交 useNodeProp前端桌面应用AI 应用MCP 服务上一篇Godot卡牌游戏框架终极指南如何在1小时内构建专业级卡牌游戏下一篇Legacy iOS Kit终极指南让旧iPhone/iPad重获新生的完整工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考