-
Notifications
You must be signed in to change notification settings - Fork 291
Open
Description
问题描述
官方文档声明 Text 原语(原语节点)支持 letterSpacing 和 wordSpacing。但是该功能似乎不可用,问题贯穿了从底层的 测量算法 到中间的 样式解析 再到上层的 业务组件封装 的完整链路。
代码分析
1. 底层:测量函数忽略(measureText)
measureText实现忽略: 在src/utils/measure-text.ts中,逻辑只解构了fontFamily,fontSize,fontWeight,lineHeight,完全忽略了letterSpacing和wordSpacing。- 调用链路截断:
src/utils/text.ts中的updateTextElement在调用measureText时,显式解构并过滤了样式属性,直接丢弃了这两个属性。
2.中间层: 样式解析不一致
-
渲染属性白名单缺失:在
src/renderer/composites/text.ts的getTextAttributes函数中,使用了白名单机制提取 SVG 属性。- 现状: 该白名单包含
'letter-spacing',但漏掉了'word-spacing'。 - 后果: 即使上层传入了
wordSpacing,它也会在最终生成 SVGforeignObject内容时被剥离,无法渲染出视觉效果。
- 现状: 该白名单包含
-
在
src/utils/text.ts中的getTextStyle函数对letterSpacing做了处理,加上了px,但是没有对wordSpacing做处理。
3.顶层:业务组件透传阻断
虽然原子组件 ItemLabel/ItemValue /ItemDes支持透传 TextProps,但在 SimpleItem、BadgeCard 等业务组件中,并没有开放接口来配置内部文本的间距,也没有将letterSpacing和wordSpacing透传给文本节点。
4.总结:文本属性支持情况对比表
| 层级 | 问题 | letterSpacing | wordSpacing |
|---|---|---|---|
底层 (measureText) |
测量忽略间距属性 | ❌ 不支持 | ❌ 不支持 |
中间层 (text.ts getTextStyle) |
px 后缀处理 | ✅ 有处理 | ❌ 无处理 |
中间层 (composites/text.ts) |
渲染白名单 | ✅ 已包含 | ❌ 缺失 |
原语层 (jsx Text) |
属性透传 | ✅ 正确 | ✅ 正确 |
| 业务组件层 | 接口暴露 | ❌ 未暴露 | ❌ 未暴露 |
建议方案
Step 1: 修复核心渲染与测量 (Core Fix)
- Refactor
measureText: 升级函数签名,支持传入letterSpacing和wordSpacing。 - Fix
utils/text.ts: 在updateTextElement中正确透传这两个属性给测量函数。并且在getTextStyle函数中添加对wordSpacing的处理。 - Fix
renderer/composites/text.ts: 在getTextAttributes的白名单数组中添加'word-spacing'。
Step 2: 修复组件层数据流 (Component Fix)
- Update Business Components: 修改
SimpleItem等组件,允许通过 props (如labelStyle) 传入间距属性,并将其透传给内部的ItemLabel/ItemDesc。
Step 3:性能优化 (Performance Optimization - 可选)
- 实现 LRU 缓存: 我发现
measureText在每次调用时都会触发 Canvas/DOM 测量,而没有任何缓存机制。我建议引入 LRU (Least Recently Used) 缓存机制(例如通过项目现有的flru库实现)。
备注: 我已经准备好了一套本地实现LRU的方案。
如果维护者同意,我愿意参与第一步(核心修复)和第三步(性能优化)。
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels