@taole/giftstage 0.1.27 → 0.1.29

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.
Files changed (74) hide show
  1. package/README.md +667 -605
  2. package/dist/core/audio-manager.d.ts +19 -0
  3. package/dist/core/gift-stage.d.ts +117 -0
  4. package/dist/core/index.d.ts +4 -0
  5. package/dist/core/post-animator.d.ts +43 -0
  6. package/dist/core/render-manager.d.ts +99 -0
  7. package/dist/core/webcodecs-video-atlas.d.ts +30 -0
  8. package/dist/gift-stage.cjs.js +198 -171
  9. package/dist/gift-stage.es.js +2806 -2255
  10. package/dist/gpu/detect.d.ts +2 -0
  11. package/dist/gpu/gl-utils.d.ts +10 -0
  12. package/dist/gpu/index.d.ts +3 -0
  13. package/dist/gpu/webgl1-backend.d.ts +43 -0
  14. package/dist/gpu/webgl2-backend.d.ts +69 -0
  15. package/dist/gpu/webgpu-backend.d.ts +155 -0
  16. package/dist/index.d.ts +27 -0
  17. package/dist/parsers/atlas-builder.d.ts +37 -0
  18. package/dist/parsers/atlas-packing.d.ts +31 -0
  19. package/dist/parsers/index.d.ts +7 -0
  20. package/dist/parsers/inflate-js.d.ts +37 -0
  21. package/dist/parsers/svga-image-decode-worker-client.d.ts +14 -0
  22. package/dist/parsers/svga-parser-worker-client.d.ts +31 -0
  23. package/dist/parsers/svga-parser.d.ts +49 -0
  24. package/dist/parsers/svga-proto-js.d.ts +7 -0
  25. package/dist/parsers/svga-sprite-table-binary.d.ts +36 -0
  26. package/dist/parsers/svga-sprite-table.d.ts +59 -0
  27. package/dist/parsers/svga-worker-payload-binary.d.ts +10 -0
  28. package/dist/parsers/vap-config-parser.d.ts +20 -0
  29. package/dist/renderers/alpha-video-renderer.d.ts +48 -0
  30. package/dist/renderers/image-renderer.d.ts +15 -0
  31. package/dist/renderers/index.d.ts +4 -0
  32. package/dist/renderers/svga-batch-renderer.d.ts +113 -0
  33. package/dist/renderers/vap-renderer.d.ts +58 -0
  34. package/dist/renderers/vertex-builder.d.ts +5 -0
  35. package/dist/shaders/index.d.ts +49 -0
  36. package/dist/types/index.d.ts +699 -0
  37. package/dist/utils/abort.d.ts +3 -0
  38. package/dist/utils/atlas-constants.d.ts +9 -0
  39. package/dist/utils/buffer-pool.d.ts +14 -0
  40. package/dist/utils/canvas-dpr.d.ts +37 -0
  41. package/dist/utils/clip-mesh.d.ts +6 -0
  42. package/dist/utils/detect.d.ts +7 -0
  43. package/dist/utils/easing.d.ts +7 -0
  44. package/dist/utils/frame-budget.d.ts +36 -0
  45. package/dist/utils/gift-object-fit.d.ts +14 -0
  46. package/dist/utils/gift-position.d.ts +5 -0
  47. package/dist/utils/gift-size.d.ts +11 -0
  48. package/dist/utils/gift-transform.d.ts +29 -0
  49. package/dist/utils/html-video-upload-gate.d.ts +35 -0
  50. package/dist/utils/image-source.d.ts +9 -0
  51. package/dist/utils/math.d.ts +9 -0
  52. package/dist/utils/resource-cache.d.ts +20 -0
  53. package/dist/utils/slot-content.d.ts +17 -0
  54. package/dist/utils/svg-path-parser.d.ts +11 -0
  55. package/dist/utils/svga-binary-cache.d.ts +26 -0
  56. package/dist/utils/svga-work-scheduler.d.ts +7 -0
  57. package/dist/utils/triangulate.d.ts +11 -0
  58. package/dist/utils/utf8.d.ts +2 -0
  59. package/dist/utils/vap-mix-composer.d.ts +26 -0
  60. package/dist/utils/wc-atlas-upload-size.d.ts +9 -0
  61. package/dist/video/mp4box-loader.d.ts +2 -0
  62. package/dist/video/webcodecs-mp4-core.d.ts +49 -0
  63. package/dist/video/webcodecs-mp4-playback.d.ts +71 -0
  64. package/dist/video/webcodecs-mp4.worker.d.ts +18 -0
  65. package/dist/wasm/wasm-bridge.d.ts +36 -0
  66. package/dist/workers/parser-worker.d.ts +13 -0
  67. package/dist/workers/svga-atlas-worker-client.d.ts +25 -0
  68. package/dist/workers/svga-atlas-worker.d.ts +37 -0
  69. package/dist/workers/svga-clip-worker-client.d.ts +6 -0
  70. package/dist/workers/svga-clip-worker.d.ts +17 -0
  71. package/dist/workers/svga-image-decode-worker.d.ts +19 -0
  72. package/dist/workers/vertex-worker.d.ts +15 -0
  73. package/dist/workers/worker-scheduler.d.ts +19 -0
  74. package/package.json +7 -5
@@ -0,0 +1,19 @@
1
+ import type { GiftSlot, GiftHandle } from '../types';
2
+ export declare class AudioManager {
3
+ private ctx;
4
+ private decodedCache;
5
+ private activeSources;
6
+ private globalMute;
7
+ private gainNode;
8
+ private ensureContext;
9
+ decodeAudio(key: string, data: ArrayBuffer): Promise<void>;
10
+ /**
11
+ * Frame-synced playback: start audio on startFrame, stop on endFrame.
12
+ * Matches SVGAPlayer-Web-master Canvas/renderer.js playAudio() pattern.
13
+ */
14
+ tickFrame(slot: GiftSlot, currentFrame: number, _handle: GiftHandle): void;
15
+ private startAudio;
16
+ stopAllForGift(giftId: string): void;
17
+ setMute(mute: boolean): void;
18
+ destroy(): void;
19
+ }
@@ -0,0 +1,117 @@
1
+ import type { GiftStageOptions, AddGiftOptions, GiftHandle, BackendType } from '../types';
2
+ export declare function resolveResourcePipelineConcurrency(explicit: number | undefined, hardwareConcurrency?: number | undefined): number;
3
+ export declare class GiftStage {
4
+ private static readonly SVGA_ATLAS_MAX_SIZE;
5
+ private static readonly SVGA_ATLAS_PADDING;
6
+ private static readonly DEFAULT_SHARED_VIDEO_PLAYBACK_WINDOW_MS;
7
+ private static readonly DEFAULT_RESOURCE_CACHE_MEMORY_BYTES;
8
+ private static readonly DEFAULT_RESOURCE_CACHE_PERSISTENT_BYTES;
9
+ private readonly sharedSVGAEntities;
10
+ private readonly pendingSharedSVGAEntities;
11
+ private readonly sharedVideoSources;
12
+ private readonly sharedHtmlVideos;
13
+ private readonly sharedVideoTextures;
14
+ private readonly pendingSharedHtmlVideos;
15
+ private readonly sharedImageTextures;
16
+ private readonly pendingSharedImageTextures;
17
+ private readonly sharedWebCodecsPlaybacks;
18
+ private readonly pendingSharedWebCodecsPlaybacks;
19
+ private readonly sharedWebCodecsSurfaces;
20
+ private readonly completedPlaybackSlots;
21
+ private readonly playbackCompleteWaiters;
22
+ private canvas;
23
+ private backend;
24
+ private manager;
25
+ private options;
26
+ /** Resolves when WebGPU/WebGL backend + WASM are ready; safe to `await` before `addGift`. */
27
+ readonly ready: Promise<void>;
28
+ private destroyed;
29
+ private resizeObserver;
30
+ private nextRenderOrder;
31
+ private nextSharedWebCodecsPlaybackId;
32
+ private nextSharedWebCodecsSurfaceId;
33
+ private readonly onWindowLayout;
34
+ constructor(options: GiftStageOptions);
35
+ private backingStoreDpr;
36
+ private syncCanvasSize;
37
+ private resourcePipelineConcurrency;
38
+ private init;
39
+ private svgaParseOptions;
40
+ private svgaAtlasFrameBudgetMs;
41
+ private svgaClipFrameBudgetMs;
42
+ private isSlotLoadActive;
43
+ private assertSlotLoadActive;
44
+ private isLoadCanceled;
45
+ private currentCanvasCssSize;
46
+ private resolveGiftIntrinsicSize;
47
+ private normalizeAddGiftOptions;
48
+ private resolveAnimationStepTarget;
49
+ private runGiftAnimationStep;
50
+ private createGiftAnimationChain;
51
+ addGift(options: AddGiftOptions): Promise<GiftHandle>;
52
+ private loadSVGA;
53
+ private acquireSharedSVGAEntity;
54
+ private waitForPendingSharedSVGAEntity;
55
+ private buildSharedSVGAEntity;
56
+ private releaseSharedSVGAEntity;
57
+ private createCachedSVGAAtlasTextures;
58
+ private deleteSVGAAtlasTextures;
59
+ private deleteSVGAAtlasResultTextures;
60
+ private finishLoadSVGA;
61
+ private svgaAtlasMaxSize;
62
+ private buildSVGAAtlasIfNeeded;
63
+ private svgaAtlasMaxPages;
64
+ private shouldTryWebCodecs;
65
+ /** DevTools: filter by `[GiftStage]` to see WebCodecs vs &lt;video&gt; per gift. */
66
+ private logPlaybackBackend;
67
+ private tryWebCodecsPlayback;
68
+ private acquireWebCodecsPlayback;
69
+ private acquireSharedWebCodecsPlayback;
70
+ private createPendingSharedWebCodecsPlayback;
71
+ private waitForPendingSharedWebCodecsPlayback;
72
+ private releaseSharedWebCodecsPlayback;
73
+ private attachWebCodecsPlayback;
74
+ private releaseAttachedWebCodecsPlayback;
75
+ private acquireSharedWebCodecsSurface;
76
+ private retainSharedWebCodecsSurface;
77
+ private createSharedWebCodecsSurface;
78
+ private releaseSharedWebCodecsSurface;
79
+ private attachSharedWebCodecsSurface;
80
+ private loadVAP;
81
+ private createVAPMixResourceTextures;
82
+ private loadAlphaVideo;
83
+ /**
84
+ * Some mobile WebKit builds ignore or partially apply `video.loop`; `ended` still fires once.
85
+ * Drive repeat / infinite playback explicitly from `ended` (aligns with SVGA `loop`: 0 = ∞, default 1).
86
+ */
87
+ private bindVideoLoopOnEnded;
88
+ private createVideo;
89
+ private waitVideoMetadata;
90
+ private probeVideoNaturalSize;
91
+ private acquireVideoPlaybackSource;
92
+ private normalizeSharedVideoSourceKey;
93
+ private fetchSharedVideoSource;
94
+ private releaseSharedVideoSource;
95
+ private tryAcquireSharedHtmlVideo;
96
+ private acquireSharedVideoTexture;
97
+ private acquireImageTexture;
98
+ private releaseSharedImageTexture;
99
+ private releaseSharedVideoTexture;
100
+ private releaseSharedHtmlVideo;
101
+ /**
102
+ * After `play()`, wait until at least one frame is presented so WebGPU
103
+ * `copyExternalImageToTexture(<video>)` can import (avoids “no back resource” / early return).
104
+ */
105
+ private waitForFirstVideoFrame;
106
+ private waitVideoReady;
107
+ removeGift(id: string): void;
108
+ removeAll(): void;
109
+ pause(): void;
110
+ resume(): void;
111
+ get activeCount(): number;
112
+ get backendType(): BackendType;
113
+ destroy(): void;
114
+ private markGiftPlaybackComplete;
115
+ private resolveGiftPlaybackWaiters;
116
+ private waitForGiftPlaybackComplete;
117
+ }
@@ -0,0 +1,4 @@
1
+ export { GiftStage } from './gift-stage';
2
+ export { RenderManager } from './render-manager';
3
+ export { AudioManager } from './audio-manager';
4
+ export { PostAnimator } from './post-animator';
@@ -0,0 +1,43 @@
1
+ import type { GiftSlot } from '../types';
2
+ export interface PostAnimationTarget {
3
+ targetX: number;
4
+ targetY: number;
5
+ targetScale: number;
6
+ targetOpacity: number;
7
+ targetRotation?: number;
8
+ duration: number;
9
+ easing: (t: number) => number;
10
+ onComplete?: () => void;
11
+ }
12
+ export declare class PostAnimator {
13
+ private animations;
14
+ private completedScratch;
15
+ private individuallyPaused;
16
+ private globallyPaused;
17
+ startFly(slot: GiftSlot, targetX: number, targetY: number, targetScale: number, duration: number, easing: (t: number) => number, onComplete?: () => void, targetOpacity?: number, targetRotation?: number): void;
18
+ startTween(slot: GiftSlot, targetX: number, targetY: number, targetScale: number, duration: number, easing: (t: number) => number, onComplete?: () => void, onCancel?: () => void, targetOpacity?: number, targetRotation?: number): void;
19
+ startTweenPromise(slot: GiftSlot, targetX: number, targetY: number, targetScale: number, duration: number, easing: (t: number) => number, onComplete?: () => void, targetOpacity?: number, targetRotation?: number): Promise<void>;
20
+ startSequence(slot: GiftSlot, targets: PostAnimationTarget[]): Promise<void>;
21
+ update(now: number): void;
22
+ /**
23
+ * Get the current animated position/scale for a gift.
24
+ * Returns null if no active animation.
25
+ */
26
+ getAnimatedState(giftId: string, now: number): {
27
+ x: number;
28
+ y: number;
29
+ scale: number;
30
+ opacity: number;
31
+ rotation: number;
32
+ } | null;
33
+ applyAnimatedState(slot: GiftSlot, now: number): boolean;
34
+ hasAnimation(giftId: string): boolean;
35
+ hasActiveAnimations(): boolean;
36
+ pauseForGift(giftId: string, now?: number): void;
37
+ resumeForGift(giftId: string, now?: number): void;
38
+ pauseAll(now?: number): void;
39
+ resumeAll(now?: number): void;
40
+ cancelForGift(giftId: string): void;
41
+ releaseGift(giftId: string): void;
42
+ destroy(): void;
43
+ }
@@ -0,0 +1,99 @@
1
+ import type { GPUBackend, GiftSlot, GiftHandle, GPUTextureHandle } from '../types';
2
+ import { type SVGAClipMeshMap } from '../renderers/svga-batch-renderer';
3
+ import { PostAnimator } from './post-animator';
4
+ import { AudioManager } from './audio-manager';
5
+ import { type WebCodecsAtlasRect } from './webcodecs-video-atlas';
6
+ export declare class RenderManager {
7
+ private backend;
8
+ private svgaBatch;
9
+ private vapRenderer;
10
+ private alphaVideoRenderer;
11
+ private imageRenderer;
12
+ readonly postAnimator: PostAnimator;
13
+ readonly audioManager: AudioManager;
14
+ private slots;
15
+ private handles;
16
+ private rafId;
17
+ private lastTime;
18
+ private running;
19
+ private forceNextDraw;
20
+ private readonly onAnimationFrame;
21
+ private readonly finishedSlotIdsScratch;
22
+ private readonly videoRunMapScratch;
23
+ /** Shared WebCodecs RGBA atlas (optional); multiple slots may reference `handle` with distinct `wcAtlasRect`. */
24
+ private wcAtlas;
25
+ /** One-shot logs for WebCodecs clock debugging (filter console by `[GiftStage:WC]`). */
26
+ private readonly wcDbgTickOnce;
27
+ private readonly advancedSharedWebCodecsScratch;
28
+ private readonly activeSharedWebCodecsScratch;
29
+ constructor(backend: GPUBackend);
30
+ addSlot(slot: GiftSlot, handle: GiftHandle): void;
31
+ releaseSlotResources(slot: GiftSlot): void;
32
+ removeSlot(id: string): void;
33
+ getSlot(id: string): GiftSlot | undefined;
34
+ get activeCount(): number;
35
+ getSlotIds(): string[];
36
+ /**
37
+ * Reserve a sub-rectangle in the shared WebCodecs atlas (when `webCodecsVideoAtlas` is configured).
38
+ * Returns null if disabled, full, or size mismatch while the atlas is still in use.
39
+ */
40
+ tryAllocateWebCodecsAtlas(slotId: string, frameW: number, frameH: number, cfg: {
41
+ width: number;
42
+ height: number;
43
+ } | undefined): {
44
+ handle: GPUTextureHandle;
45
+ rect: WebCodecsAtlasRect;
46
+ } | null;
47
+ releaseWebCodecsAtlasAllocation(slotId: string): void;
48
+ /** Re-apply CSS-space options when canvas backing store or layout changes (skips active fly animations). */
49
+ syncSlotLayoutFromOptions(): void;
50
+ private start;
51
+ private stop;
52
+ private clearFrameOnce;
53
+ pause(): void;
54
+ resume(): void;
55
+ prewarmSVGAClipMeshes(entity: NonNullable<GiftSlot['videoEntity']>, options?: {
56
+ frameBudgetMs?: number;
57
+ workerTimeSliceMs?: number;
58
+ useWorker?: boolean;
59
+ checkActive?: () => void;
60
+ signal?: AbortSignal;
61
+ }): Promise<number>;
62
+ hydrateSVGAClipMeshes(meshes: SVGAClipMeshMap | null | undefined): void;
63
+ snapshotSVGAClipMeshes(entity: NonNullable<GiftSlot['videoEntity']>): SVGAClipMeshMap;
64
+ private renderLoop;
65
+ /**
66
+ * Fixed-step frame advancement matching Unity SvgaLitePlayer.Update()
67
+ */
68
+ /**
69
+ * Advance WebCodecs playback clock (mirrors HTMLVideoElement time + `ended` loop semantics).
70
+ */
71
+ private tickSharedWebCodecs;
72
+ private tickWebCodecs;
73
+ private wcDbgLogTickOnce;
74
+ /** Same completion path as `GiftStage.bindVideoLoopOnEnded` for &lt;video&gt;. */
75
+ private onWebCodecsPlaybackComplete;
76
+ private tickSVGA;
77
+ private onGiftPlayComplete;
78
+ private tickImage;
79
+ private removeFinished;
80
+ /** Reused scratch to avoid a per-frame array allocation; consumed synchronously by getRenderLayers. */
81
+ private orderedSlotsScratch;
82
+ private getRenderOrderedSlots;
83
+ private getRenderLayers;
84
+ /**
85
+ * Multiple copies of the same gift are often added together before each copy
86
+ * flies to a different target. While their visual state is exactly identical,
87
+ * drawing every copy only increases overdraw and changes translucent pixels.
88
+ * Keep the top-most copy until a transform or frame diverges.
89
+ */
90
+ private collapseCoincidentVisualDuplicates;
91
+ private getCoincidentVisualKey;
92
+ private getSVGASlotTextureKey;
93
+ private drawLayer;
94
+ private drawSlotRun;
95
+ /** Batch keys are cached on the slot and only rebuilt when their inputs change. */
96
+ private getBatchKey;
97
+ private deleteSVGAAtlasTextures;
98
+ destroy(): void;
99
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Row-packs decoded WebCodecs frames into one RGBA atlas to share a single texture bind across many gifts.
3
+ * Falls back to per-gift textures when allocation fails (returns null).
4
+ */
5
+ export interface WebCodecsAtlasRect {
6
+ x: number;
7
+ y: number;
8
+ w: number;
9
+ h: number;
10
+ }
11
+ export declare class WebCodecsVideoAtlasAllocator {
12
+ private readonly atlasW;
13
+ private readonly atlasH;
14
+ /** Current row: y offset and row height. */
15
+ private rowY;
16
+ private rowH;
17
+ private rowX;
18
+ private readonly slots;
19
+ constructor(atlasW: number, atlasH: number);
20
+ get size(): {
21
+ w: number;
22
+ h: number;
23
+ };
24
+ /**
25
+ * Reserve a `w×h` rectangle (texels). Returns null if it does not fit.
26
+ */
27
+ tryAllocate(slotId: string, w: number, h: number): WebCodecsAtlasRect | null;
28
+ release(slotId: string): void;
29
+ getRect(slotId: string): WebCodecsAtlasRect | undefined;
30
+ }