fix(ui): fix layer debug

This commit is contained in:
psychedelicious 2024-04-12 16:28:00 +10:00 committed by Kent Keirsey
parent 8911017bd1
commit e7523bd1d9
5 changed files with 56 additions and 18 deletions

View File

@ -26,7 +26,7 @@ export const LayerColorPicker = ({ id }: Props) => {
<ColorPreview previewColor={layer.color} />
</PopoverTrigger>
<PopoverContent>
<PopoverBody w={64} h={64}>
<PopoverBody minH={64}>
<RgbColorPicker color={layer.color} onChange={onColorChange} withNumberInput />
</PopoverBody>
</PopoverContent>

View File

@ -5,7 +5,13 @@ import { LayerBoundingBox } from 'features/regionalPrompts/components/LayerBound
import { LineComponent } from 'features/regionalPrompts/components/LineComponent';
import { RectComponent } from 'features/regionalPrompts/components/RectComponent';
import { useLayer } from 'features/regionalPrompts/hooks/layerStateHooks';
import { $stage, layerBboxChanged, layerTranslated } from 'features/regionalPrompts/store/regionalPromptsSlice';
import {
$stage,
layerBboxChanged,
layerTranslated,
REGIONAL_PROMPT_LAYER_NAME,
REGIONAL_PROMPT_LAYER_OBJECT_GROUP_NAME,
} from 'features/regionalPrompts/store/regionalPromptsSlice';
import { getKonvaLayerBbox } from 'features/regionalPrompts/util/bbox';
import type { Group as KonvaGroupType } from 'konva/lib/Group';
import type { Layer as KonvaLayerType } from 'konva/lib/Layer';
@ -19,7 +25,8 @@ type Props = {
id: string;
};
const filterChildren = (item: KonvaNodeType<KonvaNodeConfigType>) => item.name() !== 'regionalPromptLayerObjectGroup';
export const selectPromptLayerObjectGroup = (item: KonvaNodeType<KonvaNodeConfigType>) =>
item.name() !== REGIONAL_PROMPT_LAYER_OBJECT_GROUP_NAME;
export const LayerComponent: React.FC<Props> = ({ id }) => {
const dispatch = useAppDispatch();
@ -74,7 +81,7 @@ export const LayerComponent: React.FC<Props> = ({ id }) => {
onChangeBbox(null);
return;
}
onChangeBbox(getKonvaLayerBbox(layerRef.current, filterChildren));
onChangeBbox(getKonvaLayerBbox(layerRef.current, selectPromptLayerObjectGroup));
}, [tool, layer.objects, onChangeBbox]);
if (!layer.isVisible) {
@ -85,8 +92,8 @@ export const LayerComponent: React.FC<Props> = ({ id }) => {
<>
<KonvaLayer
ref={layerRef}
id={`layer-${layer.id}`}
name="regionalPromptLayer"
id={layer.id}
name={REGIONAL_PROMPT_LAYER_NAME}
onDragEnd={onDragEnd}
onDragMove={onDragMove}
dragBoundFunc={dragBoundFunc}
@ -94,7 +101,7 @@ export const LayerComponent: React.FC<Props> = ({ id }) => {
>
<KonvaGroup
id={`layer-${layer.id}-group`}
name="regionalPromptLayerObjectGroup"
name={REGIONAL_PROMPT_LAYER_OBJECT_GROUP_NAME}
ref={groupRef}
listening={false}
>

View File

@ -8,19 +8,23 @@ import { LayerListItem } from 'features/regionalPrompts/components/LayerListItem
import { RegionalPromptsStage } from 'features/regionalPrompts/components/RegionalPromptsStage';
import { ToolChooser } from 'features/regionalPrompts/components/ToolChooser';
import { selectRegionalPromptsSlice } from 'features/regionalPrompts/store/regionalPromptsSlice';
import { getLayerBlobs } from 'features/regionalPrompts/util/getLayerBlobs';
import { getRegionalPromptLayerBlobs } from 'features/regionalPrompts/util/getLayerBlobs';
import { ImageSizeLinear } from 'features/settingsAccordions/components/ImageSettingsAccordion/ImageSizeLinear';
const selectLayerIdsReversed = createSelector(selectRegionalPromptsSlice, (regionalPrompts) =>
regionalPrompts.layers.map((l) => l.id).reverse()
);
const debugBlobs = () => {
getRegionalPromptLayerBlobs(true);
};
export const RegionalPromptsEditor = () => {
const layerIdsReversed = useAppSelector(selectLayerIdsReversed);
return (
<Flex gap={4}>
<Flex flexDir="column" gap={4} flexShrink={0}>
<Button onClick={getLayerBlobs}>DEBUG LAYERS</Button>
<Button onClick={debugBlobs}>DEBUG LAYERS</Button>
<AddLayerButton />
<BrushSize />
<ImageSizeLinear />

View File

@ -270,3 +270,5 @@ export const getStage = (): Konva.Stage => {
assert(stage);
return stage;
};
export const REGIONAL_PROMPT_LAYER_NAME = 'regionalPromptLayer';
export const REGIONAL_PROMPT_LAYER_OBJECT_GROUP_NAME = 'regionalPromptLayerObjectGroup';

View File

@ -1,26 +1,51 @@
import { getStore } from 'app/store/nanostores/store';
import openBase64ImageInTab from 'common/util/openBase64ImageInTab';
import { blobToDataURL } from 'features/canvas/util/blobToDataURL';
import { $stage } from 'features/regionalPrompts/store/regionalPromptsSlice';
import { selectPromptLayerObjectGroup } from 'features/regionalPrompts/components/LayerComponent';
import { $stage, REGIONAL_PROMPT_LAYER_NAME } from 'features/regionalPrompts/store/regionalPromptsSlice';
import Konva from 'konva';
import { assert } from 'tsafe';
export const getLayerBlobs = async () => {
export const getRegionalPromptLayerBlobs = async (preview: boolean = false): Promise<Record<string, Blob>> => {
const state = getStore().getState();
const stage = $stage.get();
assert(stage !== null, 'Stage is null');
const stageLayers = stage.getLayers().filter((l) => l.name() === 'regionalPromptLayer');
for (const layer of stageLayers) {
const regionalPromptLayers = stage.getLayers().filter((l) => l.name() === REGIONAL_PROMPT_LAYER_NAME);
// We need to reconstruct each layer to only output the desired data. This logic mirrors the logic in
// `getKonvaLayerBbox()` in `invokeai/frontend/web/src/features/regionalPrompts/util/bbox.ts`
const offscreenStageContainer = document.createElement('div');
const offscreenStage = new Konva.Stage({
container: offscreenStageContainer,
width: stage.width(),
height: stage.height(),
});
const blobs: Record<string, Blob> = {};
for (const layer of regionalPromptLayers) {
const layerClone = layer.clone();
for (const child of layerClone.getChildren(selectPromptLayerObjectGroup)) {
child.destroy();
}
offscreenStage.add(layerClone);
const blob = await new Promise<Blob>((resolve) => {
layer.toBlob({
offscreenStage.toBlob({
callback: (blob) => {
assert(blob, 'Blob is null');
resolve(blob);
},
});
});
const base64 = await blobToDataURL(blob);
const prompt = state.regionalPrompts.layers.find((l) => l.id === layer.id())?.prompt;
assert(prompt !== undefined, 'Prompt is undefined');
openBase64ImageInTab([{ base64, caption: prompt }]);
blobs[layer.id()] = blob;
if (preview) {
const base64 = await blobToDataURL(blob);
const prompt = state.regionalPrompts.layers.find((l) => l.id === layer.id())?.prompt;
openBase64ImageInTab([{ base64, caption: prompt ?? '' }]);
}
layerClone.destroy();
}
return blobs;
};