diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-02-23 10:03:15 +0100 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-02-23 10:03:15 +0100 |
| commit | baa5f33407da81463196cde7639592d1fc984494 (patch) | |
| tree | 502f963f8961245f8a7e85194dcd0cf348249ac4 /apps/web/src/services/renderer/nodes/sticker-node.ts | |
| parent | dbfecbba59bb37aa73a133987230f6badecb080c (diff) | |
| download | opencut-baa5f33407da81463196cde7639592d1fc984494.tar.gz | |
fix preview perf issues
Diffstat (limited to 'apps/web/src/services/renderer/nodes/sticker-node.ts')
| -rw-r--r-- | apps/web/src/services/renderer/nodes/sticker-node.ts | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/apps/web/src/services/renderer/nodes/sticker-node.ts b/apps/web/src/services/renderer/nodes/sticker-node.ts index a2fb0170..acf638eb 100644 --- a/apps/web/src/services/renderer/nodes/sticker-node.ts +++ b/apps/web/src/services/renderer/nodes/sticker-node.ts @@ -6,29 +6,46 @@ export interface StickerNodeParams extends VisualNodeParams { stickerId: string; } -export class StickerNode extends VisualNode<StickerNodeParams> { - private image?: HTMLImageElement; - private readyPromise: Promise<void>; +interface CachedStickerSource { + source: HTMLImageElement; + width: number; + height: number; +} - constructor(params: StickerNodeParams) { - super(params); - this.readyPromise = this.load(); - } +const stickerSourceCache = new Map<string, Promise<CachedStickerSource>>(); - private async load() { - const image = new Image(); - this.image = image; +function loadStickerSource(stickerId: string): Promise<CachedStickerSource> { + const cached = stickerSourceCache.get(stickerId); + if (cached) return cached; + + const promise = (async (): Promise<CachedStickerSource> => { const url = resolveStickerId({ - stickerId: this.params.stickerId, + stickerId, options: { width: 200, height: 200 }, }); + const image = new Image(); + await new Promise<void>((resolve, reject) => { image.onload = () => resolve(); image.onerror = () => - reject(new Error(`Failed to load sticker: ${this.params.stickerId}`)); + reject(new Error(`Failed to load sticker: ${stickerId}`)); image.src = url; }); + + return { source: image, width: 200, height: 200 }; + })(); + + stickerSourceCache.set(stickerId, promise); + return promise; +} + +export class StickerNode extends VisualNode<StickerNodeParams> { + private cachedSource: Promise<CachedStickerSource>; + + constructor(params: StickerNodeParams) { + super(params); + this.cachedSource = loadStickerSource(params.stickerId); } async render({ renderer, time }: { renderer: CanvasRenderer; time: number }) { @@ -38,17 +55,13 @@ export class StickerNode extends VisualNode<StickerNodeParams> { return; } - await this.readyPromise; - - if (!this.image) { - return; - } + const { source, width, height } = await this.cachedSource; this.renderVisual({ renderer, - source: this.image, - sourceWidth: 200, - sourceHeight: 200, + source, + sourceWidth: width, + sourceHeight: height, }); } } |
