Files
wangjia 1340b477a7 feat(client): 字体可注入 + 启用 golden 视觉回归闸
- pangolin_theme: PangolinFonts 加 useBundled 开关 + sora/manrope/jetBrainsMono/
  manropeTextTheme 封装(生产走 google_fonts / 测试走 bundled family);
  PangolinText 与 _build 改调封装,移除散落的 GoogleFonts 直接调用
- test/flutter_test_config.dart: 全测试前置,FontLoader 注册 test/fonts 真实
  Sora/Manrope/JetBrainsMono + Lucide 图标字体,置 useBundled=true
- 启用 test/golden(去 @Skip):连接键三态+推荐卡+额度卡×明暗 12 基准图
- tool/visual-diff.md: 标注 golden 严格闸已落地

测试: flutter test 76 通过(原 64+1skip → 76 无 skip), analyze 0 error

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 11:36:50 +08:00

48 lines
2.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 视觉 diff 工作流(pangolin 客户端 ↔ design/ui_kits 原型)
`design-distill` skill 的截图 diff 工具,把 Flutter 实现与 `design/ui_kits/{desktop,tablet,mobile}` React 原型对照。
## 工具
- 原型截图:`~/.claude/skills/design-distill/tools/shoot-prototype.mjs`
- 像素 diff`~/.claude/skills/design-distill/tools/diff.mjs`
## 原型基准(已验证可用)
从项目根运行(脚本自动起临时 http server,让 Babel 原型能 fetch jsx):
```bash
SHOOT=~/.claude/skills/design-distill/tools/shoot-prototype.mjs
# desktop 连接页 明/暗(920×600 内容,截外层 sand 画布给点余量)
node $SHOOT design/ui_kits/desktop/index.html shots/desktop_connect_light.png \
--width 1000 --height 720 --theme light --lang zh --wait-for "#root > *"
node $SHOOT design/ui_kits/desktop/index.html shots/desktop_connect_dark.png \
--width 1000 --height 720 --theme dark --lang zh --wait-for "#root > *"
```
> 原型是 SPA,默认显示连接页。截其它页需给 shoot-prototype 加 `--click <navSelector>`(待补)。
## diff
```bash
node ~/.claude/skills/design-distill/tools/diff.mjs <baseline.png> <impl.png> <diff.png> --threshold 0.05
```
## 实现侧截图:两条路径与现状
### A. Flutter golden(已启用 ✅,CI 严格回归闸)
`flutter test --update-goldens test/golden``RepaintBoundary`,无 chrome/窗口问题,入 CI。
**字体方案**(已落地):`PangolinFonts.useBundled` 开关 + `test/flutter_test_config.dart``FontLoader`
注册 `test/fonts/` 真实 Sora/Manrope/JetBrainsMono + Lucide 图标字体,测试态绕过 google_fonts。
- 改组件视觉后:`flutter test test/golden` 失败即回归;确认是预期变更则 `--update-goldens` 重生成基准。
- 现覆盖:连接键三态 + 推荐卡 + 额度卡 × 明暗(`test/golden/components_golden_test.dart`)。
- 注:CJK 文案用 fallbackNoto Sans SC 未打包,体积大),基准自洽不影响回归检测;新增屏/组件按此模式扩展。
### B. screencapture 真实 app(已可截,但受限)
真实渲染、字体真实,但:macOS 原生标题栏(红绿灯) vs 原型自绘 chrome 结构不同;窗口精确定位需「辅助功能」权限。
**用途**:作为**人工视觉对照**(生成 diff 图定位结构偏差),非严格像素闸。
### C. iOS 模拟器(最干净的全屏,未接)
`xcrun simctl io booted screenshot` 截模拟器无桌面 chrome、字体真实,适合 mobile/tablet。导航多页仍需 integration_test 驱动。
## 建议
- **严格回归闸** → 走 A,先做 `PangolinText` 字体可注入(一次性小重构),启用 golden。
- **对照设计原型** → 原型基准(本文档)+ A 的 golden 截图,用 diff.mjs 比对。
- desktop 因 chrome 差异,像素级 100% 对齐不是目标;以**布局/间距/颜色结构一致**为验收口径。