mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Fixes inpainting + code cleanup
This commit is contained in:
parent
00385240e7
commit
e21e901fa2
@ -698,22 +698,24 @@ class InvokeAIWebServer:
|
||||
|
||||
So we need to convert each into a PIL Image.
|
||||
"""
|
||||
init_img_url = generation_parameters["init_img"]
|
||||
truncated_outpaint_mask_b64 = generation_parameters["init_mask"][:64]
|
||||
|
||||
init_img_url = generation_parameters["init_img"]
|
||||
|
||||
init_img_url = generation_parameters["init_img"]
|
||||
|
||||
init_img_path = self.get_image_path_from_url(init_img_url)
|
||||
|
||||
original_image = Image.open(init_img_path)
|
||||
|
||||
rgba_image = original_image.convert("RGBA")
|
||||
|
||||
# copy a region from it which we will inpaint
|
||||
cropped_init_image = copy_image_from_bounding_box(
|
||||
rgba_image, **generation_parameters["bounding_box"]
|
||||
)
|
||||
|
||||
original_bounding_box = generation_parameters["bounding_box"].copy()
|
||||
|
||||
generation_parameters["init_img"] = cropped_init_image
|
||||
|
||||
# Convert mask dataURL to an image and convert to greyscale
|
||||
|
515
frontend/dist/assets/index.a06633cf.js
vendored
515
frontend/dist/assets/index.a06633cf.js
vendored
File diff suppressed because one or more lines are too long
593
frontend/dist/assets/index.ece4fb83.js
vendored
Normal file
593
frontend/dist/assets/index.ece4fb83.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
frontend/dist/index.html
vendored
4
frontend/dist/index.html
vendored
@ -7,6 +7,7 @@
|
||||
<title>InvokeAI - A Stable Diffusion Toolkit</title>
|
||||
<link rel="shortcut icon" type="icon" href="./assets/favicon.0d253ced.ico" />
|
||||
<<<<<<< refs/remotes/upstream/development
|
||||
<<<<<<< refs/remotes/upstream/development
|
||||
<<<<<<< refs/remotes/upstream/development
|
||||
<script type="module" crossorigin src="./assets/index.a8ba2a6c.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index.40a72c80.css">
|
||||
@ -15,6 +16,9 @@
|
||||
=======
|
||||
<script type="module" crossorigin src="./assets/index.a06633cf.js"></script>
|
||||
>>>>>>> Builds fresh bundle
|
||||
=======
|
||||
<script type="module" crossorigin src="./assets/index.ece4fb83.js"></script>
|
||||
>>>>>>> Fixes inpainting + code cleanup
|
||||
<link rel="stylesheet" href="./assets/index.a44a1287.css">
|
||||
>>>>>>> Builds fresh bundle
|
||||
</head>
|
||||
|
@ -1,9 +1,6 @@
|
||||
import { useEffect } from 'react';
|
||||
import ProgressBar from 'features/system/ProgressBar';
|
||||
import SiteHeader from 'features/system/SiteHeader';
|
||||
import Console from 'features/system/Console';
|
||||
import { useAppDispatch } from './store';
|
||||
import { requestSystemConfig } from './socketio/actions';
|
||||
import { keepGUIAlive } from './utils';
|
||||
import InvokeTabs from 'features/tabs/InvokeTabs';
|
||||
import ImageUploader from 'common/components/ImageUploader';
|
||||
@ -80,8 +77,6 @@ const appSelector = createSelector(
|
||||
);
|
||||
|
||||
const App = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { shouldShowGalleryButton, shouldShowOptionsPanelButton } =
|
||||
useAppSelector(appSelector);
|
||||
|
||||
|
@ -17,7 +17,6 @@ import {
|
||||
modelChangeRequested,
|
||||
setIsProcessing,
|
||||
} from 'features/system/systemSlice';
|
||||
import { inpaintingImageElementRef } from 'features/canvas/IAICanvas';
|
||||
import { InvokeTabName } from 'features/tabs/InvokeTabs';
|
||||
import * as InvokeAI from 'app/invokeai';
|
||||
import { RootState } from 'app/store';
|
||||
@ -57,9 +56,9 @@ const makeSocketIOEmitters = (
|
||||
|
||||
if (['inpainting', 'outpainting'].includes(generationMode)) {
|
||||
const baseCanvasImage = baseCanvasImageSelector(getState());
|
||||
const imageUrl = baseCanvasImage?.url;
|
||||
const imageUrl = baseCanvasImage?.image.url;
|
||||
|
||||
if (!inpaintingImageElementRef.current || !imageUrl) {
|
||||
if (!imageUrl) {
|
||||
dispatch(
|
||||
addLogEntry({
|
||||
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
||||
@ -72,9 +71,6 @@ const makeSocketIOEmitters = (
|
||||
}
|
||||
|
||||
frontendToBackendParametersConfig.imageToProcessUrl = imageUrl;
|
||||
|
||||
// frontendToBackendParametersConfig.maskImageElement =
|
||||
// inpaintingImageElementRef.current;
|
||||
} else if (!['txt2img', 'img2img'].includes(generationMode)) {
|
||||
if (!galleryState.currentImage?.url) return;
|
||||
|
||||
|
@ -32,12 +32,14 @@ import {
|
||||
setInitialImage,
|
||||
setMaskPath,
|
||||
} from 'features/options/optionsSlice';
|
||||
import { requestImages, requestNewImages, requestSystemConfig } from './actions';
|
||||
import {
|
||||
requestImages,
|
||||
requestNewImages,
|
||||
requestSystemConfig,
|
||||
} from './actions';
|
||||
import {
|
||||
addImageToOutpaintingSesion,
|
||||
clearImageToInpaint,
|
||||
setImageToInpaint,
|
||||
setImageToOutpaint,
|
||||
} from 'features/canvas/canvasSlice';
|
||||
import { tabMap } from 'features/tabs/InvokeTabs';
|
||||
|
||||
@ -312,16 +314,11 @@ const makeSocketIOListeners = (
|
||||
|
||||
// remove references to image in options
|
||||
const { initialImage, maskPath } = getState().options;
|
||||
const { inpainting, outpainting } = getState().canvas;
|
||||
|
||||
if (initialImage?.url === url || initialImage === url) {
|
||||
dispatch(clearInitialImage());
|
||||
}
|
||||
|
||||
// if (imageToInpaint?.url === url) {
|
||||
// dispatch(clearImageToInpaint());
|
||||
// }
|
||||
|
||||
if (maskPath === url) {
|
||||
dispatch(setMaskPath(''));
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Heading } from '@chakra-ui/react';
|
||||
import { KeyboardEvent } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
|
||||
type ImageUploadOverlayProps = {
|
||||
|
@ -1,15 +1,13 @@
|
||||
// lib
|
||||
import { MutableRefObject, useEffect, useRef, useState } from 'react';
|
||||
import { MutableRefObject, useRef } from 'react';
|
||||
import Konva from 'konva';
|
||||
import { Layer, Stage } from 'react-konva';
|
||||
import { Image as KonvaImage } from 'react-konva';
|
||||
import { Stage as StageType } from 'konva/lib/Stage';
|
||||
|
||||
// app
|
||||
import { useAppDispatch, useAppSelector } from 'app/store';
|
||||
import { useAppSelector } from 'app/store';
|
||||
import {
|
||||
baseCanvasImageSelector,
|
||||
clearImageToInpaint,
|
||||
currentCanvasSelector,
|
||||
outpaintingCanvasSelector,
|
||||
} from 'features/canvas/canvasSlice';
|
||||
@ -18,8 +16,7 @@ import {
|
||||
import IAICanvasMaskLines from './IAICanvasMaskLines';
|
||||
import IAICanvasBrushPreview from './IAICanvasBrushPreview';
|
||||
import { Vector2d } from 'konva/lib/types';
|
||||
import IAICanvasBoundingBoxPreview from './IAICanvasBoundingBoxPreview';
|
||||
import { useToast } from '@chakra-ui/react';
|
||||
import IAICanvasBoundingBox from './IAICanvasBoundingBox';
|
||||
import useCanvasHotkeys from './hooks/useCanvasHotkeys';
|
||||
import _ from 'lodash';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
@ -32,7 +29,7 @@ import useCanvasMouseMove from './hooks/useCanvasMouseMove';
|
||||
import useCanvasMouseEnter from './hooks/useCanvasMouseEnter';
|
||||
import useCanvasMouseOut from './hooks/useCanvasMouseOut';
|
||||
import useCanvasDragMove from './hooks/useCanvasDragMove';
|
||||
import IAICanvasOutpaintingObjects from './IAICanvasOutpaintingObjects';
|
||||
import IAICanvasObjectRenderer from './IAICanvasObjectRenderer';
|
||||
import IAICanvasGrid from './IAICanvasGrid';
|
||||
import IAICanvasIntermediateImage from './IAICanvasIntermediateImage';
|
||||
import IAICanvasStatusText from './IAICanvasStatusText';
|
||||
@ -46,18 +43,14 @@ const canvasSelector = createSelector(
|
||||
],
|
||||
(currentCanvas, outpaintingCanvas, baseCanvasImage, activeTabName) => {
|
||||
const {
|
||||
shouldInvertMask,
|
||||
isMaskEnabled,
|
||||
shouldShowCheckboardTransparency,
|
||||
stageScale,
|
||||
shouldShowBoundingBox,
|
||||
shouldLockBoundingBox,
|
||||
isTransformingBoundingBox,
|
||||
isMouseOverBoundingBox,
|
||||
isMovingBoundingBox,
|
||||
stageDimensions,
|
||||
stageCoordinates,
|
||||
isMoveStageKeyHeld,
|
||||
tool,
|
||||
isMovingStage,
|
||||
} = currentCanvas;
|
||||
@ -71,7 +64,7 @@ const canvasSelector = createSelector(
|
||||
stageCursor = undefined;
|
||||
} else if (isMouseOverBoundingBox) {
|
||||
stageCursor = 'move';
|
||||
} else {
|
||||
} else if (activeTabName === 'outpainting') {
|
||||
if (isMovingStage) {
|
||||
stageCursor = 'grabbing';
|
||||
} else {
|
||||
@ -83,22 +76,15 @@ const canvasSelector = createSelector(
|
||||
}
|
||||
|
||||
return {
|
||||
shouldInvertMask,
|
||||
isMaskEnabled,
|
||||
shouldShowCheckboardTransparency,
|
||||
stageScale,
|
||||
shouldShowBoundingBox,
|
||||
shouldLockBoundingBox,
|
||||
shouldShowGrid,
|
||||
isTransformingBoundingBox,
|
||||
isModifyingBoundingBox: isTransformingBoundingBox || isMovingBoundingBox,
|
||||
stageCursor,
|
||||
isMouseOverBoundingBox,
|
||||
stageDimensions,
|
||||
stageCoordinates,
|
||||
isMoveStageKeyHeld,
|
||||
activeTabName,
|
||||
baseCanvasImage,
|
||||
isMaskEnabled,
|
||||
isModifyingBoundingBox: isTransformingBoundingBox || isMovingBoundingBox,
|
||||
shouldShowBoundingBox,
|
||||
shouldShowGrid,
|
||||
stageCoordinates,
|
||||
stageCursor,
|
||||
stageDimensions,
|
||||
stageScale,
|
||||
tool,
|
||||
};
|
||||
},
|
||||
@ -112,45 +98,32 @@ const canvasSelector = createSelector(
|
||||
// Use a closure allow other components to use these things... not ideal...
|
||||
export let stageRef: MutableRefObject<StageType | null>;
|
||||
export let canvasImageLayerRef: MutableRefObject<Konva.Layer | null>;
|
||||
export let inpaintingImageElementRef: MutableRefObject<HTMLImageElement | null>;
|
||||
|
||||
const IAICanvas = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const {
|
||||
shouldInvertMask,
|
||||
activeTabName,
|
||||
isMaskEnabled,
|
||||
shouldShowCheckboardTransparency,
|
||||
stageScale,
|
||||
shouldShowBoundingBox,
|
||||
isModifyingBoundingBox,
|
||||
shouldShowBoundingBox,
|
||||
shouldShowGrid,
|
||||
stageCoordinates,
|
||||
stageCursor,
|
||||
stageDimensions,
|
||||
stageCoordinates,
|
||||
shouldShowGrid,
|
||||
activeTabName,
|
||||
baseCanvasImage,
|
||||
stageScale,
|
||||
tool,
|
||||
} = useAppSelector(canvasSelector);
|
||||
|
||||
useCanvasHotkeys();
|
||||
|
||||
const toast = useToast();
|
||||
// set the closure'd refs
|
||||
stageRef = useRef<StageType>(null);
|
||||
canvasImageLayerRef = useRef<Konva.Layer>(null);
|
||||
inpaintingImageElementRef = useRef<HTMLImageElement>(null);
|
||||
|
||||
const lastCursorPositionRef = useRef<Vector2d>({ x: 0, y: 0 });
|
||||
|
||||
// Use refs for values that do not affect rendering, other values in redux
|
||||
const didMouseMoveRef = useRef<boolean>(false);
|
||||
|
||||
// Load the image into this
|
||||
const [canvasBgImage, setCanvasBgImage] = useState<HTMLImageElement | null>(
|
||||
null
|
||||
);
|
||||
|
||||
const handleWheel = useCanvasWheel(stageRef);
|
||||
const handleMouseDown = useCanvasMouseDown(stageRef);
|
||||
const handleMouseUp = useCanvasMouseUp(stageRef, didMouseMoveRef);
|
||||
@ -164,29 +137,6 @@ const IAICanvas = () => {
|
||||
const { handleDragStart, handleDragMove, handleDragEnd } =
|
||||
useCanvasDragMove();
|
||||
|
||||
// Load the image and set the options panel width & height
|
||||
useEffect(() => {
|
||||
if (baseCanvasImage) {
|
||||
const image = new Image();
|
||||
image.onload = () => {
|
||||
inpaintingImageElementRef.current = image;
|
||||
setCanvasBgImage(image);
|
||||
};
|
||||
image.onerror = () => {
|
||||
toast({
|
||||
title: 'Unable to Load Image',
|
||||
description: `Image ${baseCanvasImage.url} failed to load`,
|
||||
status: 'error',
|
||||
isClosable: true,
|
||||
});
|
||||
dispatch(clearImageToInpaint());
|
||||
};
|
||||
image.src = baseCanvasImage.url;
|
||||
} else {
|
||||
setCanvasBgImage(null);
|
||||
}
|
||||
}, [baseCanvasImage, dispatch, stageScale, toast]);
|
||||
|
||||
return (
|
||||
<div className="inpainting-canvas-container">
|
||||
<div className="inpainting-canvas-wrapper">
|
||||
@ -209,36 +159,31 @@ const IAICanvas = () => {
|
||||
onDragMove={handleDragMove}
|
||||
onDragEnd={handleDragEnd}
|
||||
onWheel={handleWheel}
|
||||
listening={
|
||||
tool === 'move' &&
|
||||
!isModifyingBoundingBox &&
|
||||
activeTabName === 'outpainting'
|
||||
}
|
||||
listening={tool === 'move' && !isModifyingBoundingBox}
|
||||
draggable={
|
||||
tool === 'move' &&
|
||||
!isModifyingBoundingBox &&
|
||||
activeTabName === 'outpainting'
|
||||
}
|
||||
>
|
||||
<Layer visible={shouldShowGrid}>
|
||||
<Layer id={'grid'} visible={shouldShowGrid}>
|
||||
<IAICanvasGrid />
|
||||
</Layer>
|
||||
|
||||
<Layer
|
||||
id={'image-layer'}
|
||||
id={'image'}
|
||||
ref={canvasImageLayerRef}
|
||||
listening={false}
|
||||
imageSmoothingEnabled={false}
|
||||
>
|
||||
<IAICanvasOutpaintingObjects />
|
||||
<IAICanvasObjectRenderer />
|
||||
<IAICanvasIntermediateImage />
|
||||
</Layer>
|
||||
<Layer id={'mask-layer'} visible={isMaskEnabled} listening={false}>
|
||||
<Layer id={'mask'} visible={isMaskEnabled} listening={false}>
|
||||
<IAICanvasMaskLines visible={true} listening={false} />
|
||||
|
||||
<IAICanvasMaskCompositer listening={false} />
|
||||
|
||||
{canvasBgImage && (
|
||||
{/* {canvasBgImage && (
|
||||
<>
|
||||
<KonvaImage
|
||||
image={canvasBgImage}
|
||||
@ -256,10 +201,10 @@ const IAICanvas = () => {
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
)} */}
|
||||
</Layer>
|
||||
<Layer id={'preview-layer'}>
|
||||
<IAICanvasBoundingBoxPreview visible={shouldShowBoundingBox} />
|
||||
<Layer id={'tool'}>
|
||||
<IAICanvasBoundingBox visible={shouldShowBoundingBox} />
|
||||
<IAICanvasBrushPreview
|
||||
visible={tool !== 'move'}
|
||||
listening={false}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import Konva from 'konva';
|
||||
import { Context } from 'konva/lib/Context';
|
||||
import { KonvaEventObject } from 'konva/lib/Node';
|
||||
import { Box } from 'konva/lib/shapes/Transformer';
|
||||
import { Vector2d } from 'konva/lib/types';
|
||||
@ -33,7 +32,6 @@ const boundingBoxPreviewSelector = createSelector(
|
||||
boundingBoxDimensions,
|
||||
stageDimensions,
|
||||
stageScale,
|
||||
shouldLockBoundingBox,
|
||||
isDrawing,
|
||||
isTransformingBoundingBox,
|
||||
isMovingBoundingBox,
|
||||
@ -52,7 +50,6 @@ const boundingBoxPreviewSelector = createSelector(
|
||||
shouldDarkenOutsideBoundingBox,
|
||||
isMovingBoundingBox,
|
||||
isTransformingBoundingBox,
|
||||
shouldLockBoundingBox,
|
||||
stageDimensions,
|
||||
stageScale,
|
||||
baseCanvasImage,
|
||||
@ -72,9 +69,7 @@ const boundingBoxPreviewSelector = createSelector(
|
||||
|
||||
type IAICanvasBoundingBoxPreviewProps = GroupConfig;
|
||||
|
||||
const IAICanvasBoundingBoxPreview = (
|
||||
props: IAICanvasBoundingBoxPreviewProps
|
||||
) => {
|
||||
const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => {
|
||||
const { ...rest } = props;
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
@ -86,7 +81,6 @@ const IAICanvasBoundingBoxPreview = (
|
||||
shouldDarkenOutsideBoundingBox,
|
||||
isMovingBoundingBox,
|
||||
isTransformingBoundingBox,
|
||||
shouldLockBoundingBox,
|
||||
stageCoordinates,
|
||||
stageDimensions,
|
||||
stageScale,
|
||||
@ -104,7 +98,7 @@ const IAICanvasBoundingBoxPreview = (
|
||||
if (!transformerRef.current || !shapeRef.current) return;
|
||||
transformerRef.current.nodes([shapeRef.current]);
|
||||
transformerRef.current.getLayer()?.batchDraw();
|
||||
}, [shouldLockBoundingBox]);
|
||||
}, []);
|
||||
|
||||
const scaledStep = 64 * stageScale;
|
||||
|
||||
@ -264,7 +258,6 @@ const IAICanvasBoundingBoxPreview = (
|
||||
[scaledStep]
|
||||
);
|
||||
|
||||
// OK
|
||||
const boundBoxFunc = useCallback(
|
||||
(oldBoundBox: Box, newBoundBox: Box) => {
|
||||
/**
|
||||
@ -341,10 +334,10 @@ const IAICanvasBoundingBoxPreview = (
|
||||
dragBoundFunc={
|
||||
activeTabName === 'inpainting' ? dragBoundFunc : undefined
|
||||
}
|
||||
listening={!isDrawing && tool === 'move'}
|
||||
draggable={true}
|
||||
fillEnabled={tool === 'move'}
|
||||
height={boundingBoxDimensions.height}
|
||||
listening={!isDrawing && tool === 'move'}
|
||||
onDragEnd={handleEndedModifying}
|
||||
onDragMove={handleOnDragMove}
|
||||
onMouseDown={handleStartedMoving}
|
||||
@ -387,4 +380,4 @@ const IAICanvasBoundingBoxPreview = (
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasBoundingBoxPreview;
|
||||
export default IAICanvasBoundingBox;
|
@ -15,7 +15,6 @@ import IAIPopover from 'common/components/IAIPopover';
|
||||
import IAIColorPicker from 'common/components/IAIColorPicker';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import IAINumberInput from 'common/components/IAINumberInput';
|
||||
|
||||
export const selector = createSelector(
|
||||
[currentCanvasSelector, outpaintingCanvasSelector, activeTabNameSelector],
|
||||
|
@ -2,7 +2,7 @@ import IAICanvasBrushControl from './IAICanvasControls/IAICanvasBrushControl';
|
||||
import IAICanvasEraserControl from './IAICanvasControls/IAICanvasEraserControl';
|
||||
import IAICanvasUndoControl from './IAICanvasControls/IAICanvasUndoButton';
|
||||
import IAICanvasRedoControl from './IAICanvasControls/IAICanvasRedoButton';
|
||||
import { Button, ButtonGroup } from '@chakra-ui/react';
|
||||
import { ButtonGroup } from '@chakra-ui/react';
|
||||
import IAICanvasMaskClear from './IAICanvasControls/IAICanvasMaskControls/IAICanvasMaskClear';
|
||||
import IAICanvasMaskVisibilityControl from './IAICanvasControls/IAICanvasMaskControls/IAICanvasMaskVisibilityControl';
|
||||
import IAICanvasMaskInvertControl from './IAICanvasControls/IAICanvasMaskControls/IAICanvasMaskInvertControl';
|
||||
@ -11,8 +11,6 @@ import IAICanvasShowHideBoundingBoxControl from './IAICanvasControls/IAICanvasSh
|
||||
import ImageUploaderIconButton from 'common/components/ImageUploaderIconButton';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import {
|
||||
currentCanvasSelector,
|
||||
GenericCanvasState,
|
||||
outpaintingCanvasSelector,
|
||||
OutpaintingCanvasState,
|
||||
uploadOutpaintingMergedImage,
|
||||
@ -23,7 +21,6 @@ import { OptionsState } from 'features/options/optionsSlice';
|
||||
import _ from 'lodash';
|
||||
import IAICanvasImageEraserControl from './IAICanvasControls/IAICanvasImageEraserControl';
|
||||
import { canvasImageLayerRef } from './IAICanvas';
|
||||
import { uploadImage } from 'app/socketio/actions';
|
||||
import IAIIconButton from 'common/components/IAIIconButton';
|
||||
import { FaSave } from 'react-icons/fa';
|
||||
|
||||
@ -56,12 +53,7 @@ export const canvasControlsSelector = createSelector(
|
||||
|
||||
const IAICanvasControls = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const {
|
||||
activeTabName,
|
||||
boundingBoxCoordinates,
|
||||
boundingBoxDimensions,
|
||||
stageScale,
|
||||
} = useAppSelector(canvasControlsSelector);
|
||||
const { activeTabName } = useAppSelector(canvasControlsSelector);
|
||||
|
||||
return (
|
||||
<div className="inpainting-settings">
|
||||
|
@ -42,7 +42,7 @@ const IAICanvasIntermediateImage = (props: Props) => {
|
||||
const {
|
||||
boundingBox: { x, y, width, height },
|
||||
} = intermediateImage;
|
||||
|
||||
|
||||
return loadedImageElement ? (
|
||||
<KonvaImage
|
||||
x={x}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppSelector } from 'app/store';
|
||||
import { RectConfig } from 'konva/lib/shapes/Rect';
|
||||
import _ from 'lodash';
|
||||
import { Rect } from 'react-konva';
|
||||
import {
|
||||
currentCanvasSelector,
|
||||
@ -24,7 +23,6 @@ export const canvasMaskCompositerSelector = createSelector(
|
||||
stageDimensions,
|
||||
stageScale,
|
||||
maskColorString: rgbaColorToString(maskColor),
|
||||
maskOpacity: maskColor.a,
|
||||
};
|
||||
}
|
||||
);
|
||||
@ -116,13 +114,8 @@ const getColoredSVG = (color: string) => {
|
||||
const IAICanvasMaskCompositer = (props: IAICanvasMaskCompositerProps) => {
|
||||
const { ...rest } = props;
|
||||
|
||||
const {
|
||||
maskColorString,
|
||||
maskOpacity,
|
||||
stageCoordinates,
|
||||
stageDimensions,
|
||||
stageScale,
|
||||
} = useAppSelector(canvasMaskCompositerSelector);
|
||||
const { maskColorString, stageCoordinates, stageDimensions, stageScale } =
|
||||
useAppSelector(canvasMaskCompositerSelector);
|
||||
|
||||
const [fillPatternImage, setFillPatternImage] =
|
||||
useState<HTMLImageElement | null>(null);
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { RootState, useAppSelector } from 'app/store';
|
||||
import { useAppSelector } from 'app/store';
|
||||
import _ from 'lodash';
|
||||
import { Group, Line } from 'react-konva';
|
||||
import {
|
||||
CanvasState,
|
||||
currentCanvasSelector,
|
||||
isCanvasBaseImage,
|
||||
isCanvasBaseLine,
|
||||
} from './canvasSlice';
|
||||
@ -11,14 +11,9 @@ import IAICanvasImage from './IAICanvasImage';
|
||||
import { rgbaColorToString } from './util/colorToString';
|
||||
|
||||
const selector = createSelector(
|
||||
[(state: RootState) => state.canvas],
|
||||
(canvas: CanvasState) => {
|
||||
return {
|
||||
objects:
|
||||
canvas.currentCanvas === 'outpainting'
|
||||
? canvas.outpainting.objects
|
||||
: undefined,
|
||||
};
|
||||
[currentCanvasSelector],
|
||||
(currentCanvas) => {
|
||||
return currentCanvas.objects;
|
||||
},
|
||||
{
|
||||
memoizeOptions: {
|
||||
@ -27,8 +22,8 @@ const selector = createSelector(
|
||||
}
|
||||
);
|
||||
|
||||
const IAICanvasOutpaintingObjects = () => {
|
||||
const { objects } = useAppSelector(selector);
|
||||
const IAICanvasObjectRenderer = () => {
|
||||
const objects = useAppSelector(selector);
|
||||
|
||||
if (!objects) return null;
|
||||
|
||||
@ -62,4 +57,4 @@ const IAICanvasOutpaintingObjects = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasOutpaintingObjects;
|
||||
export default IAICanvasObjectRenderer;
|
@ -5,14 +5,10 @@ import { activeTabNameSelector } from 'features/options/optionsSelectors';
|
||||
import {
|
||||
baseCanvasImageSelector,
|
||||
CanvasState,
|
||||
currentCanvasSelector,
|
||||
GenericCanvasState,
|
||||
setStageDimensions,
|
||||
setStageScale,
|
||||
} from 'features/canvas/canvasSlice';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import * as InvokeAI from 'app/invokeai';
|
||||
import { first } from 'lodash';
|
||||
|
||||
const canvasResizerSelector = createSelector(
|
||||
(state: RootState) => state.canvas,
|
||||
@ -39,13 +35,12 @@ const IAICanvasResizer = () => {
|
||||
useLayoutEffect(() => {
|
||||
window.setTimeout(() => {
|
||||
if (!ref.current || !baseCanvasImage) return;
|
||||
|
||||
const width = ref.current.clientWidth;
|
||||
const height = ref.current.clientHeight;
|
||||
const { width: imageWidth, height: imageHeight } = baseCanvasImage.image;
|
||||
const { clientWidth, clientHeight } = ref.current;
|
||||
|
||||
const scale = Math.min(
|
||||
1,
|
||||
Math.min(width / baseCanvasImage.width, height / baseCanvasImage.height)
|
||||
Math.min(clientWidth / imageWidth, clientHeight / imageHeight)
|
||||
);
|
||||
|
||||
dispatch(setStageScale(scale));
|
||||
@ -53,15 +48,15 @@ const IAICanvasResizer = () => {
|
||||
if (activeTabName === 'inpainting') {
|
||||
dispatch(
|
||||
setStageDimensions({
|
||||
width: Math.floor(baseCanvasImage.width * scale),
|
||||
height: Math.floor(baseCanvasImage.height * scale),
|
||||
width: Math.floor(imageWidth * scale),
|
||||
height: Math.floor(imageHeight * scale),
|
||||
})
|
||||
);
|
||||
} else if (activeTabName === 'outpainting') {
|
||||
dispatch(
|
||||
setStageDimensions({
|
||||
width: Math.floor(width),
|
||||
height: Math.floor(height),
|
||||
width: Math.floor(clientWidth),
|
||||
height: Math.floor(clientHeight),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import * as InvokeAI from 'app/invokeai';
|
||||
import _ from 'lodash';
|
||||
import { roundDownToMultiple } from 'common/util/roundDownToMultiple';
|
||||
import { RootState } from 'app/store';
|
||||
import { activeTabNameSelector } from 'features/options/optionsSelectors';
|
||||
import { MutableRefObject } from 'react';
|
||||
import Konva from 'konva';
|
||||
|
||||
@ -137,7 +136,7 @@ const initialGenericCanvasState: GenericCanvasState = {
|
||||
tool: 'brush',
|
||||
brushColor: { r: 90, g: 90, b: 255, a: 1 },
|
||||
brushSize: 50,
|
||||
maskColor: { r: 255, g: 90, b: 90, a: 0.5 },
|
||||
maskColor: { r: 255, g: 90, b: 90, a: 1 },
|
||||
eraserSize: 50,
|
||||
stageDimensions: { width: 0, height: 0 },
|
||||
stageCoordinates: { x: 0, y: 0 },
|
||||
@ -351,7 +350,16 @@ export const canvasSlice = createSlice({
|
||||
state.inpainting.boundingBoxDimensions = newDimensions;
|
||||
state.inpainting.boundingBoxCoordinates = newCoordinates;
|
||||
|
||||
state.inpainting.imageToInpaint = action.payload;
|
||||
// state.inpainting.imageToInpaint = action.payload;
|
||||
state.inpainting.objects = [
|
||||
{
|
||||
kind: 'image',
|
||||
layer: 'base',
|
||||
x: 0,
|
||||
y: 0,
|
||||
image: action.payload,
|
||||
},
|
||||
];
|
||||
state.doesCanvasNeedScaling = true;
|
||||
},
|
||||
setStageDimensions: (state, action: PayloadAction<Dimensions>) => {
|
||||
@ -567,19 +575,19 @@ export const canvasSlice = createSlice({
|
||||
lastLine.points.push(...action.payload);
|
||||
},
|
||||
undo: (state) => {
|
||||
if (state.outpainting.objects.length === 0) return;
|
||||
if (state[state.currentCanvas].objects.length === 0) return;
|
||||
|
||||
const newObjects = state.outpainting.pastObjects.pop();
|
||||
const newObjects = state[state.currentCanvas].pastObjects.pop();
|
||||
if (!newObjects) return;
|
||||
state.outpainting.futureObjects.unshift(state.outpainting.objects);
|
||||
state.outpainting.objects = newObjects;
|
||||
state[state.currentCanvas].futureObjects.unshift(state[state.currentCanvas].objects);
|
||||
state[state.currentCanvas].objects = newObjects;
|
||||
},
|
||||
redo: (state) => {
|
||||
if (state.outpainting.futureObjects.length === 0) return;
|
||||
const newObjects = state.outpainting.futureObjects.shift();
|
||||
if (state[state.currentCanvas].futureObjects.length === 0) return;
|
||||
const newObjects = state[state.currentCanvas].futureObjects.shift();
|
||||
if (!newObjects) return;
|
||||
state.outpainting.pastObjects.push(state.outpainting.objects);
|
||||
state.outpainting.objects = newObjects;
|
||||
state[state.currentCanvas].pastObjects.push(state[state.currentCanvas].objects);
|
||||
state[state.currentCanvas].objects = newObjects;
|
||||
},
|
||||
setShouldShowGrid: (state, action: PayloadAction<boolean>) => {
|
||||
state.outpainting.shouldShowGrid = action.payload;
|
||||
@ -748,17 +756,8 @@ export const inpaintingCanvasSelector = (
|
||||
): InpaintingCanvasState => state.canvas.inpainting;
|
||||
|
||||
export const baseCanvasImageSelector = createSelector(
|
||||
[(state: RootState) => state.canvas, activeTabNameSelector],
|
||||
(canvas: CanvasState, activeTabName) => {
|
||||
if (activeTabName === 'inpainting') {
|
||||
return canvas.inpainting.imageToInpaint;
|
||||
} else if (activeTabName === 'outpainting') {
|
||||
const firstImageObject = canvas.outpainting.objects.find(
|
||||
(obj) => obj.kind === 'image'
|
||||
);
|
||||
if (firstImageObject && firstImageObject.kind === 'image') {
|
||||
return firstImageObject.image;
|
||||
}
|
||||
}
|
||||
[currentCanvasSelector],
|
||||
(currentCanvas) => {
|
||||
return currentCanvas.objects.find(isCanvasBaseImage);
|
||||
}
|
||||
);
|
||||
|
@ -2,26 +2,20 @@ import { createSelector } from '@reduxjs/toolkit';
|
||||
import _ from 'lodash';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { activeTabNameSelector } from 'features/options/optionsSelectors';
|
||||
import { OptionsState } from 'features/options/optionsSlice';
|
||||
import {
|
||||
CanvasTool,
|
||||
setShouldShowBoundingBox,
|
||||
setTool,
|
||||
toggleShouldLockBoundingBox,
|
||||
} from 'features/canvas/canvasSlice';
|
||||
import { RootState, useAppDispatch, useAppSelector } from 'app/store';
|
||||
import { currentCanvasSelector, GenericCanvasState } from '../canvasSlice';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store';
|
||||
import { currentCanvasSelector } from '../canvasSlice';
|
||||
import { useRef } from 'react';
|
||||
|
||||
const inpaintingCanvasHotkeysSelector = createSelector(
|
||||
[
|
||||
(state: RootState) => state.options,
|
||||
currentCanvasSelector,
|
||||
activeTabNameSelector,
|
||||
],
|
||||
(options: OptionsState, currentCanvas: GenericCanvasState, activeTabName) => {
|
||||
[currentCanvasSelector, activeTabNameSelector],
|
||||
(currentCanvas, activeTabName) => {
|
||||
const {
|
||||
isMaskEnabled,
|
||||
cursorPosition,
|
||||
shouldLockBoundingBox,
|
||||
shouldShowBoundingBox,
|
||||
@ -30,7 +24,6 @@ const inpaintingCanvasHotkeysSelector = createSelector(
|
||||
|
||||
return {
|
||||
activeTabName,
|
||||
isMaskEnabled,
|
||||
isCursorOnCanvas: Boolean(cursorPosition),
|
||||
shouldLockBoundingBox,
|
||||
shouldShowBoundingBox,
|
||||
@ -46,8 +39,9 @@ const inpaintingCanvasHotkeysSelector = createSelector(
|
||||
|
||||
const useInpaintingCanvasHotkeys = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { isMaskEnabled, activeTabName, shouldShowBoundingBox, tool } =
|
||||
useAppSelector(inpaintingCanvasHotkeysSelector);
|
||||
const { activeTabName, shouldShowBoundingBox, tool } = useAppSelector(
|
||||
inpaintingCanvasHotkeysSelector
|
||||
);
|
||||
|
||||
const previousToolRef = useRef<CanvasTool | null>(null);
|
||||
// Toggle lock bounding box
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { useAppDispatch } from 'app/store';
|
||||
import _ from 'lodash';
|
||||
import { useCallback } from 'react';
|
||||
import { setCursorPosition, setIsDrawing } from '../canvasSlice';
|
||||
|
||||
|
@ -21,7 +21,7 @@ import IAIIconButton from 'common/components/IAIIconButton';
|
||||
import UpscaleOptions from 'features/options/AdvancedOptions/Upscale/UpscaleOptions';
|
||||
import FaceRestoreOptions from 'features/options/AdvancedOptions/FaceRestore/FaceRestoreOptions';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { ButtonGroup, Link, useClipboard, useToast } from '@chakra-ui/react';
|
||||
import { ButtonGroup, Link, useToast } from '@chakra-ui/react';
|
||||
import {
|
||||
FaAsterisk,
|
||||
FaCode,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { IconButton, Image, Spinner } from '@chakra-ui/react';
|
||||
import { IconButton, Image } from '@chakra-ui/react';
|
||||
import { useState } from 'react';
|
||||
import { FaAngleLeft, FaAngleRight } from 'react-icons/fa';
|
||||
import { RootState, useAppDispatch, useAppSelector } from 'app/store';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { RootState, useAppDispatch, useAppSelector } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store';
|
||||
import IAICheckbox from 'common/components/IAICheckbox';
|
||||
import {
|
||||
currentCanvasSelector,
|
||||
|
@ -1,12 +1,10 @@
|
||||
import React from 'react';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
|
||||
import { RootState, useAppDispatch, useAppSelector } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import {
|
||||
currentCanvasSelector,
|
||||
GenericCanvasState,
|
||||
// InpaintingState,
|
||||
setBoundingBoxDimensions,
|
||||
} from 'features/canvas/canvasSlice';
|
||||
|
||||
@ -15,7 +13,7 @@ import _ from 'lodash';
|
||||
|
||||
const boundingBoxDimensionsSelector = createSelector(
|
||||
currentCanvasSelector,
|
||||
(currentCanvas: GenericCanvasState) => {
|
||||
(currentCanvas) => {
|
||||
const { stageDimensions, boundingBoxDimensions, shouldLockBoundingBox } =
|
||||
currentCanvas;
|
||||
return {
|
||||
|
@ -1,16 +1,15 @@
|
||||
import React from 'react';
|
||||
import { RootState, useAppDispatch, useAppSelector } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store';
|
||||
import IAICheckbox from 'common/components/IAICheckbox';
|
||||
import {
|
||||
currentCanvasSelector,
|
||||
GenericCanvasState,
|
||||
setShouldLockBoundingBox,
|
||||
} from 'features/canvas/canvasSlice';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
|
||||
const boundingBoxLockSelector = createSelector(
|
||||
currentCanvasSelector,
|
||||
(currentCanvas: GenericCanvasState) => currentCanvas.shouldLockBoundingBox
|
||||
(currentCanvas) => currentCanvas.shouldLockBoundingBox
|
||||
);
|
||||
|
||||
export default function BoundingBoxLock() {
|
||||
|
@ -1,17 +1,16 @@
|
||||
import React from 'react';
|
||||
import { BiHide, BiShow } from 'react-icons/bi';
|
||||
import { RootState, useAppDispatch, useAppSelector } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store';
|
||||
import IAIIconButton from 'common/components/IAIIconButton';
|
||||
import {
|
||||
currentCanvasSelector,
|
||||
GenericCanvasState,
|
||||
setShouldShowBoundingBox,
|
||||
} from 'features/canvas/canvasSlice';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
|
||||
const boundingBoxVisibilitySelector = createSelector(
|
||||
currentCanvasSelector,
|
||||
(currentCanvas: GenericCanvasState) => currentCanvas.shouldShowBoundingBox
|
||||
(currentCanvas) => currentCanvas.shouldShowBoundingBox
|
||||
);
|
||||
|
||||
export default function BoundingBoxVisibility() {
|
||||
|
@ -1,9 +1,5 @@
|
||||
import React, { ChangeEvent } from 'react';
|
||||
import {
|
||||
RootState,
|
||||
useAppDispatch,
|
||||
useAppSelector,
|
||||
} from '../../../../app/store';
|
||||
import { useAppDispatch, useAppSelector } from '../../../../app/store';
|
||||
import _ from 'lodash';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import IAISwitch from '../../../../common/components/IAISwitch';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Image, useToast } from '@chakra-ui/react';
|
||||
import { SyntheticEvent } from 'react';
|
||||
import { RootState, useAppDispatch, useAppSelector } from 'app/store';
|
||||
import ImageUploaderIconButton from 'common/components/ImageUploaderIconButton';
|
||||
import { clearInitialImage } from 'features/options/optionsSlice';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
// import IAICanvas from 'features/canvas/IAICanvas';
|
||||
import IAICanvasControls from 'features/canvas/IAICanvasControls';
|
||||
import IAICanvasResizer from 'features/canvas/IAICanvasResizer';
|
||||
import _ from 'lodash';
|
||||
@ -9,23 +8,25 @@ import ImageUploadButton from 'common/components/ImageUploaderButton';
|
||||
import CurrentImageDisplay from 'features/gallery/CurrentImageDisplay';
|
||||
import { OptionsState } from 'features/options/optionsSlice';
|
||||
import {
|
||||
baseCanvasImageSelector,
|
||||
CanvasState,
|
||||
setDoesCanvasNeedScaling,
|
||||
} from 'features/canvas/canvasSlice';
|
||||
import IAICanvas from 'features/canvas/IAICanvas';
|
||||
|
||||
const inpaintingDisplaySelector = createSelector(
|
||||
[(state: RootState) => state.canvas, (state: RootState) => state.options],
|
||||
(canvas: CanvasState, options: OptionsState) => {
|
||||
const {
|
||||
doesCanvasNeedScaling,
|
||||
inpainting: { imageToInpaint },
|
||||
} = canvas;
|
||||
[
|
||||
baseCanvasImageSelector,
|
||||
(state: RootState) => state.canvas,
|
||||
(state: RootState) => state.options,
|
||||
],
|
||||
(baseCanvasImage, canvas: CanvasState, options: OptionsState) => {
|
||||
const { doesCanvasNeedScaling } = canvas;
|
||||
const { showDualDisplay } = options;
|
||||
return {
|
||||
doesCanvasNeedScaling,
|
||||
showDualDisplay,
|
||||
imageToInpaint,
|
||||
baseCanvasImage,
|
||||
};
|
||||
},
|
||||
{
|
||||
@ -37,7 +38,7 @@ const inpaintingDisplaySelector = createSelector(
|
||||
|
||||
const InpaintingDisplay = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { showDualDisplay, doesCanvasNeedScaling, imageToInpaint } =
|
||||
const { showDualDisplay, doesCanvasNeedScaling, baseCanvasImage } =
|
||||
useAppSelector(inpaintingDisplaySelector);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
@ -49,7 +50,7 @@ const InpaintingDisplay = () => {
|
||||
return () => window.removeEventListener('resize', resizeCallback);
|
||||
}, [dispatch]);
|
||||
|
||||
const inpaintingComponent = imageToInpaint ? (
|
||||
const inpaintingComponent = baseCanvasImage ? (
|
||||
<div className="inpainting-main-area">
|
||||
<IAICanvasControls />
|
||||
<div className="inpainting-canvas-area">
|
||||
|
@ -4,7 +4,6 @@ import React, { ReactElement } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { RootState, useAppDispatch, useAppSelector } from 'app/store';
|
||||
import NodesWIP from 'common/components/WorkInProgress/NodesWIP';
|
||||
import OutpaintingWIP from 'common/components/WorkInProgress/OutpaintingWIP';
|
||||
import { PostProcessingWIP } from 'common/components/WorkInProgress/PostProcessingWIP';
|
||||
import ImageToImageIcon from 'common/icons/ImageToImageIcon';
|
||||
import InpaintIcon from 'common/icons/InpaintIcon';
|
||||
@ -19,13 +18,9 @@ import {
|
||||
} from 'features/options/optionsSlice';
|
||||
import ImageToImageWorkarea from './ImageToImage';
|
||||
import InpaintingWorkarea from './Inpainting/InpaintingWorkarea';
|
||||
// import { setDoesCanvasNeedScaling } from './Inpainting/inpaintingSlice';
|
||||
import TextToImageWorkarea from './TextToImage';
|
||||
import Lightbox from 'features/lightbox/Lightbox';
|
||||
import {
|
||||
setCurrentCanvas,
|
||||
setDoesCanvasNeedScaling,
|
||||
} from 'features/canvas/canvasSlice';
|
||||
import { setDoesCanvasNeedScaling } from 'features/canvas/canvasSlice';
|
||||
import OutpaintingWorkarea from './Outpainting/OutpaintingWorkarea';
|
||||
import { setShouldShowGallery } from 'features/gallery/gallerySlice';
|
||||
|
||||
|
@ -19,7 +19,6 @@ const workareaSelector = createSelector(
|
||||
return {
|
||||
showDualDisplay,
|
||||
shouldPinOptionsPanel,
|
||||
activeTabName,
|
||||
isLightBoxOpen,
|
||||
shouldShowDualDisplayButton: ['inpainting'].includes(activeTabName),
|
||||
};
|
||||
@ -37,7 +36,6 @@ const InvokeWorkarea = (props: InvokeWorkareaProps) => {
|
||||
const { optionsPanel, children, styleClass } = props;
|
||||
const {
|
||||
showDualDisplay,
|
||||
activeTabName,
|
||||
isLightBoxOpen,
|
||||
shouldShowDualDisplayButton,
|
||||
} = useAppSelector(workareaSelector);
|
||||
|
@ -1,34 +1,26 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
// import IAICanvas from 'features/canvas/IAICanvas';
|
||||
import IAICanvasControls from 'features/canvas/IAICanvasControls';
|
||||
import IAICanvasResizer from 'features/canvas/IAICanvasResizer';
|
||||
import _ from 'lodash';
|
||||
import { useLayoutEffect } from 'react';
|
||||
import { RootState, useAppDispatch, useAppSelector } from 'app/store';
|
||||
import ImageUploadButton from 'common/components/ImageUploaderButton';
|
||||
import CurrentImageDisplay from 'features/gallery/CurrentImageDisplay';
|
||||
import { OptionsState } from 'features/options/optionsSlice';
|
||||
import {
|
||||
CanvasState,
|
||||
currentCanvasSelector,
|
||||
GenericCanvasState,
|
||||
OutpaintingCanvasState,
|
||||
setDoesCanvasNeedScaling,
|
||||
} from 'features/canvas/canvasSlice';
|
||||
import IAICanvas from 'features/canvas/IAICanvas';
|
||||
import IAICanvasOutpaintingControls from 'features/canvas/IAICanvasOutpaintingControls';
|
||||
|
||||
const outpaintingDisplaySelector = createSelector(
|
||||
[(state: RootState) => state.canvas, (state: RootState) => state.options],
|
||||
(canvas: CanvasState, options: OptionsState) => {
|
||||
[(state: RootState) => state.canvas],
|
||||
(canvas: CanvasState) => {
|
||||
const {
|
||||
doesCanvasNeedScaling,
|
||||
outpainting: { objects },
|
||||
} = canvas;
|
||||
const { showDualDisplay } = options;
|
||||
return {
|
||||
doesCanvasNeedScaling,
|
||||
showDualDisplay,
|
||||
doesOutpaintingHaveObjects: objects.length > 0,
|
||||
};
|
||||
},
|
||||
@ -41,8 +33,9 @@ const outpaintingDisplaySelector = createSelector(
|
||||
|
||||
const OutpaintingDisplay = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { showDualDisplay, doesCanvasNeedScaling, doesOutpaintingHaveObjects } =
|
||||
useAppSelector(outpaintingDisplaySelector);
|
||||
const { doesCanvasNeedScaling, doesOutpaintingHaveObjects } = useAppSelector(
|
||||
outpaintingDisplaySelector
|
||||
);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const resizeCallback = _.debounce(
|
||||
|
Loading…
Reference in New Issue
Block a user