mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): store all stage attrs in nanostores
This commit is contained in:
parent
2c3ac972e5
commit
154e3e6f64
@ -1,18 +1,20 @@
|
|||||||
import { Box, Flex, Text } from '@invoke-ai/ui-library';
|
import { Box, Flex, Text } from '@invoke-ai/ui-library';
|
||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { $stageScale } from 'features/controlLayers/store/controlLayersSlice';
|
import { $stageAttrs } from 'features/controlLayers/store/controlLayersSlice';
|
||||||
import { round } from 'lodash-es';
|
import { round } from 'lodash-es';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
export const HeadsUpDisplay = memo(() => {
|
export const HeadsUpDisplay = memo(() => {
|
||||||
const stageScale = useStore($stageScale);
|
const stageAttrs = useStore($stageAttrs);
|
||||||
const layerCount = useAppSelector((s) => s.controlLayers.present.layers.length);
|
const layerCount = useAppSelector((s) => s.controlLayers.present.layers.length);
|
||||||
const bbox = useAppSelector((s) => s.controlLayers.present.bbox);
|
const bbox = useAppSelector((s) => s.controlLayers.present.bbox);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex flexDir="column" bg="blackAlpha.400" borderBottomEndRadius="base" p={2} minW={64} gap={2}>
|
<Flex flexDir="column" bg="blackAlpha.400" borderBottomEndRadius="base" p={2} minW={64} gap={2}>
|
||||||
<HUDItem label="Scale" value={round(stageScale, 3)} />
|
<HUDItem label="Scale" value={round(stageAttrs.scale, 3)} />
|
||||||
|
<HUDItem label="Stage Pos" value={`${round(stageAttrs.x, 3)}, ${round(stageAttrs.y, 3)}`} />
|
||||||
|
<HUDItem label="Stage Size" value={`${round(stageAttrs.width, 3)}, ${round(stageAttrs.height, 3)}`} />
|
||||||
<HUDItem label="Layer Count" value={layerCount} />
|
<HUDItem label="Layer Count" value={layerCount} />
|
||||||
<HUDItem label="BBox Size" value={`${bbox.width}×${bbox.height}`} />
|
<HUDItem label="BBox Size" value={`${bbox.width}×${bbox.height}`} />
|
||||||
<HUDItem label="BBox Position" value={`${bbox.x}, ${bbox.y}`} />
|
<HUDItem label="BBox Position" value={`${bbox.x}, ${bbox.y}`} />
|
||||||
|
@ -26,8 +26,7 @@ import {
|
|||||||
$lastMouseDownPos,
|
$lastMouseDownPos,
|
||||||
$selectedLayer,
|
$selectedLayer,
|
||||||
$shouldInvertBrushSizeScrollDirection,
|
$shouldInvertBrushSizeScrollDirection,
|
||||||
$stagePos,
|
$stageAttrs,
|
||||||
$stageScale,
|
|
||||||
$tool,
|
$tool,
|
||||||
$toolBuffer,
|
$toolBuffer,
|
||||||
bboxChanged,
|
bboxChanged,
|
||||||
@ -89,7 +88,6 @@ const useStageRenderer = (stage: Konva.Stage, container: HTMLDivElement | null,
|
|||||||
const lastCursorPos = useStore($lastCursorPos);
|
const lastCursorPos = useStore($lastCursorPos);
|
||||||
const lastMouseDownPos = useStore($lastMouseDownPos);
|
const lastMouseDownPos = useStore($lastMouseDownPos);
|
||||||
const isMouseDown = useStore($isMouseDown);
|
const isMouseDown = useStore($isMouseDown);
|
||||||
const stageScale = useStore($stageScale);
|
|
||||||
const isDrawing = useStore($isDrawing);
|
const isDrawing = useStore($isDrawing);
|
||||||
const brushColor = useAppSelector(selectBrushColor);
|
const brushColor = useAppSelector(selectBrushColor);
|
||||||
const selectedLayer = useAppSelector(selectSelectedLayer);
|
const selectedLayer = useAppSelector(selectSelectedLayer);
|
||||||
@ -197,8 +195,7 @@ const useStageRenderer = (stage: Konva.Stage, container: HTMLDivElement | null,
|
|||||||
$lastMouseDownPos,
|
$lastMouseDownPos,
|
||||||
$lastCursorPos,
|
$lastCursorPos,
|
||||||
$lastAddedPoint,
|
$lastAddedPoint,
|
||||||
$stageScale,
|
$stageAttrs,
|
||||||
$stagePos,
|
|
||||||
$brushSize,
|
$brushSize,
|
||||||
$brushColor,
|
$brushColor,
|
||||||
$brushSpacingPx,
|
$brushSpacingPx,
|
||||||
@ -236,6 +233,13 @@ const useStageRenderer = (stage: Konva.Stage, container: HTMLDivElement | null,
|
|||||||
const fitStageToContainer = () => {
|
const fitStageToContainer = () => {
|
||||||
stage.width(container.offsetWidth);
|
stage.width(container.offsetWidth);
|
||||||
stage.height(container.offsetHeight);
|
stage.height(container.offsetHeight);
|
||||||
|
$stageAttrs.set({
|
||||||
|
x: stage.x(),
|
||||||
|
y: stage.y(),
|
||||||
|
width: stage.width(),
|
||||||
|
height: stage.height(),
|
||||||
|
scale: stage.scaleX(),
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver(fitStageToContainer);
|
const resizeObserver = new ResizeObserver(fitStageToContainer);
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
import { calculateNewBrushSize } from 'features/canvas/hooks/useCanvasZoom';
|
import { calculateNewBrushSize } from 'features/canvas/hooks/useCanvasZoom';
|
||||||
import { CANVAS_SCALE_BY, MAX_CANVAS_SCALE, MIN_CANVAS_SCALE } from 'features/canvas/util/constants';
|
import { CANVAS_SCALE_BY, MAX_CANVAS_SCALE, MIN_CANVAS_SCALE } from 'features/canvas/util/constants';
|
||||||
import { getIsMouseDown, getScaledFlooredCursorPosition, snapPosToStage } from 'features/controlLayers/konva/util';
|
import { getIsMouseDown, getScaledFlooredCursorPosition, snapPosToStage } from 'features/controlLayers/konva/util';
|
||||||
import {
|
import type {
|
||||||
type AddBrushLineArg,
|
AddBrushLineArg,
|
||||||
type AddEraserLineArg,
|
AddEraserLineArg,
|
||||||
type AddPointToLineArg,
|
AddPointToLineArg,
|
||||||
type AddRectShapeArg,
|
AddRectShapeArg,
|
||||||
DEFAULT_RGBA_COLOR,
|
Layer,
|
||||||
type Layer,
|
StageAttrs,
|
||||||
type Tool,
|
Tool,
|
||||||
} from 'features/controlLayers/store/types';
|
} from 'features/controlLayers/store/types';
|
||||||
|
import { DEFAULT_RGBA_COLOR } from 'features/controlLayers/store/types';
|
||||||
import type Konva from 'konva';
|
import type Konva from 'konva';
|
||||||
import type { Vector2d } from 'konva/lib/types';
|
import type { Vector2d } from 'konva/lib/types';
|
||||||
import { clamp } from 'lodash-es';
|
import { clamp } from 'lodash-es';
|
||||||
@ -27,8 +28,7 @@ type SetStageEventHandlersArg = {
|
|||||||
$lastMouseDownPos: WritableAtom<Vector2d | null>;
|
$lastMouseDownPos: WritableAtom<Vector2d | null>;
|
||||||
$lastCursorPos: WritableAtom<Vector2d | null>;
|
$lastCursorPos: WritableAtom<Vector2d | null>;
|
||||||
$lastAddedPoint: WritableAtom<Vector2d | null>;
|
$lastAddedPoint: WritableAtom<Vector2d | null>;
|
||||||
$stageScale: WritableAtom<number>;
|
$stageAttrs: WritableAtom<StageAttrs>;
|
||||||
$stagePos: WritableAtom<Vector2d>;
|
|
||||||
$brushColor: WritableAtom<RgbaColor>;
|
$brushColor: WritableAtom<RgbaColor>;
|
||||||
$brushSize: WritableAtom<number>;
|
$brushSize: WritableAtom<number>;
|
||||||
$brushSpacingPx: WritableAtom<number>;
|
$brushSpacingPx: WritableAtom<number>;
|
||||||
@ -93,8 +93,7 @@ export const setStageEventHandlers = ({
|
|||||||
$lastMouseDownPos,
|
$lastMouseDownPos,
|
||||||
$lastCursorPos,
|
$lastCursorPos,
|
||||||
$lastAddedPoint,
|
$lastAddedPoint,
|
||||||
$stagePos,
|
$stageAttrs,
|
||||||
$stageScale,
|
|
||||||
$brushColor,
|
$brushColor,
|
||||||
$brushSize,
|
$brushSize,
|
||||||
$brushSpacingPx,
|
$brushSpacingPx,
|
||||||
@ -333,15 +332,31 @@ export const setStageEventHandlers = ({
|
|||||||
stage.scaleX(newScale);
|
stage.scaleX(newScale);
|
||||||
stage.scaleY(newScale);
|
stage.scaleY(newScale);
|
||||||
stage.position(newPos);
|
stage.position(newPos);
|
||||||
$stageScale.set(newScale);
|
$stageAttrs.set({ ...newPos, width: stage.width(), height: stage.height(), scale: newScale });
|
||||||
$stagePos.set(newPos);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
stage.on('dragmove', () => {
|
||||||
|
$stageAttrs.set({
|
||||||
|
x: stage.x(),
|
||||||
|
y: stage.y(),
|
||||||
|
width: stage.width(),
|
||||||
|
height: stage.height(),
|
||||||
|
scale: stage.scaleX(),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
stage.on('dragend', () => {
|
stage.on('dragend', () => {
|
||||||
// Stage position should always be an integer, else we get fractional pixels which are blurry
|
// Stage position should always be an integer, else we get fractional pixels which are blurry
|
||||||
stage.x(Math.floor(stage.x()));
|
stage.x(Math.floor(stage.x()));
|
||||||
stage.y(Math.floor(stage.y()));
|
stage.y(Math.floor(stage.y()));
|
||||||
|
$stageAttrs.set({
|
||||||
|
x: stage.x(),
|
||||||
|
y: stage.y(),
|
||||||
|
width: stage.width(),
|
||||||
|
height: stage.height(),
|
||||||
|
scale: stage.scaleX(),
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const onKeyDown = (e: KeyboardEvent) => {
|
const onKeyDown = (e: KeyboardEvent) => {
|
||||||
|
@ -13,6 +13,9 @@ export const PREVIEW_RECT_ID = 'preview_layer.rect';
|
|||||||
export const PREVIEW_GENERATION_BBOX_GROUP = 'preview_layer.gen_bbox_group';
|
export const PREVIEW_GENERATION_BBOX_GROUP = 'preview_layer.gen_bbox_group';
|
||||||
export const PREVIEW_GENERATION_BBOX_TRANSFORMER = 'preview_layer.gen_bbox_transformer';
|
export const PREVIEW_GENERATION_BBOX_TRANSFORMER = 'preview_layer.gen_bbox_transformer';
|
||||||
export const PREVIEW_GENERATION_BBOX_DUMMY_RECT = 'preview_layer.gen_bbox_dummy_rect';
|
export const PREVIEW_GENERATION_BBOX_DUMMY_RECT = 'preview_layer.gen_bbox_dummy_rect';
|
||||||
|
export const PREVIEW_DOCUMENT_SIZE_GROUP = 'preview_layer.doc_size_group';
|
||||||
|
export const PREVIEW_DOCUMENT_SIZE_STAGE_RECT = 'preview_layer.doc_size_stage_rect';
|
||||||
|
export const PREVIEW_DOCUMENT_SIZE_DOCUMENT_RECT = 'preview_layer.doc_size_doc_rect';
|
||||||
|
|
||||||
// Names for Konva layers and objects (comparable to CSS classes)
|
// Names for Konva layers and objects (comparable to CSS classes)
|
||||||
export const LAYER_BBOX_NAME = 'layer.bbox';
|
export const LAYER_BBOX_NAME = 'layer.bbox';
|
||||||
|
@ -60,6 +60,7 @@ import type {
|
|||||||
RasterLayer,
|
RasterLayer,
|
||||||
RegionalGuidanceLayer,
|
RegionalGuidanceLayer,
|
||||||
RgbaColor,
|
RgbaColor,
|
||||||
|
StageAttrs,
|
||||||
Tool,
|
Tool,
|
||||||
} from './types';
|
} from './types';
|
||||||
import {
|
import {
|
||||||
@ -997,8 +998,13 @@ export const $lastCursorPos = atom<Vector2d | null>(null);
|
|||||||
export const $isPreviewVisible = atom(true);
|
export const $isPreviewVisible = atom(true);
|
||||||
export const $lastAddedPoint = atom<Vector2d | null>(null);
|
export const $lastAddedPoint = atom<Vector2d | null>(null);
|
||||||
export const $isSpaceDown = atom(false);
|
export const $isSpaceDown = atom(false);
|
||||||
export const $stageScale = atom<number>(1);
|
export const $stageAttrs = atom<StageAttrs>({
|
||||||
export const $stagePos = atom<Vector2d>({ x: 0, y: 0 });
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
scale: 0,
|
||||||
|
});
|
||||||
|
|
||||||
// Some nanostores that are manually synced to redux state to provide imperative access
|
// Some nanostores that are manually synced to redux state to provide imperative access
|
||||||
// TODO(psyche): This is a hack, figure out another way to handle this...
|
// TODO(psyche): This is a hack, figure out another way to handle this...
|
||||||
|
@ -272,6 +272,7 @@ export type ControlLayersState = {
|
|||||||
bbox: IRect;
|
bbox: IRect;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type StageAttrs = { x: number; y: number; width: number; height: number; scale: number };
|
||||||
export type AddEraserLineArg = { layerId: string; points: [number, number, number, number] };
|
export type AddEraserLineArg = { layerId: string; points: [number, number, number, number] };
|
||||||
export type AddBrushLineArg = AddEraserLineArg & { color: RgbaColor };
|
export type AddBrushLineArg = AddEraserLineArg & { color: RgbaColor };
|
||||||
export type AddPointToLineArg = { layerId: string; point: [number, number] };
|
export type AddPointToLineArg = { layerId: string; point: [number, number] };
|
||||||
|
Loading…
Reference in New Issue
Block a user