# 项目计划(2026-02-08) ## 1. 当前状态 ### 1.1 已完成(保留能力) - Web 应用主链路可用:字体选择、预览、收藏、导出(SVG/PNG) - Python CLI 可独立运行:`font2svg.py`、`pic2svg.py` - 字体清单生成脚本可用:`scripts/generate-font-list.py` ### 1.2 新增目标 - 在不影响现有 Web/CLI 的前提下,新增微信小程序版本(新目录:`miniprogram/`) - 小程序版本以移动端体验为主,不做 Web 页面 1:1 迁移 ## 2. 小程序专项范围 ### 2.1 技术选型 **开发方式**:微信小程序原生开发(TypeScript + WXML + WXSS) - 理由:充分利用 Worker、Canvas 2D 等原生能力,避免框架转换损耗 - 放弃 Taro/uni-app:复杂业务逻辑转换可能引入额外兼容问题 **核心算法复用**:直接复制 Web 端 `utils/` 核心模块 - `svg-builder.ts`:字形路径生成与 SVG 构建(纯函数,无浏览器 API 依赖) - `text-layout.ts`:文本换行逻辑 - `font-loader.ts`:适配为小程序 API(`wx.downloadFile` + `wx.getFileSystemManager`) **字体资源托管**:云存储(微信云开发 / 第三方 OSS) - 字体文件上传到云端,生成 CDN URL - `fonts.json` 清单文件托管(含字体元数据) - 按需下载,突破小程序 2MB 主包限制 ### 2.2 范围内(MVP) - 文本输入 + 字体选择(搜索/分类/收藏)+ 实时预览 - 字号、颜色调节 - 导出 SVG(文件系统写入 + 分享) - 导出 PNG(Canvas 2D 渲染 + 保存相册) - 本地状态持久化(文本、字体、参数) ### 2.3 范围外(后续迭代) - HarfBuzz/WASM 高级 shaping(首版关闭,使用 opentype.js 基础能力) - 多字体对比预览(Web 版特性,小程序屏幕受限) - 批量导出与 ZIP 打包(小程序 API 限制) - 字体树分类折叠展开(简化为扁平列表 + 搜索) ## 3. 移动端差异与技术策略 ### 3.1 交互策略 - 单列流程:输入 -> 预览 -> 导出 - 大按钮、触控优先、避免多栏复杂布局 ### 3.2 性能策略 - 字形生成放入 `Worker`,主线程专注渲染 - 长文本分批处理,支持任务取消 - 字体对象缓存与内存上限控制 ### 3.3 平台适配策略 - 文件系统:`wx.getFileSystemManager()` + `writeFile/saveFile` - PNG 导出:`wx.canvasToTempFilePath` - 文件分享:`wx.shareFileMessage` - 图片保存:`wx.saveImageToPhotosAlbum`(带授权处理) - 预览:优先 `image` 组件渲染 SVG,必要时回退 PNG ### 3.4 包体策略 - 字体与 Worker 支持分包/按需加载 - 首包仅保留必要资源 ## 4. 目录结构设计 ``` miniprogram/ ├── pages/ # 页面 │ ├── index/ # 主页(输入+预览+导出) │ │ ├── index.wxml │ │ ├── index.ts │ │ ├── index.wxss │ │ └── index.json │ └── font-picker/ # 字体选择页 │ ├── font-picker.wxml │ ├── font-picker.ts │ ├── font-picker.wxss │ └── font-picker.json ├── components/ # 组件 │ ├── text-input/ # 文本输入组件 │ ├── font-item/ # 字体列表项 │ ├── preview-card/ # 预览卡片 │ └── export-panel/ # 导出面板 ├── workers/ # Worker 线程 │ └── svg-generator/ # SVG 生成 Worker │ └── index.ts ├── utils/ # 工具函数 │ ├── core/ # 核心算法(复用 Web) │ │ ├── svg-builder.ts # SVG 生成核心 │ │ ├── text-layout.ts # 文本换行 │ │ └── glyph-path.ts # 字形路径 │ ├── mp/ # 小程序专用 │ │ ├── font-loader-mp.ts # 字体加载适配 │ │ ├── storage-mp.ts # 存储适配 │ │ ├── canvas-export.ts # Canvas 导出 │ │ └── share-mp.ts # 分享/保存 │ └── worker-manager.ts # Worker 管理器 ├── typings/ # 类型定义(复用 Web types/) │ └── font.d.ts ├── assets/ # 静态资源 │ └── icons/ # 图标(复用 Web) ├── styles/ # 全局样式 │ └── variables.wxss # 设计 token(基于 Figma) ├── miniprogram_npm/ # npm 构建产物 ├── app.ts # 小程序入口 ├── app.json # 全局配置 ├── app.wxss # 全局样式 ├── package.json # npm 依赖 ├── tsconfig.json # TypeScript 配置 └── project.config.json # 微信开发者工具配置 ``` ## 5. 里程碑与验收 ### M1:工程骨架(P0) **实施步骤**: 1. 创建 `miniprogram/` 目录,微信开发者工具初始化原生项目 2. 配置 `project.config.json`: - 设置 `miniprogramRoot`、基础库版本 ≥ 2.9.0 - 启用 TypeScript 编译插件 3. 创建 `package.json`,安装依赖: ```json { "dependencies": { "opentype.js": "^1.3.4" }, "devDependencies": { "miniprogram-api-typings": "latest", "typescript": "~5.9.3" } } ``` 4. 配置 `tsconfig.json`(参考 `frontend/tsconfig.json`) 5. 创建 `app.ts`、`app.json`、`app.wxss` 6. 创建首页 `pages/index/`(空白页面) 7. 微信开发者工具"构建 npm" **验收标准**: - 开发者工具可启动并进入首页(显示空白页面) - TypeScript 编译无错误 - npm 包构建成功(`miniprogram_npm/` 生成) ### M2:核心算法迁移(P0) **实施步骤**: 1. **复制纯算法模块**: - `frontend/src/utils/svg-builder.ts` → `miniprogram/utils/core/svg-builder.ts` - 保留 `generateSvg()` 函数(移除 `generateSvgWithHarfbuzz()`) - `frontend/src/utils/text-layout.ts` → `miniprogram/utils/core/text-layout.ts` - 提取字形路径逻辑到 `miniprogram/utils/core/glyph-path.ts` 2. **复制类型定义**: - `frontend/src/types/font.d.ts` → `miniprogram/typings/font.d.ts` 3. **平台适配层开发**: - `miniprogram/utils/mp/font-loader-mp.ts`: - `loadFontFromUrl()`:使用 `wx.downloadFile()` + `wx.getFileSystemManager()` - `miniprogram/utils/mp/storage-mp.ts`: - 封装 `wx.getStorageSync/setStorageSync` - 提供类型安全的 `getStorage`、`setStorage` 方法 4. **编写单元测试**: - `miniprogram/utils/core/__tests__/svg-builder.test.ts` - 测试用例:单字符、多字符、空字符串、特殊字符 **验收标准**: - 输入文本 + Font 对象可生成有效 SVG 字符串 - SVG 结构正确(包含 ``、``、`viewBox`) - 核心算法单测通过(覆盖率 > 80%) ### M3:预览链路(P0) **实施步骤**: 1. **主页布局**(`pages/index/`): - 文本输入区(`