From 90686c7f9c2e48398da9548957e84693b59692f3 Mon Sep 17 00:00:00 2001 From: symant233 Date: Thu, 4 Apr 2024 18:41:22 +0800 Subject: [PATCH] feat: Unified Canvas Fit Image Size on Drop --- invokeai/frontend/web/public/locales/en.json | 1 + invokeai/frontend/web/public/locales/zh_CN.json | 3 ++- .../IAICanvasSettingsButtonPopover.tsx | 10 ++++++++++ .../src/features/canvas/store/canvasSlice.ts | 17 ++++++++++++----- .../src/features/canvas/store/canvasTypes.ts | 1 + 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index 0cf98289e4..623cea64ee 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -1423,6 +1423,7 @@ "eraseBoundingBox": "Erase Bounding Box", "eraser": "Eraser", "fillBoundingBox": "Fill Bounding Box", + "initialFitImageSize": "Fit Image Size on Drop", "invertBrushSizeScrollDirection": "Invert Scroll for Brush Size", "layer": "Layer", "limitStrokesToBox": "Limit Strokes to Box", diff --git a/invokeai/frontend/web/public/locales/zh_CN.json b/invokeai/frontend/web/public/locales/zh_CN.json index 77a06ea77b..e40b04ed10 100644 --- a/invokeai/frontend/web/public/locales/zh_CN.json +++ b/invokeai/frontend/web/public/locales/zh_CN.json @@ -583,7 +583,8 @@ "next": "下一张", "accept": "接受", "discardAll": "放弃所有", - "antialiasing": "抗锯齿", + "antialiasing": "抗锯齿", + "initialFitImageSize": "初始适应图片大小", "showResultsOn": "显示结果 (开)", "showResultsOff": "显示结果 (关)", "saveMask": "保存 $t(unifiedCanvas.mask)" diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasSettingsButtonPopover.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasSettingsButtonPopover.tsx index 0228b158dd..80be585aa2 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasSettingsButtonPopover.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasSettingsButtonPopover.tsx @@ -18,6 +18,7 @@ import { setShouldAutoSave, setShouldCropToBoundingBoxOnSave, setShouldDarkenOutsideBoundingBox, + setShouldFitImageSize, setShouldInvertBrushSizeScrollDirection, setShouldRestrictStrokesToBox, setShouldShowCanvasDebugInfo, @@ -48,6 +49,7 @@ const IAICanvasSettingsButtonPopover = () => { const shouldSnapToGrid = useAppSelector((s) => s.canvas.shouldSnapToGrid); const shouldRestrictStrokesToBox = useAppSelector((s) => s.canvas.shouldRestrictStrokesToBox); const shouldAntialias = useAppSelector((s) => s.canvas.shouldAntialias); + const sholdFitImageSize = useAppSelector((s) => s.canvas.shouldFitImageSize); useHotkeys( ['n'], @@ -102,6 +104,10 @@ const IAICanvasSettingsButtonPopover = () => { (e: ChangeEvent) => dispatch(setShouldAntialias(e.target.checked)), [dispatch] ); + const handleChangeSholdFitImageSize = useCallback( + (e: ChangeEvent) => dispatch(setShouldFitImageSize(e.target.checked)), + [dispatch] + ); return ( @@ -165,6 +171,10 @@ const IAICanvasSettingsButtonPopover = () => { {t('unifiedCanvas.antialiasing')} + + {t('unifiedCanvas.initialFitImageSize')} + + diff --git a/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts b/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts index 68eba694ab..b9f68cf47d 100644 --- a/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts +++ b/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts @@ -66,6 +66,7 @@ const initialCanvasState: CanvasState = { shouldAutoSave: false, shouldCropToBoundingBoxOnSave: false, shouldDarkenOutsideBoundingBox: false, + shouldFitImageSize: false, shouldInvertBrushSizeScrollDirection: false, shouldLockBoundingBox: false, shouldPreserveMaskedArea: false, @@ -144,12 +145,14 @@ export const canvasSlice = createSlice({ reducer: (state, action: PayloadActionWithOptimalDimension) => { const { width, height, image_name } = action.payload; const { optimalDimension } = action.meta; - const { stageDimensions } = state; + const { stageDimensions, shouldFitImageSize } = state; - const newBoundingBoxDimensions = { - width: roundDownToMultiple(clamp(width, CANVAS_GRID_SIZE_FINE, optimalDimension), CANVAS_GRID_SIZE_FINE), - height: roundDownToMultiple(clamp(height, CANVAS_GRID_SIZE_FINE, optimalDimension), CANVAS_GRID_SIZE_FINE), - }; + const newBoundingBoxDimensions = shouldFitImageSize + ? { width, height } + : { + width: roundDownToMultiple(clamp(width, CANVAS_GRID_SIZE_FINE, optimalDimension), CANVAS_GRID_SIZE_FINE), + height: roundDownToMultiple(clamp(height, CANVAS_GRID_SIZE_FINE, optimalDimension), CANVAS_GRID_SIZE_FINE), + }; const newBoundingBoxCoordinates = { x: roundToMultiple(width / 2 - newBoundingBoxDimensions.width / 2, CANVAS_GRID_SIZE_FINE), @@ -582,6 +585,9 @@ export const canvasSlice = createSlice({ setShouldAntialias: (state, action: PayloadAction) => { state.shouldAntialias = action.payload; }, + setShouldFitImageSize: (state, action: PayloadAction) => { + state.shouldFitImageSize = action.payload; + }, setShouldCropToBoundingBoxOnSave: (state, action: PayloadAction) => { state.shouldCropToBoundingBoxOnSave = action.payload; }, @@ -692,6 +698,7 @@ export const { setShouldRestrictStrokesToBox, stagingAreaInitialized, setShouldAntialias, + setShouldFitImageSize, canvasResized, canvasBatchIdAdded, canvasBatchIdsReset, diff --git a/invokeai/frontend/web/src/features/canvas/store/canvasTypes.ts b/invokeai/frontend/web/src/features/canvas/store/canvasTypes.ts index 7fc39fde1f..2d30e18760 100644 --- a/invokeai/frontend/web/src/features/canvas/store/canvasTypes.ts +++ b/invokeai/frontend/web/src/features/canvas/store/canvasTypes.ts @@ -120,6 +120,7 @@ export interface CanvasState { shouldAutoSave: boolean; shouldCropToBoundingBoxOnSave: boolean; shouldDarkenOutsideBoundingBox: boolean; + shouldFitImageSize: boolean; shouldInvertBrushSizeScrollDirection: boolean; shouldLockBoundingBox: boolean; shouldPreserveMaskedArea: boolean;