Files
erqiwang_youle/client/js/vendor/README-spine-patches.md
T
2026-08-11 22:17:54 +08:00

126 lines
5.5 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.
# Spine 运行时 vendor 补丁记录
> ⚠️ **升级 `spine-canvas.js` / `spine-webgl.js` 前必读。**
> 这两个文件**不是官方发行版原样**,含本地补丁。直接用官方文件覆盖会导致
> `file://` 协议下资源加载全部失败(表现:所有 Spine 特效不显示)。
## 基线版本
| 文件 | npm 包 | 基线版本 | 字节数 | sha256 |
|---|---|---|---|---|
| `spine-canvas.js` | `@esotericsoftware/spine-canvas` | **4.2.113**(与 4.2.114 官方产物完全相同) | 455670 | `a19ad49c42490d4f41dbc805b0b91d72ccca4236957b2cdab8e57483c3aeb45c` |
| `spine-webgl.js` | `@esotericsoftware/spine-webgl` | **4.2.113** | 553987 | `0c2a0d8cb833297168bac7bbb7821d6ebe87aa11c3708831ca6741468b3d4d25` |
骨架资源导出版本为 **4.2.43**(见 `client/assets/spine/*.json` 的 `skeleton.spine` 字段),
运行时须保持在 **4.2.x** 系列。
官方产物获取地址:
```
https://cdn.jsdelivr.net/npm/@esotericsoftware/spine-canvas@4.2.113/dist/iife/spine-canvas.js
https://cdn.jsdelivr.net/npm/@esotericsoftware/spine-webgl@4.2.113/dist/iife/spine-webgl.js
```
官方原始产物 sha256(用于确认下载无误):
- spine-canvas 4.2.113/114:`b706c28a…`(4.2.43 版,仅作对照,非本项目基线)
- spine-webgl 4.2.113:`e737ac4e7caa9fae…`(打补丁前)
---
## 补丁清单
### 补丁 1 —— `file://` 下不设 `crossOrigin`
**应用于**:`spine-canvas.js`、`spine-webgl.js`
**位置**:`AssetManager.loadTexture` 中构造 `Image` 处(canvas 版约 5798 行 / webgl 版约 5838 行)。
**原因**:`file://` 协议下设置 `image.crossOrigin = "anonymous"` 会使图片被判为跨域而加载失败。
这是 PNG 图集能在 `file://` 下加载的关键。
```js
// 官方
image.crossOrigin = "anonymous";
// 本地
if (typeof location === "undefined" || location.protocol !== "file:")
image.crossOrigin = "anonymous";
```
⚠️ 只改 `loadTexture` 中的 `image`。webgl 版另有 `logoImage` / `spinnerImage`
(约 14004 / 14008 行,属 loading spinner),**不要动**。
---
### 补丁 2 —— 删除 `toLoad === 0` 提前 resolve 分支
**应用于**:仅 `spine-canvas.js`(**`spine-webgl.js` 未移植,保留官方逻辑**)
**位置**:`AssetManager.loadTextureAtlas`(canvas 版官方约 5826-5830 行)。
```js
// 官方(webgl 版保留此段)
if (toLoad === 0) {
this.success(success, path, atlas);
resolve(atlas);
return;
}
```
**行为差异**:官方在 `atlas.pages.length === 0` 时立即 resolve;删除后该情形下 Promise
永不 resolve,`isLoadingComplete()` 恒为 false,全部 Spine 都不会显示。
**未移植到 webgl 版的理由**:本项目 20 个 atlas 文件实测**全部至少 1 页**(共 23 页),
该分支在本项目不可达,删与不删行为完全相同;而官方逻辑在边界情形下更安全。
**注**:此补丁在 `spine-canvas.js` 中随 commit `1f48f4ea`(2026-04-20)打包引入,
提交信息未提及,**原始意图在仓库中无记录可考**。上述为行为分析,非意图推定。
---
### 补丁 3 —— `rawDataUri` 判定改为 `startsWith("data:")`
**应用于**:`spine-canvas.js`(仅 `downloadText`)、`spine-webgl.js`(`downloadText` + `downloadBinary`)
**位置**:`Downloader.downloadText` / `Downloader.downloadBinary`
(canvas 版约 6070 / 6096 行,webgl 版约 6110 / 6136 行)。
```js
// 官方
if (rawDataUri && !rawDataUri.includes(".")) {
// 本地
if (rawDataUri && rawDataUri.startsWith("data:")) {
```
**原因**:`SpineMgr.js` 用 `setRawDataURI(key, "data:," + textData[key])` 注入嵌入的
json/atlas 文本(见 `client/generated/spine_data.js`),以规避 `file://` 下 XHR 的 CORS 拦截。
而 json 文本中必然含小数点(坐标、版本号等),官方那个「不含点才算 data URI」的判定会误判为
非 data URI,导致回退到 XHR 请求而失败。
**两版差异说明**:`spine-canvas.js` 只改了 `downloadText`,因为本项目只用 `loadText`
(json/atlas 均为文本),不走二进制 `.skel` 路径。`spine-webgl.js` 两处都改了 ——
该判定本身是官方的缺陷逻辑,改为 `startsWith("data:")` 在两处均为纯正确性提升、无副作用。
---
## 升级流程
1. 从上述 CDN 取目标版本的官方 iife 产物,记录其原始 sha256。
2. 逐条比对本文件的补丁清单,确认每处补丁点在新版中仍存在且语境未变。
3. 移植补丁时**必须校验匹配次数**(补丁 1 应命中 1 处、补丁 3 应命中 2 处),
匹配数不符即中止并重新核对,不得盲替。
4. 验证产物:`node --check` 语法检查;用 vm 加载并确认关键 API 齐备
(`AssetManager` / `SkeletonJson` / `AtlasAttachmentLoader` / `Skeleton` /
`AnimationState` / `AnimationStateData` / `Physics` / `TextureAtlas`,
webgl 版另需 `SceneRenderer` / `PolygonBatcher` / `GLTexture` /
`ManagedWebGLRenderingContext`)。
5. 更新本文件的版本号与 sha256。
6. 真机验证 `file://` 下资源加载正常(补丁 1、3 的实际验收点)。
## 已知约束
两个文件都以 `var spine = (() => {...})()` 形式暴露**同一个全局名 `spine`**。
**同时加载两者会互相覆盖**,后加载的胜出。因此运行时只能加载其中一个,
或在两次加载之间抢存引用。相关设计见
`docs/superpowers/specs/2026-08-08-spine-webgl-migration-design.md`。