mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): image loading fallback for raster layers
This commit is contained in:
parent
51de25122a
commit
40cab08133
@ -115,6 +115,7 @@
|
||||
"githubLabel": "Github",
|
||||
"goTo": "Go to",
|
||||
"hotkeysLabel": "Hotkeys",
|
||||
"loadingImage": "Loading Image",
|
||||
"imageFailedToLoad": "Unable to Load Image",
|
||||
"img2img": "Image To Image",
|
||||
"inpaint": "inpaint",
|
||||
|
@ -2,6 +2,7 @@ import { rgbaColorToString } from 'features/canvas/util/colorToString';
|
||||
import { getObjectGroupId } from 'features/controlLayers/konva/naming';
|
||||
import type { BrushLine, EraserLine, ImageObject, RectShape } from 'features/controlLayers/store/types';
|
||||
import { DEFAULT_RGBA_COLOR } from 'features/controlLayers/store/types';
|
||||
import { t } from 'i18next';
|
||||
import Konva from 'konva';
|
||||
import { getImageDTO } from 'services/api/endpoints/images';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
@ -81,16 +82,58 @@ export const createRectShape = (rectShape: RectShape, layerObjectGroup: Konva.Gr
|
||||
return konvaRect;
|
||||
};
|
||||
|
||||
export const createImageObject = async (
|
||||
const createImagePlaceholderGroup = (
|
||||
imageObject: ImageObject
|
||||
): { konvaPlaceholderGroup: Konva.Group; onError: () => void; onLoading: () => void; onLoaded: () => void } => {
|
||||
const { width, height } = imageObject.image;
|
||||
const konvaPlaceholderGroup = new Konva.Group({ name: 'image-placeholder', listening: false });
|
||||
const konvaPlaceholderRect = new Konva.Rect({
|
||||
fill: 'hsl(220 12% 45% / 1)', // 'base.500'
|
||||
width,
|
||||
height,
|
||||
});
|
||||
const konvaPlaceholderText = new Konva.Text({
|
||||
name: 'image-placeholder-text',
|
||||
fill: 'hsl(220 12% 10% / 1)', // 'base.900'
|
||||
width,
|
||||
height,
|
||||
align: 'center',
|
||||
verticalAlign: 'middle',
|
||||
fontFamily: '"Inter Variable", sans-serif',
|
||||
fontSize: width / 16,
|
||||
fontStyle: '600',
|
||||
text: 'Loading Image',
|
||||
listening: false,
|
||||
});
|
||||
konvaPlaceholderGroup.add(konvaPlaceholderRect);
|
||||
konvaPlaceholderGroup.add(konvaPlaceholderText);
|
||||
|
||||
const onError = () => {
|
||||
konvaPlaceholderText.text(t('common.imageFailedToLoad', 'Image Failed to Load'));
|
||||
};
|
||||
const onLoading = () => {
|
||||
konvaPlaceholderText.text(t('common.loadingImage', 'Loading Image'));
|
||||
};
|
||||
const onLoaded = () => {
|
||||
konvaPlaceholderGroup.destroy();
|
||||
};
|
||||
return { konvaPlaceholderGroup, onError, onLoading, onLoaded };
|
||||
};
|
||||
|
||||
export const createImageObjectGroup = async (
|
||||
imageObject: ImageObject,
|
||||
layerObjectGroup: Konva.Group,
|
||||
name: string
|
||||
): Promise<Konva.Image | null> => {
|
||||
const imageDTO = await getImageDTO(imageObject.image.name);
|
||||
if (!imageDTO) {
|
||||
return null;
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
): Promise<Konva.Group> => {
|
||||
const konvaImageGroup = new Konva.Group({ id: imageObject.id, name, listening: false });
|
||||
const placeholder = createImagePlaceholderGroup(imageObject);
|
||||
konvaImageGroup.add(placeholder.konvaPlaceholderGroup);
|
||||
layerObjectGroup.add(konvaImageGroup);
|
||||
getImageDTO(imageObject.image.name).then((imageDTO) => {
|
||||
if (!imageDTO) {
|
||||
placeholder.onError();
|
||||
return;
|
||||
}
|
||||
const imageEl = new Image();
|
||||
imageEl.onload = () => {
|
||||
const konvaImage = new Konva.Image({
|
||||
@ -99,15 +142,16 @@ export const createImageObject = async (
|
||||
listening: false,
|
||||
image: imageEl,
|
||||
});
|
||||
layerObjectGroup.add(konvaImage);
|
||||
resolve(konvaImage);
|
||||
placeholder.onLoaded();
|
||||
konvaImageGroup.add(konvaImage);
|
||||
};
|
||||
imageEl.onerror = () => {
|
||||
resolve(null);
|
||||
placeholder.onError();
|
||||
};
|
||||
imageEl.id = imageObject.id;
|
||||
imageEl.src = imageDTO.image_url;
|
||||
});
|
||||
return konvaImageGroup;
|
||||
};
|
||||
/**
|
||||
* Creates a konva group for a layer's objects.
|
||||
|
@ -9,14 +9,13 @@ import {
|
||||
import {
|
||||
createBrushLine,
|
||||
createEraserLine,
|
||||
createImageObject,
|
||||
createImageObjectGroup,
|
||||
createObjectGroup,
|
||||
createRectShape,
|
||||
} from 'features/controlLayers/konva/renderers/objects';
|
||||
import { getScaledFlooredCursorPosition, mapId, selectRasterObjects } from 'features/controlLayers/konva/util';
|
||||
import type { RasterLayer, Tool } from 'features/controlLayers/store/types';
|
||||
import Konva from 'konva';
|
||||
import { assert } from 'tsafe';
|
||||
|
||||
/**
|
||||
* Logic for creating and rendering raster layers.
|
||||
@ -109,10 +108,7 @@ export const renderRasterLayer = async (
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < layerState.objects.length; i++) {
|
||||
const obj = layerState.objects[i];
|
||||
assert(obj);
|
||||
const zIndex = layerState.objects.length - i;
|
||||
for (const obj of layerState.objects) {
|
||||
if (obj.type === 'brush_line') {
|
||||
const konvaBrushLine =
|
||||
konvaObjectGroup.findOne<Konva.Line>(`#${obj.id}`) ??
|
||||
@ -121,7 +117,6 @@ export const renderRasterLayer = async (
|
||||
if (konvaBrushLine.points().length !== obj.points.length) {
|
||||
konvaBrushLine.points(obj.points);
|
||||
}
|
||||
konvaBrushLine.zIndex(zIndex);
|
||||
} else if (obj.type === 'eraser_line') {
|
||||
const konvaEraserLine =
|
||||
konvaObjectGroup.findOne<Konva.Line>(`#${obj.id}`) ??
|
||||
@ -130,17 +125,14 @@ export const renderRasterLayer = async (
|
||||
if (konvaEraserLine.points().length !== obj.points.length) {
|
||||
konvaEraserLine.points(obj.points);
|
||||
}
|
||||
konvaEraserLine.zIndex(zIndex);
|
||||
} else if (obj.type === 'rect_shape') {
|
||||
const konvaRect =
|
||||
konvaObjectGroup.findOne<Konva.Rect>(`#${obj.id}`) ??
|
||||
if (!konvaObjectGroup.findOne<Konva.Rect>(`#${obj.id}`)) {
|
||||
createRectShape(obj, konvaObjectGroup, RASTER_LAYER_RECT_SHAPE_NAME);
|
||||
konvaRect.zIndex(zIndex);
|
||||
}
|
||||
} else if (obj.type === 'image') {
|
||||
const konvaImage =
|
||||
konvaObjectGroup.findOne<Konva.Image>(`#${obj.id}`) ??
|
||||
(await createImageObject(obj, konvaObjectGroup, RASTER_LAYER_IMAGE_NAME));
|
||||
konvaImage?.zIndex(zIndex);
|
||||
if (!konvaObjectGroup.findOne<Konva.Group>(`#${obj.id}`)) {
|
||||
createImageObjectGroup(obj, konvaObjectGroup, RASTER_LAYER_IMAGE_NAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user