feat(canvas): move image pipeline rendering off main thread with worker fallback
This commit is contained in:
@@ -1,6 +1,19 @@
|
||||
const imageBitmapCache = new Map<string, Promise<ImageBitmap>>();
|
||||
|
||||
export async function loadSourceBitmap(sourceUrl: string): Promise<ImageBitmap> {
|
||||
type LoadSourceBitmapOptions = {
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
|
||||
function throwIfAborted(signal: AbortSignal | undefined): void {
|
||||
if (signal?.aborted) {
|
||||
throw new DOMException("The operation was aborted.", "AbortError");
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadSourceBitmap(
|
||||
sourceUrl: string,
|
||||
options: LoadSourceBitmapOptions = {},
|
||||
): Promise<ImageBitmap> {
|
||||
if (!sourceUrl || sourceUrl.trim().length === 0) {
|
||||
throw new Error("Render sourceUrl is required.");
|
||||
}
|
||||
@@ -9,6 +22,19 @@ export async function loadSourceBitmap(sourceUrl: string): Promise<ImageBitmap>
|
||||
throw new Error("ImageBitmap is not available in this environment.");
|
||||
}
|
||||
|
||||
throwIfAborted(options.signal);
|
||||
|
||||
if (options.signal) {
|
||||
const response = await fetch(sourceUrl, { signal: options.signal });
|
||||
if (!response.ok) {
|
||||
throw new Error(`Render source failed: ${response.status}`);
|
||||
}
|
||||
|
||||
const blob = await response.blob();
|
||||
throwIfAborted(options.signal);
|
||||
return await createImageBitmap(blob);
|
||||
}
|
||||
|
||||
const cached = imageBitmapCache.get(sourceUrl);
|
||||
if (cached) {
|
||||
return await cached;
|
||||
|
||||
Reference in New Issue
Block a user