From 108ee082d8747ebe0c4dfb41ef930198046c00f2 Mon Sep 17 00:00:00 2001 From: Pihkaal Date: Sat, 13 Dec 2025 18:55:18 +0100 Subject: [PATCH] feat(utils): image loader --- src/utils/loadImages.ts | 52 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/utils/loadImages.ts diff --git a/src/utils/loadImages.ts b/src/utils/loadImages.ts new file mode 100644 index 0000000..3489db7 --- /dev/null +++ b/src/utils/loadImages.ts @@ -0,0 +1,52 @@ +export function loadImage(src: string): Promise { + return new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => resolve(img); + img.onerror = reject; + img.src = src; + }); +} + +export async function loadImages( + ...srcs: string[] +): Promise { + return Promise.all(srcs.map(loadImage)); +} + +export class ImageLoader { + private images: Map = new Map(); + private loadPromise: Promise | null = null; + + constructor(imageSources: Record) { + this.loadPromise = this.loadAll(imageSources); + } + + private async loadAll(imageSources: Record): Promise { + const entries = Object.entries(imageSources); + const images = await loadImages(...entries.map(([_, src]) => src)); + + entries.forEach(([key], index) => { + this.images.set(key, images[index]); + }); + } + + public async ready(): Promise { + await this.loadPromise; + } + + public get isReady(): boolean { + return this.loadPromise !== null && this.images.size > 0; + } + + public get(key: string): HTMLImageElement | undefined { + return this.images.get(key); + } + + public require(key: string): HTMLImageElement { + const image = this.images.get(key); + if (!image) { + throw new Error(`Image not found: ${key}`); + } + return image; + } +}