Files
SpineWallpaper/.scratch/build-pipeline/issues/18-panel-preview.md
T
Shuery 3f11426964 feat: TS 构建管线、Spine 抓取器与 wallpapers/ 唯一真相来源
把项目从「手写 dist/」改成「wallpapers/ 是唯一真相来源,dist/ 由 pnpm build 生成」,
并补上配套的类型、门禁与抓取器。一次提交落地整条管线,因为拆开会留下不能构建的中间态。

- src/:运行时与模拟器源码(TS,strict),编译到 build/ 再拷进各分发
- tools/:build / dev / check-{syntax,paths,dist},以及抓取器与回归门禁 tools/checks/
  (.scratch/ 下那批一次性脚本移入 tools/checks/ 并入库为长期门禁)
- wallpapers/:七档壁纸的源数据 + README.md(id/音频/预设的完整规范)
- docs/adr/0005-0008:构建管线与分发拓扑、模拟器契约、自包含 sim、每骨架资源布局
- .gitignore:排除 .scratch/ 的参考资料副本(上游 spine 整仓克隆 ~1.2 GB、
  抓取侦查数据 ~680 MB)与调试转储;这些是本地调查材料,补偿会让仓库无法克隆
- 归一化 .gitignore/CONTEXT.md 行尾(工作区 CRLF、索引 LF 造成的整文件假 diff)

同时修掉三档卡住构建的未完工壁纸:
- kv45 的 meta.json 里 id 还是抓取期场景名 scene_main,经 downloader promote 正名为 kv45
- shajin / zhigengniao_juheye 的 meta.json 误用了骨架描述文件(name/spine/animations/pages)、
  且都缺 preset.template.json;现按规范重建:骨架沉到 spines/<名>/(spine-ts 按 atlas 所在
  目录解析贴图页)、补上元数据与单骨架预设,并清掉 zhigengniao 骨架里指向作者机的绝对路径
- 顺带 promote 已在 sources.yml 里的 kv46(月升之前,与兽共舞)

pnpm check 五道门全绿:10 个分发 / 7 档壁纸 / 141 处引用自包含。
2026-10-02 01:27:02 +08:00

92 lines
4.6 KiB
Markdown
Raw 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.
# 18 — 设置面板上方的预览图
Status: resolved
Type: task
## 需求
> wallpaper engine 的设置面板上方是会展示 preview.gif 的,你确认一下之前给的截图中的样式,还原一下
## 先量,再写
用户第一张截图还在 attachments 里,我直接把它读回来、裁出预览区放大 3 倍看,并**逐像素采样**取几何与配色——
而不是凭记忆估:
| 量到的东西 | 值 |
| --- | --- |
| 面板底色 | `#222222` |
| 预览区左右内缩 | 各 20px(内容宽 298,高 237 ≈ 5:4) |
| 箭头按钮 | 36×26 的 `#3c3c3c` 方块 |
| 箭头字形 | `#4082f5` 的 `‹` `›`(**蓝色**,不是白色) |
| 箭头位置 | 贴预览的左右边缘、距预览底 26px |
| 预览图本体 | `preview.gif` 是 **160×160**(方形),面板里按 5:4 裁切显示 |
## 左右箭头:量到了,但最后**去掉了**
我一开始照着截图把那对箭头也做了出来,用"切换本分发的预设"当最近的对应。用户随后指出:
> 预览图上的上一个、下一个按钮在 wallpaper engine 中是切换壁纸用的,我们不需要,直接把那两按钮去掉
判断是对的,而且理由比"不需要"更硬:
- WE 那对箭头切的是**已安装的壁纸列表**,模拟器里**没有那个列表**——所谓"最近的对应"其实是**另一件事**。
- 面板上本来就有「壁纸预设切换」下拉,两个箭头只是重复。
- 更糟的是它会**误导**:看起来像在切壁纸,实际切的是预设。
所以 CSS 与 DOM 一起删掉,并在 `verify-panel.mts` 里留了一条**防回归断言**(`navs.length === 0`),
免得以后又照着截图把它加回来。
那个 3 倍放大的裁剪图留在 `.scratch/shots/ref-preview-area.png`,以后要再核对就用它。
(注意:那张图里**有**箭头——它是官方原样,不是我们的目标形态。)
## 打通链路
预览图**不被 preset.js 引用**,所以它不在原有的资源收集范围里,得单独接:
1. `project.json` 的 `preview` → 驱动(`SIMULATOR_DRIVER`)多带一个 `preview` 字段
2. 三条注入路径都要传:调试服(`dev.ts`)、静态构建(`build.ts` 的 `renderIndexHtml`)、自包含包(`bundle.ts`)
3. 面板渲染预览区;URL 走与运行时**同一套**解析(`__simAssetRoot` + `__simSwap`)
4. `collectAssets` 把预览图也内联成 `data:` URL
**第 2 步我漏了自包含包那一处**,于是自包含页的预览区整块不出现。补上后才对。
### 为什么自包含包必须内联它
自包含页在 `<分发根>/sim/` 下,而预览图在 `<分发根>/preview.gif`。
file:// 下 `../preview.gif` 是**跨目录**读取,浏览器直接拒绝——所以只能内联成 `data:` URL。
这和别的资源是同一个理由,不是额外讲究。
## 三个分支都验过
| 分发 | 有 preview | 结果 |
| --- | --- | --- |
| `collection-all` | ✓ | 预览区在,图片解码出 160×160,箭头可用 |
| `single-hsr-xilian` | ✓ | 同上 |
| `single-hsr-kv37` | ✗ | **整块不出现**(与发布产物一致:project.json 里没有 preview) |
| `collection-hsr` | ✗ | 同上 |
自包含包里:`data:` URL + 能解码。静态托管(`--with-sim`)下:子路径里 **0 个 404**。
## 左右箭头(已去掉,见上)
官方那两个箭头是切换"已安装的壁纸"。~~这里切**本分发的预设**——语义最近的对应:
读 `preset` combo 的 options,点一下切到上一个/下一个,单档分发(连 `preset` 属性都没有)两个都禁用。~~
## 验证
`tools/checks/verify-panel.mts` 第 ⑪ 组 + `tools/checks/verify-sim-page.mts` 的新断言,全绿:
- 预览区已渲染、`src` 指向分发根的 `preview.gif`、`naturalWidth` 真的是 160×160(**不是坏图**)
- **预览上没有左右箭头**(防回归:它们曾经存在过)
- 自包含页:`src` 是 `data:` 且能解码
其余回归全绿:`pnpm check`、调试服与浏览器冒烟、面板还原度、热更新、开发模式构建开关、
`test-props` / `test-resize` / `test-acceptance` / `verify-fitter`、sim 门禁、内联守卫、模块改写、
6 组渲染逐像素相同、`diff-project` 仍是 14 处(预览改动**没有**动发布产物)。
## 两个环境注意
- **内联守卫测试会改 `src/vendor/spine-player.js`**,而调试服的热更新在监听 `src/`——
两者会抢构建,跑那个测试时要先停调试服。同理 `pnpm build sim` 与 watcher 也会抢 `dist/`。
- `pnpm build:sim` 只编译模拟器(tsc),**不产出 sim 页**;改完面板要跑 `pnpm build sim` 才会重新内联。