modern-canvas 0.23.4 → 0.23.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3644,19 +3644,29 @@ var $n = class extends w {
3644
3644
  return u(e);
3645
3645
  }
3646
3646
  static linearGradient(e, t, n) {
3647
- t ||= 1, n ||= 1;
3648
- let r = S(t, n);
3649
- if (!r) throw Error("GradientTexture requires a canvas; call setCanvasFactory() in non-browser environments.");
3650
- let i = r.getContext("2d");
3651
- if (!i) throw Error("Failed to parse linear gradient, get canvas context is null.");
3652
- let { angle: a = 0, stops: o } = e, s = t, c = n, l = s / 2, u = c / 2, d = (a + 90) * Math.PI / 180, f = Math.sin(d), p = -Math.cos(d), m = Math.abs(s * Math.sin(d)) + Math.abs(c * Math.cos(d)), h = l - m / 2 * f, g = u - m / 2 * p, ee = l + m / 2 * f, te = u + m / 2 * p, ne = i.createLinearGradient(h, g, ee, te);
3653
- for (let e of o) ne.addColorStop(e.offset, e.color);
3654
- i.fillStyle = ne, i.fillRect(0, 0, s, c);
3655
- let re = i.getImageData(0, 0, r.width, r.height);
3647
+ let r = Number.isFinite(t) && t > 0, i = Number.isFinite(n) && n > 0, a = Number.isFinite(e.angle);
3648
+ t = r ? t : 1, n = i ? n : 1;
3649
+ let o = S(t, n);
3650
+ if (!o) throw Error("GradientTexture requires a canvas; call setCanvasFactory() in non-browser environments.");
3651
+ let s = o.getContext("2d");
3652
+ if (!s) throw Error("Failed to parse linear gradient, get canvas context is null.");
3653
+ let { stops: c } = e, l = t, u = n;
3654
+ if (!r || !i || !a) s.fillStyle = c?.find((e) => e?.color)?.color ?? "transparent", s.fillRect(0, 0, l, u);
3655
+ else {
3656
+ let t = e.angle, n = l / 2, r = u / 2, i = (t + 90) * Math.PI / 180, a = Math.sin(i), o = -Math.cos(i), d = Math.abs(l * Math.sin(i)) + Math.abs(u * Math.cos(i)), f = s.createLinearGradient(n - d / 2 * a, r - d / 2 * o, n + d / 2 * a, r + d / 2 * o);
3657
+ for (let e of c) {
3658
+ let t = Number.isFinite(e.offset) ? Math.min(1, Math.max(0, e.offset)) : 0;
3659
+ try {
3660
+ f.addColorStop(t, e.color);
3661
+ } catch {}
3662
+ }
3663
+ s.fillStyle = f, s.fillRect(0, 0, l, u);
3664
+ }
3665
+ let d = s.getImageData(0, 0, o.width, o.height);
3656
3666
  return {
3657
- width: re.width,
3658
- height: re.height,
3659
- source: new Uint8Array(re.data.buffer),
3667
+ width: d.width,
3668
+ height: d.height,
3669
+ source: new Uint8Array(d.data.buffer),
3660
3670
  uploadMethodId: "buffer"
3661
3671
  };
3662
3672
  }
@@ -6728,16 +6738,13 @@ var ki = class extends J {
6728
6738
  });
6729
6739
  }
6730
6740
  async _resolveSourceCanvas() {
6731
- this._sourceImage !== this.image && (this._sourceCanvas = void 0, this._sourceImage = this.image);
6732
- let e = this.texture?.source;
6733
- if (e && e.width > 0 && e.height > 0) return this._sourceCanvas = this._snapshot(e);
6734
- if (this._sourceCanvas) return this._sourceCanvas;
6741
+ if (this._sourceImage !== this.image && (this._sourceCanvas = void 0, this._sourceImage = this.image), this._sourceCanvas) return this._sourceCanvas;
6735
6742
  if (d(this.image) || this.image === "viewport") return;
6736
- let t = this.image, n = await $.loadBy(`${t}#mc-foreground-source`, async () => {
6737
- let e = await $.fetchImageBitmap(t), n = this._snapshot(e);
6738
- return Ne && e instanceof ImageBitmap && e.close(), n;
6743
+ let e = this.image, t = await $.loadBy(`${e}#mc-foreground-source`, async () => {
6744
+ let t = await $.fetchImageBitmap(e), n = this._snapshot(t);
6745
+ return Ne && t instanceof ImageBitmap && t.close(), n;
6739
6746
  });
6740
- return this._sourceImage === t && (this._sourceCanvas = n), n;
6747
+ return this._sourceImage === e && t && (this._sourceCanvas = t), t;
6741
6748
  }
6742
6749
  _snapshot(e) {
6743
6750
  let t = Math.max(1, Math.round(e.width)), n = Math.max(1, Math.round(e.height)), r = S(t, n), i = r?.getContext("2d");
@@ -11,10 +11,11 @@ export declare class Element2DForeground extends Element2DFill implements Normal
11
11
  /**
12
12
  * 原图的 CPU 副本(HTMLCanvas),供烘焙 effects 使用。
13
13
  *
14
- * 不能依赖 `this.texture.source`:那是张 ImageBitmap,经 GPU 上传 / 资源 GC 后
15
- * 会被 `close()`(detached,width/height 归零),此时 drawImage 会抛
16
- * `InvalidStateError`。实测纹理加载返回时 source 往往已是 detached,故这份副本
17
- * 必须从图片自身独立解码(见 `_resolveSourceCanvas`),与 GPU 纹理生命周期解耦。
14
+ * 刻意不读 `this.texture.source`:那张 ImageBitmap 由纹理管线持有,会经 GPU
15
+ * 上传(premultiply)/ 资源 GC 而被消费或 `close()`,其内容与尺寸随运行环境
16
+ * (含 headless / 自定义 canvas factory)漂移——实测过空白、尺寸异常(如
17
+ * 3552×3552 全透明)。这份副本一律由 `_resolveSourceCanvas` image 独立解码,
18
+ * 与 GPU 纹理生命周期彻底解耦。
18
19
  */
19
20
  protected _sourceCanvas?: HTMLCanvasElement;
20
21
  /** `_sourceCanvas` 对应的图片地址,image 变更时用于失效旧副本 */
@@ -22,12 +23,12 @@ export declare class Element2DForeground extends Element2DFill implements Normal
22
23
  setProperties(properties?: Foreground): this;
23
24
  protected _updateProperty(key: string, value: any, oldValue: any): void;
24
25
  loadTexture(): Promise<void>;
25
- /** 把原图 + effects 烘焙成一张运行时 canvas,包成 CanvasTexture(gif/无 effects 时跳过) */
26
+ /** 把原图 + effects 烘焙成一张运行时纹理(gif/无 effects 时跳过) */
26
27
  protected _applyEffects(): Promise<void>;
27
28
  /**
28
- * 取得用于烘焙的 CPU 副本:
29
- * 1) 若纹理 source 仍存活(width>0),直接快照(省一次解码);
30
- * 2) 否则从 image 重新解码一份(资源层按 url 缓存复用,避免重复烘焙时反复解码)。
29
+ * 取得用于烘焙的 CPU 副本:始终从 image 独立解码一份(createImageBitmap 保证解码
30
+ * 就绪),快照进 canvas,按 url 在资源层缓存复用。不读 `this.texture.source`——见
31
+ * `_sourceCanvas` 注释。只缓存真正拿到的副本,避免把空/未就绪结果钉死。
31
32
  */
32
33
  protected _resolveSourceCanvas(): Promise<HTMLCanvasElement | undefined>;
33
34
  /** 把一张存活的图源画进新 canvas(不会被 close,可反复用于烘焙) */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "modern-canvas",
3
3
  "type": "module",
4
- "version": "0.23.4",
4
+ "version": "0.23.6",
5
5
  "packageManager": "pnpm@10.19.0",
6
6
  "description": "A JavaScript WebGL rendering engine. only the ESM.",
7
7
  "author": "wxm",