mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-02-13 20:45:17 -05:00
107 lines
2.8 KiB
TypeScript
107 lines
2.8 KiB
TypeScript
import { Mutex } from 'async-mutex';
|
|
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
|
|
import { CanvasModuleBase } from 'features/controlLayers/konva/CanvasModuleBase';
|
|
import { getPrefixedId, loadImage } from 'features/controlLayers/konva/util';
|
|
import Konva from 'konva';
|
|
import type { Logger } from 'roarr';
|
|
|
|
export class CanvasProgressImageModule extends CanvasModuleBase {
|
|
readonly type = 'progress_image';
|
|
readonly id: string;
|
|
readonly path: string[];
|
|
readonly parent: CanvasManager;
|
|
readonly manager: CanvasManager;
|
|
readonly log: Logger;
|
|
|
|
progressImageId: string | null = null;
|
|
konva: {
|
|
group: Konva.Group;
|
|
image: Konva.Image | null; // The image is loaded asynchronously, so it may not be available immediately
|
|
};
|
|
isLoading: boolean = false;
|
|
isError: boolean = false;
|
|
imageElement: HTMLImageElement | null = null;
|
|
|
|
subscriptions = new Set<() => void>();
|
|
|
|
mutex: Mutex = new Mutex();
|
|
|
|
constructor(manager: CanvasManager) {
|
|
super();
|
|
this.id = getPrefixedId(this.type);
|
|
this.parent = manager;
|
|
this.manager = manager;
|
|
this.path = this.manager.buildPath(this);
|
|
this.log = this.manager.buildLogger(this);
|
|
|
|
this.log.debug('Creating progress image module');
|
|
|
|
this.konva = {
|
|
group: new Konva.Group({ name: `${this.type}:group`, listening: false }),
|
|
image: null,
|
|
};
|
|
|
|
this.subscriptions.add(this.manager.stateApi.$lastCanvasProgressEvent.listen(this.render));
|
|
}
|
|
|
|
getNodes = () => {
|
|
return [this.konva.group];
|
|
};
|
|
|
|
render = async () => {
|
|
const release = await this.mutex.acquire();
|
|
|
|
const event = this.manager.stateApi.$lastCanvasProgressEvent.get();
|
|
|
|
if (!event) {
|
|
this.konva.group.visible(false);
|
|
this.imageElement = null;
|
|
this.isLoading = false;
|
|
this.isError = false;
|
|
release();
|
|
return;
|
|
}
|
|
|
|
this.isLoading = true;
|
|
|
|
const { x, y, width, height } = this.manager.stateApi.getBbox().rect;
|
|
const { dataURL } = event.progress_image;
|
|
try {
|
|
this.imageElement = await loadImage(dataURL);
|
|
if (this.konva.image) {
|
|
this.konva.image.setAttrs({
|
|
image: this.imageElement,
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
});
|
|
} else {
|
|
this.konva.image = new Konva.Image({
|
|
name: `${this.type}:image`,
|
|
listening: false,
|
|
image: this.imageElement,
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
});
|
|
this.konva.group.add(this.konva.image);
|
|
}
|
|
this.konva.group.visible(true);
|
|
} catch {
|
|
this.isError = true;
|
|
} finally {
|
|
this.isLoading = false;
|
|
release();
|
|
}
|
|
};
|
|
|
|
destroy = () => {
|
|
this.log.debug('Destroying module');
|
|
this.subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
this.subscriptions.clear();
|
|
this.konva.group.destroy();
|
|
};
|
|
}
|