Files
youle_framework/client/js/vendor/README-spine-patches.md
T
2026-08-19 08:14:48 +08:00

5.5 KiB
Raw Blame History

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:// 下加载的关键。

// 官方
          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 行)。

// 官方(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 行)。

// 官方
      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。