feat(ui): document bounds overlay

This commit is contained in:
psychedelicious 2024-06-17 17:53:30 +10:00
parent aea03b4e92
commit b76e0ab4e4
3 changed files with 65 additions and 1 deletions

View File

@ -11,6 +11,7 @@ import {
debouncedRenderers, debouncedRenderers,
renderers as normalRenderers, renderers as normalRenderers,
} from 'features/controlLayers/konva/renderers/layers'; } from 'features/controlLayers/konva/renderers/layers';
import { renderDocumentBoundsOverlay } from 'features/controlLayers/konva/renderers/previewLayer';
import { renderLayers } from 'features/controlLayers/konva/renderers/rasterLayer'; import { renderLayers } from 'features/controlLayers/konva/renderers/rasterLayer';
import { renderRegions } from 'features/controlLayers/konva/renderers/rgLayer'; import { renderRegions } from 'features/controlLayers/konva/renderers/rgLayer';
import { import {
@ -298,6 +299,7 @@ const useStageRenderer = (stage: Konva.Stage, container: HTMLDivElement | null,
scale: stage.scaleX(), scale: stage.scaleX(),
}); });
renderBackgroundLayer(stage); renderBackgroundLayer(stage);
renderDocumentBoundsOverlay(stage, $document.get);
}; };
const resizeObserver = new ResizeObserver(fitStageToContainer); const resizeObserver = new ResizeObserver(fitStageToContainer);
@ -328,6 +330,7 @@ const useStageRenderer = (stage: Konva.Stage, container: HTMLDivElement | null,
}, [ }, [
asPreview, asPreview,
currentFill, currentFill,
document,
isDrawing, isDrawing,
isMouseDown, isMouseDown,
lastCursorPos, lastCursorPos,
@ -372,6 +375,10 @@ const useStageRenderer = (stage: Konva.Stage, container: HTMLDivElement | null,
renderControlAdapters(stage, controlAdapters, getImageDTO); renderControlAdapters(stage, controlAdapters, getImageDTO);
}, [controlAdapters, stage]); }, [controlAdapters, stage]);
useLayoutEffect(() => {
renderDocumentBoundsOverlay(stage, $document.get);
}, [stage, document]);
useLayoutEffect(() => { useLayoutEffect(() => {
arrangeEntities(stage, layers, controlAdapters, regions); arrangeEntities(stage, layers, controlAdapters, regions);
}, [layers, controlAdapters, regions, stage]); }, [layers, controlAdapters, regions, stage]);

View File

@ -1,5 +1,5 @@
import { renderBackgroundLayer } from 'features/controlLayers/konva/renderers/background'; import { renderBackgroundLayer } from 'features/controlLayers/konva/renderers/background';
import { scaleToolPreview } from 'features/controlLayers/konva/renderers/previewLayer'; import { renderDocumentBoundsOverlay, scaleToolPreview } from 'features/controlLayers/konva/renderers/previewLayer';
import { getScaledFlooredCursorPosition } from 'features/controlLayers/konva/util'; import { getScaledFlooredCursorPosition } from 'features/controlLayers/konva/util';
import type { import type {
BrushLineAddedArg, BrushLineAddedArg,
@ -469,6 +469,7 @@ export const setStageEventHandlers = ({
setStageAttrs({ ...newPos, width: stage.width(), height: stage.height(), scale: newScale }); setStageAttrs({ ...newPos, width: stage.width(), height: stage.height(), scale: newScale });
renderBackgroundLayer(stage); renderBackgroundLayer(stage);
scaleToolPreview(stage, getToolState()); scaleToolPreview(stage, getToolState());
renderDocumentBoundsOverlay(stage, getDocument);
} }
}); });
@ -482,6 +483,7 @@ export const setStageEventHandlers = ({
scale: stage.scaleX(), scale: stage.scaleX(),
}); });
renderBackgroundLayer(stage); renderBackgroundLayer(stage);
renderDocumentBoundsOverlay(stage, getDocument);
}); });
//#region dragend //#region dragend
@ -526,6 +528,7 @@ export const setStageEventHandlers = ({
setStageAttrs({ x, y, width, height, scale }); setStageAttrs({ x, y, width, height, scale });
scaleToolPreview(stage, getToolState()); scaleToolPreview(stage, getToolState());
renderBackgroundLayer(stage); renderBackgroundLayer(stage);
renderDocumentBoundsOverlay(stage, getDocument);
} }
}; };
window.addEventListener('keydown', onKeyDown); window.addEventListener('keydown', onKeyDown);

View File

@ -1,3 +1,4 @@
import { getArbitraryBaseColor } from '@invoke-ai/ui-library';
import { rgbaColorToString } from 'common/util/colorCodeTransformers'; import { rgbaColorToString } from 'common/util/colorCodeTransformers';
import { roundToMultiple, roundToMultipleMin } from 'common/util/roundDownToMultiple'; import { roundToMultiple, roundToMultipleMin } from 'common/util/roundDownToMultiple';
import { import {
@ -449,3 +450,56 @@ export const scaleToolPreview = (stage: Konva.Stage, toolState: CanvasV2State['t
?.findOne<Konva.Circle>(`#${PREVIEW_BRUSH_BORDER_OUTER_ID}`) ?.findOne<Konva.Circle>(`#${PREVIEW_BRUSH_BORDER_OUTER_ID}`)
?.setAttrs({ strokeWidth: BRUSH_ERASER_BORDER_WIDTH / scale, radius: radius + BRUSH_ERASER_BORDER_WIDTH / scale }); ?.setAttrs({ strokeWidth: BRUSH_ERASER_BORDER_WIDTH / scale, radius: radius + BRUSH_ERASER_BORDER_WIDTH / scale });
}; };
const getDocumentOverlayGroup = (stage: Konva.Stage): Konva.Group => {
const previewLayer = getPreviewLayer(stage);
let documentOverlayGroup = previewLayer.findOne<Konva.Group>('#document_overlay_group');
if (documentOverlayGroup) {
return documentOverlayGroup;
}
documentOverlayGroup = new Konva.Group({ id: 'document_overlay_group', listening: false });
const documentOverlayOuterRect = new Konva.Rect({
id: 'document_overlay_outer_rect',
listening: false,
fill: getArbitraryBaseColor(10),
opacity: 0.7,
});
const documentOverlayInnerRect = new Konva.Rect({
id: 'document_overlay_inner_rect',
listening: false,
fill: 'white',
globalCompositeOperation: 'destination-out',
});
documentOverlayGroup.add(documentOverlayOuterRect);
documentOverlayGroup.add(documentOverlayInnerRect);
previewLayer.add(documentOverlayGroup);
return documentOverlayGroup;
};
export const renderDocumentBoundsOverlay = (stage: Konva.Stage, getDocument: () => CanvasV2State['document']): void => {
const document = getDocument();
const documentOverlayGroup = getDocumentOverlayGroup(stage);
documentOverlayGroup.zIndex(0);
const x = stage.x();
const y = stage.y();
const width = stage.width();
const height = stage.height();
const scale = stage.scaleX();
documentOverlayGroup.findOne<Konva.Rect>('#document_overlay_outer_rect')?.setAttrs({
offsetX: x / scale,
offsetY: y / scale,
width: width / scale,
height: height / scale,
});
documentOverlayGroup.findOne<Konva.Rect>('#document_overlay_inner_rect')?.setAttrs({
x: 0,
y: 0,
width: document.width,
height: document.height,
});
};