Files
SpineWallpaper/.scratch/wallpaper-optimization/issues/05-we-properties.md
T
Shuery eb56efbd9e feat: 比例适配、bgm 音源选择与 fps 限流,打包 v3
取景(issue 04)
- 新增 viewport-fitter.js:让立绘层缩放跟随背景图的 cover 缩放——背景放大多少倍、
  特效就放大多少倍。原先背景走 cover、立绘层走 contain,比例一变两者就分叉。
  16:9 下与作者设定逐像素一致(kv37 为 0 差异)。实测证伪了"contain 会裁掉作者视口"
  这个最初的判断:contain 在任何比例下都完整含住作者视口。
- 应用方式为原地改写 config.viewport 字段后调 setViewport(),不重建播放器;
  维护挂在 config.frame 上按画布比例增量进行(config.success 早于 setViewport,拿不到视口)。

WE 属性(issue 05)
- project.json 新增 bgm combo(所有壁纸音源的并集 + 「随预设」);所选项不属于当前壁纸时
  音频回落该壁纸默认,选择本身保留。
- fps 限流包裹实例 drawFrame 并接管排程。修掉两个实测缺陷:朴素丢帧会把 rAF 抖动放大成
  整拍丢失(目标 30fps 实测只有 22.5fps);fps:0 被真值判断吞掉导致无法取消限流。

打包(issue 06)
- project.json version 升至 3 并更新描述;preset 的 combo 取值保持 xilian/kv37 不变。
- preview.gif 821 KB → 347 KB(每 2 帧取 1 帧 + 128 色不抖动,逐帧与源帧像素完全相同)。
- index.html 加内联 favicon,消除 CEF 自动请求 /favicon.ico 造成的 404 报错。

其它
- dist/scripts/wallpaper-engine.js 移到 tools/:它没有任何入口引用,且环境判据依赖真实 WE
  并不存在的 wallpaperRegisterListener,一旦按它自己的说明挂进 index.html 会在生产环境自我激活。
- 修正死文件检查:原检查会拿文件名匹配到文件自身的内容,使这类文件漏网。
- 新增离线算式验证与 resize / 属性 / 全量验收三套浏览器测试脚本。
2026-09-19 20:29:25 +08:00

41 lines
2.3 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.
# 05 WE 属性扩展:音源 combo、fps 限制
Status: resolved
## 内容
1. **音源**:`project.json` 新增 combo `bgm`,列表是所有壁纸音源声明的**并集**
(WE 的 combo 是静态列表,只能手工同步),另加一档「随预设」`auto`:
`auto` / `zaiduheni`「「再度和你」」/ `xilian`「昔涟」/ `pv37`「版本 PV」。
每档壁纸仍在自己 `preset.js` 的 `audioChoices` 里声明可选音源。
2. **fps 限制**:`properties.fps` 经 `applyGeneralProperties` 下发,WE 不会替壁纸限流,自行实现。
3. `setPaused` 不实现(WE 会整体冻结进程)。
## 实现要点
- **音源优先级**:用户自填 URL(`audio_file`)> `bgm` 选中的音源 > 本壁纸默认音源。
所选音源**只在本壁纸声明过时才生效**;不属于当前壁纸则音频回落本壁纸默认,
**选择本身保留**,切回那份壁纸时用户的选择还在。
- **门控绘制**:包裹实例上的 `drawFrame`。播放器循环写作
`requestAnimationFrame(() => this.drawFrame())`——箭头闭包在调用时才读 `this.drawFrame`,
所以在实例上换掉它就能接管排程。
- 原实现只在**真正绘制**时才排下一帧,而被限流丢掉的帧同样要排,否则循环停摆;
因此排程由包装层负责,再让原实现以 `requestNextFrame = false` 调用。
- **踩到的坑**:朴素地"距上一帧不足 `interval` 就丢"会把 rAF 抖动放大成整拍丢失——
目标 30fps 时落在 33.2ms 的那一帧被判为不足 33.33ms 而丢掉,实测只有 **22.5fps**。
改为"留 4ms 容差 + 到期时间按固定步长推进"后精确到 30.0。
- **另一个坑**:`if (properties.fps)` 的真值判断会把 `fps: 0`(取消限流)整个吞掉,
改判 `!== undefined`。
## 验收
`node .scratch/test-props.mjs`:
| 项目 | 结果 |
| --- | --- |
| bgm 切音源即时生效 | ✓(10 项音源断言全过) |
| 跨壁纸回落 + 选择保留 | ✓ xilian 选「昔涟」→ 切 kv37 回落 pv37 → 切回 xilian 回落默认 |
| 自定义 URL 优先级最高且不被切壁纸清掉 | ✓ |
| 限 30 / 20 / 取消限流 | 实测 **30.0 / 20.0 / 60.0 fps** |
| 不影响动画相位推进速度 | 0.999 / 0.999 / 1.000 倍速(基准 1.000) |