fix: 文本框宽度/阴影/边框/背景/去重 — 通用化前稳定版
- 文本框宽度:contentW 从 slide 子节点推算,排除游离节点
- TEXT 宽度:顶层用 contentW,嵌套用 parentW,最小1.5in,x+w≤slideW
- collectSlideChildren 新增 _depth 参数标记层级
- boxShadow 正确传给 pptxgenjs(之前 addShape 只传了 fill)
- 单边 border 不加 shape line,由四周边框线逻辑单独处理
- shape 默认 line: { type: 'none' } 去掉 pptxgenjs 默认边框
- 背景色:从 slide name 推断 dark/light 兜底
- findSlides 支持 'slide ' 前缀
- collectOrphans 跳过 'slide ' 子树(修复文字重复)
- 新增 docs/ 目录:映射分析和通用架构文档
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
# web-to-pixso → PPT 映射分析
|
||||
|
||||
## 1. JSON 结构总览
|
||||
|
||||
### 顶层字段
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `canvas` | 画布尺寸 `{width, height, x, y, backgroundColor}` |
|
||||
| `nodes` | 根节点树(type=FRAME, name=html) |
|
||||
| `assets` | 图片资源 `{key: base64}` |
|
||||
| `fonts` | 字体列表 |
|
||||
| `schemaVersion` | JSON 版本号 |
|
||||
|
||||
### 节点类型
|
||||
| 类型 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| FRAME | 471 | HTML 容器(div, section, table, header 等) |
|
||||
| TEXT | 393 | 文字节点 |
|
||||
| RECTANGLE | 10 | 截图底图(comparison layer,用于视觉对比) |
|
||||
|
||||
### 节点属性
|
||||
```
|
||||
type - FRAME/TEXT/RECTANGLE
|
||||
rect - {x, y, width, height} 像素坐标
|
||||
styles - 57个CSS属性(见下表)
|
||||
name - HTML元素名或文字内容
|
||||
tag - HTML标签名(HTML/DIV/TABLE/TR/TD/SPAN/#text等)
|
||||
text / src - 文字内容(TEXT节点用text,收集时映射为src)
|
||||
layerGroup - editable/text/comparison
|
||||
backgroundImages - 图片资源引用数组
|
||||
clipRect - 裁剪区域
|
||||
visibleRect - 可见区域
|
||||
clipped - 是否被裁剪
|
||||
id - 节点ID
|
||||
section - document
|
||||
visualRole - layout-wrapper/text-node/raster-fallback
|
||||
```
|
||||
|
||||
## 2. 57个 styles 字段分类
|
||||
|
||||
### 已处理(15个)
|
||||
| 字段 | 用途 | 当前处理方式 |
|
||||
|------|------|-------------|
|
||||
| backgroundColor | 背景色 | → shape fill |
|
||||
| backgroundImage | 渐变背景 | → 提取起始色做纯色 fill |
|
||||
| borderTopWidth/Color/Style | 顶部边框 | → shape line(四边都有时)或单独线条 |
|
||||
| borderBottomWidth/Color/Style | 底部边框 | 同上 |
|
||||
| borderLeftWidth/Color/Style | 左边框 | 同上 |
|
||||
| borderRightWidth/Color/Style | 右边框 | 同上 |
|
||||
| borderTopLeftRadius | 圆角 | → rectRadius |
|
||||
| boxShadow | 阴影 | → shadow |
|
||||
| fontSize | 字号 | → fontSize(pt) |
|
||||
| fontFamily | 字体 | → fontFace |
|
||||
| color | 文字颜色 | → color |
|
||||
| fontWeight | 粗体 | → bold |
|
||||
| fontStyle | 斜体 | → italic |
|
||||
| textAlign | 对齐 | → align |
|
||||
|
||||
### 未处理(42个)
|
||||
| 字段 | 重要性 | 说明 |
|
||||
|------|--------|------|
|
||||
| **opacity** | 高 | 元素透明度,PPT支持 `opacity` |
|
||||
| **lineHeight** | 高 | 行高,影响文字换行和间距 |
|
||||
| **letterSpacing** | 中 | 字间距,PPT支持 `charSpacing` |
|
||||
| **textDecorationLine** | 中 | 下划线/删除线 |
|
||||
| **textTransform** | 低 | 大小写转换 |
|
||||
| **whiteSpace** | 高 | 控制换行行为(nowrap等) |
|
||||
| **wordBreak** | 中 | 断词规则 |
|
||||
| **visibility** | 中 | visible/hidden |
|
||||
| **display** | 中 | none时不渲染 |
|
||||
| **transform** | 中 | 旋转/缩放/位移 |
|
||||
| **transformOrigin** | 低 | 变换原点 |
|
||||
| **zIndex** | 高 | 层级顺序 |
|
||||
| **overflow** | 中 | 溢出处理 |
|
||||
| **clipPath** | 低 | 裁剪路径 |
|
||||
| **filter** | 低 | CSS滤镜 |
|
||||
| **borderTopRightRadius** | 中 | 右上圆角(目前只用左上) |
|
||||
| **borderBottomLeftRadius** | 中 | 左下圆角 |
|
||||
| **borderBottomRightRadius** | 中 | 右下圆角 |
|
||||
| **backgroundPosition** | 低 | 背景定位 |
|
||||
| **backgroundSize** | 低 | 背景尺寸 |
|
||||
| **backgroundRepeat** | 低 | 背景重复 |
|
||||
| **backgroundClip** | 低 | 背景裁剪 |
|
||||
| **backgroundOrigin** | 低 | 背景原点 |
|
||||
| **position** | 低 | 定位方式 |
|
||||
| **objectFit** | 低 | 图片适配 |
|
||||
| **objectPosition** | 低 | 图片定位 |
|
||||
| **maskImage/MaskPosition/MaskSize** | 低 | 遮罩 |
|
||||
| **webkitMaskImage/MaskPosition/MaskSize** | 低 | 遮罩(webkit) |
|
||||
| **backdropFilter** | 低 | 背景滤镜 |
|
||||
|
||||
## 3. 映射优先级
|
||||
|
||||
### P0(必须处理)
|
||||
1. **opacity** → shape/text 的 opacity 属性
|
||||
2. **whiteSpace** → 控制文字是否换行
|
||||
3. **zIndex** → 调整 objects 数组顺序(后渲染在上层)
|
||||
4. **lineHeight** → 文字行高(paraSpaceBefore/after 或 lineSpacingMultiple)
|
||||
|
||||
### P1(应该处理)
|
||||
5. **letterSpacing** → charSpacing(字符间距)
|
||||
6. **textDecorationLine** → underline/strike
|
||||
7. **display:none** → 跳过该节点
|
||||
8. **visibility:hidden** → 跳过该节点
|
||||
9. **四个圆角独立处理** → 当前只用了 borderTopLeftRadius
|
||||
|
||||
### P2(可以处理)
|
||||
10. **transform** → rotate 属性
|
||||
11. **wordBreak** → 辅助判断换行
|
||||
12. **overflow** → 辅助判断裁剪
|
||||
13. **filter** → 特殊效果(大部分PPT不支持)
|
||||
|
||||
## 4. 当前代码架构
|
||||
|
||||
```
|
||||
HTML → web-to-pixso 插件 → JSON
|
||||
↓
|
||||
convert-w2p.js(提取+映射)
|
||||
↓
|
||||
Schema JSON
|
||||
↓
|
||||
pptxgenjs(渲染)
|
||||
↓
|
||||
.pptx 文件
|
||||
```
|
||||
|
||||
### convert-w2p.js 处理流程
|
||||
1. findSlides() — 找 page/slide-N 容器
|
||||
2. collectSlideChildren() — 递归提取子节点(保留层级)
|
||||
3. collectOrphans() — 收集游离节点归入最近 slide
|
||||
4. 排序:FRAME 在前,TEXT 在后
|
||||
5. 映射循环:遍历每个子节点
|
||||
- TEXT → text 对象(含字号/字体/颜色/粗体/对齐)
|
||||
- IMAGE → image 对象
|
||||
- FRAME with bg → shape 对象(含 fill/border/shadow/rectRadius)
|
||||
- 四边 border → 独立线条 shape
|
||||
6. 输出 Schema JSON + 调用 pptxgenjs 生成 PPTX
|
||||
|
||||
## 5. 下一步行动
|
||||
|
||||
### 短期(本次迭代)
|
||||
- [ ] 实现 P0:opacity、whiteSpace、zIndex、lineHeight
|
||||
- [ ] 实现 P1:letterSpacing、textDecoration、display/visibility 过滤
|
||||
|
||||
### 中期
|
||||
- [ ] 建立 web-to-pixso JSON 的完整字段文档
|
||||
- [ ] 验证不同 HTML 结构的 JSON 输出一致性
|
||||
- [ ] 处理 transform(旋转)
|
||||
|
||||
### 长期
|
||||
- [ ] 参考设计稿,实现高度还原的 PPT 输出
|
||||
- [ ] 处理复杂布局(grid/flex 嵌套)
|
||||
Reference in New Issue
Block a user