把项目从「手写 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 处引用自包含。
4.0 KiB
08 — 面板改为右边缘滑出,并让它能在静态托管上工作
Status: resolved Type: task
需求(用户原话)
模拟的壁纸测试面板是在鼠标移至页面右侧边缘时弹出的,且并不能仅有调试服提供,未来上传 GitHub 是 pages 预览也需要能够弹出壁纸设置面板
两件事:
- 面板的打开方式是鼠标移到页面右侧边缘——不是常驻按钮。
- 面板不能只有调试服能给。未来上 GitHub Pages 的预览也要能弹出设置面板。
① 交互:右边缘滑出
原来的实现是右上角一个常驻的「WE 模拟器」按钮。改成 16px 右边缘热区 + 全高抽屉,与 player 配置页同一套约定:
| 行为 | 结果 |
|---|---|
| 指针进入右边缘 16px | 面板滑出 |
| 指针离开面板/边缘 | 自动收回 |
| 点 × 收起 | 收起,且必须先离开边缘才会再次自动滑出 |
| 点热区 | 开合(触屏没有 hover,点击是兜底) |
#wesim-edge 里的把手只是"这里能滑出东西"的可见提示,pointer-events: none,不参与命中。
踩的坑:不能用 mouseenter / mouseleave 判定
第一版用 edge.mouseenter 打开、root.mouseleave 收回。测试立刻发现"指针离开 → 自动收回"永远是 data-open=1。
原因:面板是用 transform 从右侧滑进来的,出现时指针已经在它下面,浏览器不会为它补发 mouseenter——于是 root 从来没被标记为 hover,它后面的 mouseleave 自然也不会来。
改成在 mousemove 里按坐标判定,结果只取决于指针位置,与浏览器是否补发事件无关:
const nearEdge = event.clientX >= window.innerWidth - EDGE_WIDTH;
const overPanel = opened && event.clientX >= window.innerWidth - PANEL_WIDTH;
PANEL_WIDTH / EDGE_WIDTH 与 CSS 共用同一组常量(CSS 里用模板插值),避免"改了一处忘了另一处"。
armed 是"× 收起后需先离开边缘"那条规则的状态位。没有它,点 × 之后指针仍在热区里,下一次 mousemove 就把面板弹回来,表现为"× 根本关不掉"。
② 静态托管:把注入写进 index.html
| 场景 | 谁注入 | 模拟器本体从哪来 | 产物 |
|---|---|---|---|
pnpm dev |
调试服按路由注入 | 调试服自己的 /simulator/wallpaper-engine.js |
分发目录保持干净 |
| 静态托管(Pages) | 构建期写进 index.html |
分发自带的 ./scripts/wallpaper-engine.js |
pnpm build --with-sim |
| 上传 Wallpaper Engine | 没有人注入 | 不存在 | pnpm build(默认) |
要点:
- 静态地址必须相对(
./scripts/...)。Pages 把站点放在/<repo>/子路径下,根绝对路径会 404。 - 驱动带幂等闸
window.__weSimDriver:--with-sim构建的分发自带驱动,调试服又会注入一次,没有闸就会 mount 两遍、出现两个面板。 - 默认产物里既没有模拟器文件,也没有任何注入痕迹——它必须与用户从创意工坊下载到的东西完全一致(ADR 0006 第 1 条)。
验证
tools/checks/verify-static-preview.mts:刻意把分发挂在 /repo/ 前缀后面服务,而不是挂在根上——挂根上测不出相对路径的错。断言分三组:
- 静态托管下
window.__weSim存在、#wesim与#wesim-edge已挂载、没有常驻按钮、横幅在、壁纸本身也渲染 - 右边缘滑出六态:初始收起 → 滑出 → 离开收回 → 再滑出 → × 收起不被弹回 → 离开边缘后重新可触发
- 静态服务器 0 个 404、0 异常、0 控制台报错
四档分发全部通过。另有 tools/checks/smoke-sim.mts 的"面板恰好一个"断言守住双重注入。
顺带发现
- 合集那两档的自包含包是 128.7 MB,超过 GitHub 单文件 100 MB 上限。所以 Pages 只能走"分发目录 + 构建期注入"这条路,不能直接发布
sim/index.html。 src/vendor/spine-player.js.bak是内联守卫测试留下的残留,已删。