From 31a78d571b19c18f604af3d3f06db775c17c70e0 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Wed, 10 May 2023 14:13:33 +1000 Subject: [PATCH] feat(ui): canvas antialiasing --- invokeai/frontend/web/public/locales/en.json | 3 ++- .../src/features/canvas/components/IAICanvas.tsx | 14 +++++++------- .../IAICanvasSettingsButtonPopover.tsx | 10 ++++++++++ .../web/src/features/canvas/store/canvasSlice.ts | 5 +++++ .../web/src/features/canvas/store/canvasTypes.ts | 5 +++-- .../UnifiedCanvasSettings.tsx | 9 +++++++++ 6 files changed, 36 insertions(+), 10 deletions(-) diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index e3f21e50a1..71461d409a 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -650,7 +650,8 @@ "betaClear": "Clear", "betaDarkenOutside": "Darken Outside", "betaLimitToBox": "Limit To Box", - "betaPreserveMasked": "Preserve Masked" + "betaPreserveMasked": "Preserve Masked", + "antialiasing": "Antialiasing" }, "ui": { "showProgressImages": "Show Progress Images", diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvas.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvas.tsx index 1850b4bfe4..aa785c379d 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvas.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvas.tsx @@ -34,6 +34,7 @@ import IAICanvasStagingAreaToolbar from './IAICanvasStagingAreaToolbar'; import IAICanvasStatusText from './IAICanvasStatusText'; import IAICanvasBoundingBox from './IAICanvasToolbar/IAICanvasBoundingBox'; import IAICanvasToolPreview from './IAICanvasToolPreview'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; const selector = createSelector( [canvasSelector, isStagingSelector], @@ -52,6 +53,7 @@ const selector = createSelector( shouldShowIntermediates, shouldShowGrid, shouldRestrictStrokesToBox, + shouldAntialias, } = canvas; let stageCursor: string | undefined = 'none'; @@ -80,13 +82,10 @@ const selector = createSelector( tool, isStaging, shouldShowIntermediates, + shouldAntialias, }; }, - { - memoizeOptions: { - resultEqualityCheck: isEqual, - }, - } + defaultSelectorOptions ); const ChakraStage = chakra(Stage, { @@ -106,6 +105,7 @@ const IAICanvas = () => { tool, isStaging, shouldShowIntermediates, + shouldAntialias, } = useAppSelector(selector); useCanvasHotkeys(); @@ -190,7 +190,7 @@ const IAICanvas = () => { id="base" ref={canvasBaseLayerRefCallback} listening={false} - imageSmoothingEnabled={false} + imageSmoothingEnabled={shouldAntialias} > @@ -201,7 +201,7 @@ const IAICanvas = () => { - + {!isStaging && ( { shouldShowIntermediates, shouldSnapToGrid, shouldRestrictStrokesToBox, + shouldAntialias, } = useAppSelector(canvasControlsSelector); useHotkeys( @@ -148,6 +152,12 @@ const IAICanvasSettingsButtonPopover = () => { dispatch(setShouldShowCanvasDebugInfo(e.target.checked)) } /> + + dispatch(setShouldAntialias(e.target.checked))} + /> diff --git a/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts b/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts index 501dfe36d8..037d353f42 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 @@ export const initialCanvasState: CanvasState = { minimumStageScale: 1, pastLayerStates: [], scaledBoundingBoxDimensions: { width: 512, height: 512 }, + shouldAntialias: true, shouldAutoSave: false, shouldCropToBoundingBoxOnSave: false, shouldDarkenOutsideBoundingBox: false, @@ -796,6 +797,9 @@ export const canvasSlice = createSlice({ setShouldRestrictStrokesToBox: (state, action: PayloadAction) => { state.shouldRestrictStrokesToBox = action.payload; }, + setShouldAntialias: (state, action: PayloadAction) => { + state.shouldAntialias = action.payload; + }, setShouldCropToBoundingBoxOnSave: ( state, action: PayloadAction @@ -907,6 +911,7 @@ export const { setShouldRestrictStrokesToBox, stagingAreaInitialized, canvasSessionIdChanged, + setShouldAntialias, } = canvasSlice.actions; export default canvasSlice.reducer; diff --git a/invokeai/frontend/web/src/features/canvas/store/canvasTypes.ts b/invokeai/frontend/web/src/features/canvas/store/canvasTypes.ts index 9194f065b2..2a6461aaf6 100644 --- a/invokeai/frontend/web/src/features/canvas/store/canvasTypes.ts +++ b/invokeai/frontend/web/src/features/canvas/store/canvasTypes.ts @@ -37,7 +37,7 @@ export type CanvasImage = { y: number; width: number; height: number; - image: InvokeAI._Image; + image: InvokeAI.Image; }; export type CanvasMaskLine = { @@ -132,7 +132,7 @@ export interface CanvasState { cursorPosition: Vector2d | null; doesCanvasNeedScaling: boolean; futureLayerStates: CanvasLayerState[]; - intermediateImage?: InvokeAI._Image; + intermediateImage?: InvokeAI.Image; isCanvasInitialized: boolean; isDrawing: boolean; isMaskEnabled: boolean; @@ -149,6 +149,7 @@ export interface CanvasState { minimumStageScale: number; pastLayerStates: CanvasLayerState[]; scaledBoundingBoxDimensions: Dimensions; + shouldAntialias: boolean; shouldAutoSave: boolean; shouldCropToBoundingBoxOnSave: boolean; shouldDarkenOutsideBoundingBox: boolean; diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasSettings.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasSettings.tsx index a2b21368d4..bfaa7cdae8 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasSettings.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasSettings.tsx @@ -6,6 +6,7 @@ import IAIIconButton from 'common/components/IAIIconButton'; import IAIPopover from 'common/components/IAIPopover'; import { canvasSelector } from 'features/canvas/store/canvasSelectors'; import { + setShouldAntialias, setShouldAutoSave, setShouldCropToBoundingBoxOnSave, setShouldShowCanvasDebugInfo, @@ -27,6 +28,7 @@ export const canvasControlsSelector = createSelector( shouldCropToBoundingBoxOnSave, shouldShowCanvasDebugInfo, shouldShowIntermediates, + shouldAntialias, } = canvas; return { @@ -34,6 +36,7 @@ export const canvasControlsSelector = createSelector( shouldCropToBoundingBoxOnSave, shouldShowCanvasDebugInfo, shouldShowIntermediates, + shouldAntialias, }; }, { @@ -52,6 +55,7 @@ const UnifiedCanvasSettings = () => { shouldCropToBoundingBoxOnSave, shouldShowCanvasDebugInfo, shouldShowIntermediates, + shouldAntialias, } = useAppSelector(canvasControlsSelector); return ( @@ -95,6 +99,11 @@ const UnifiedCanvasSettings = () => { dispatch(setShouldShowCanvasDebugInfo(e.target.checked)) } /> + dispatch(setShouldAntialias(e.target.checked))} + />