diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts index 7f738d3fcf..8f9a664aa1 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts @@ -21,8 +21,8 @@ import { imBrushLineAdded, imEraserLineAdded, imImageCacheChanged, + imMoved, imRectAdded, - imTranslated, inpaintMaskRasterized, layerBrushLineAdded, layerEraserLineAdded, @@ -31,12 +31,12 @@ import { layerRectAdded, layerReset, layerTranslated, - regionMaskRasterized, rgBrushLineAdded, rgEraserLineAdded, rgImageCacheChanged, + rgMoved, + rgRasterized, rgRectAdded, - rgTranslated, toolBufferChanged, toolChanged, } from 'features/controlLayers/store/canvasV2Slice'; @@ -80,9 +80,9 @@ export class CanvasStateApi { if (entityType === 'layer') { this._store.dispatch(layerTranslated(arg)); } else if (entityType === 'regional_guidance') { - this._store.dispatch(rgTranslated(arg)); + this._store.dispatch(rgMoved(arg)); } else if (entityType === 'inpaint_mask') { - this._store.dispatch(imTranslated(arg)); + this._store.dispatch(imMoved(arg)); } else if (entityType === 'control_adapter') { this._store.dispatch(caTranslated(arg)); } @@ -124,7 +124,7 @@ export class CanvasStateApi { } else if (entityType === 'inpaint_mask') { this._store.dispatch(inpaintMaskRasterized(arg)); } else if (entityType === 'regional_guidance') { - this._store.dispatch(regionMaskRasterized(arg)); + this._store.dispatch(rgRasterized(arg)); } else { assert(false, 'Rasterizing not supported for this entity type'); } diff --git a/invokeai/frontend/web/src/features/controlLayers/store/canvasV2Slice.ts b/invokeai/frontend/web/src/features/controlLayers/store/canvasV2Slice.ts index 2614339936..6e8fd2e3fb 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/canvasV2Slice.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/canvasV2Slice.ts @@ -44,8 +44,6 @@ const initialState: CanvasV2State = { inpaintMask: { id: 'inpaint_mask', type: 'inpaint_mask', - bbox: null, - bboxNeedsUpdate: false, fill: RGBA_RED, imageCache: null, isEnabled: true, @@ -264,8 +262,7 @@ export const { rgRecalled, rgReset, rgIsEnabledToggled, - rgTranslated, - rgBboxChanged, + rgMoved, rgDeleted, rgAllDeleted, rgMovedForwardOne, @@ -285,11 +282,10 @@ export const { rgIPAdapterMethodChanged, rgIPAdapterModelChanged, rgIPAdapterCLIPVisionModelChanged, - rgScaled, rgBrushLineAdded, rgEraserLineAdded, rgRectAdded, - regionMaskRasterized, + rgRasterized, // Compositing setInfillMethod, setInfillTileSize, @@ -338,11 +334,9 @@ export const { imReset, imRecalled, imIsEnabledToggled, - imTranslated, - imBboxChanged, + imMoved, imFillChanged, imImageCacheChanged, - imScaled, imBrushLineAdded, imEraserLineAdded, imRectAdded, diff --git a/invokeai/frontend/web/src/features/controlLayers/store/inpaintMaskReducers.ts b/invokeai/frontend/web/src/features/controlLayers/store/inpaintMaskReducers.ts index a18041ce7a..416c6bd341 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/inpaintMaskReducers.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/inpaintMaskReducers.ts @@ -7,10 +7,8 @@ import type { CanvasV2State, Coordinate, EntityRasterizedArg, - ScaleChangedArg, } from 'features/controlLayers/store/types'; import { imageDTOToImageWithDims } from 'features/controlLayers/store/types'; -import type { IRect } from 'konva/lib/types'; import type { ImageDTO } from 'services/api/types'; import type { RgbColor } from './types'; @@ -18,8 +16,6 @@ import type { RgbColor } from './types'; export const inpaintMaskReducers = { imReset: (state) => { state.inpaintMask.objects = []; - state.inpaintMask.bbox = null; - state.inpaintMask.bboxNeedsUpdate = false; state.inpaintMask.imageCache = null; }, imRecalled: (state, action: PayloadAction<{ data: CanvasInpaintMaskState }>) => { @@ -30,35 +26,10 @@ export const inpaintMaskReducers = { imIsEnabledToggled: (state) => { state.inpaintMask.isEnabled = !state.inpaintMask.isEnabled; }, - imTranslated: (state, action: PayloadAction<{ position: Coordinate }>) => { + imMoved: (state, action: PayloadAction<{ position: Coordinate }>) => { const { position } = action.payload; state.inpaintMask.position = position; }, - imScaled: (state, action: PayloadAction) => { - const { scale, position } = action.payload; - for (const obj of state.inpaintMask.objects) { - if (obj.type === 'brush_line') { - obj.points = obj.points.map((point) => point * scale); - obj.strokeWidth *= scale; - } else if (obj.type === 'eraser_line') { - obj.points = obj.points.map((point) => point * scale); - obj.strokeWidth *= scale; - } else if (obj.type === 'rect') { - obj.x *= scale; - obj.y *= scale; - obj.height *= scale; - obj.width *= scale; - } - } - state.inpaintMask.position = position; - state.inpaintMask.bboxNeedsUpdate = true; - state.inpaintMask.imageCache = null; - }, - imBboxChanged: (state, action: PayloadAction<{ bbox: IRect | null }>) => { - const { bbox } = action.payload; - state.inpaintMask.bbox = bbox; - state.inpaintMask.bboxNeedsUpdate = false; - }, imFillChanged: (state, action: PayloadAction<{ fill: RgbColor }>) => { const { fill } = action.payload; state.inpaintMask.fill = fill; @@ -70,19 +41,16 @@ export const inpaintMaskReducers = { imBrushLineAdded: (state, action: PayloadAction<{ brushLine: CanvasBrushLineState }>) => { const { brushLine } = action.payload; state.inpaintMask.objects.push(brushLine); - state.inpaintMask.bboxNeedsUpdate = true; state.layers.imageCache = null; }, imEraserLineAdded: (state, action: PayloadAction<{ eraserLine: CanvasEraserLineState }>) => { const { eraserLine } = action.payload; state.inpaintMask.objects.push(eraserLine); - state.inpaintMask.bboxNeedsUpdate = true; state.layers.imageCache = null; }, imRectAdded: (state, action: PayloadAction<{ rect: CanvasRectState }>) => { const { rect } = action.payload; state.inpaintMask.objects.push(rect); - state.inpaintMask.bboxNeedsUpdate = true; state.layers.imageCache = null; }, inpaintMaskRasterized: (state, action: PayloadAction) => { diff --git a/invokeai/frontend/web/src/features/controlLayers/store/regionsReducers.ts b/invokeai/frontend/web/src/features/controlLayers/store/regionsReducers.ts index d4847310db..6d20996776 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/regionsReducers.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/regionsReducers.ts @@ -1,5 +1,6 @@ import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit'; import { moveOneToEnd, moveOneToStart, moveToEnd, moveToStart } from 'common/util/arrayUtils'; +import { getPrefixedId } from 'features/controlLayers/konva/util'; import type { CanvasBrushLineState, CanvasEraserLineState, @@ -9,16 +10,13 @@ import type { EntityRasterizedArg, IPMethodV2, PositionChangedArg, - ScaleChangedArg, } from 'features/controlLayers/store/types'; import { imageDTOToImageObject, imageDTOToImageWithDims } from 'features/controlLayers/store/types'; import { zModelIdentifierField } from 'features/nodes/types/common'; import type { ParameterAutoNegative } from 'features/parameters/types/parameterSchemas'; -import type { IRect } from 'konva/lib/types'; import { isEqual } from 'lodash-es'; import type { ImageDTO, IPAdapterModelConfig } from 'services/api/types'; import { assert } from 'tsafe'; -import { v4 as uuidv4 } from 'uuid'; import type { CanvasIPAdapterState, CanvasRegionalGuidanceState, RgbColor } from './types'; @@ -59,8 +57,6 @@ export const regionsReducers = { id, type: 'regional_guidance', isEnabled: true, - bbox: null, - bboxNeedsUpdate: false, objects: [], fill: getRGMaskFill(state), position: { x: 0, y: 0 }, @@ -73,7 +69,7 @@ export const regionsReducers = { state.regions.entities.push(rg); state.selectedEntityIdentifier = { type: 'regional_guidance', id }; }, - prepare: () => ({ payload: { id: uuidv4() } }), + prepare: () => ({ payload: { id: getPrefixedId('regional_guidance') } }), }, rgReset: (state, action: PayloadAction<{ id: string }>) => { const { id } = action.payload; @@ -82,8 +78,6 @@ export const regionsReducers = { return; } rg.objects = []; - rg.bbox = null; - rg.bboxNeedsUpdate = false; rg.imageCache = null; }, rgRecalled: (state, action: PayloadAction<{ data: CanvasRegionalGuidanceState }>) => { @@ -98,45 +92,13 @@ export const regionsReducers = { rg.isEnabled = !rg.isEnabled; } }, - rgTranslated: (state, action: PayloadAction) => { + rgMoved: (state, action: PayloadAction) => { const { id, position } = action.payload; const rg = selectRG(state, id); if (rg) { rg.position = position; } }, - rgScaled: (state, action: PayloadAction) => { - const { id, scale, position } = action.payload; - const rg = selectRG(state, id); - if (!rg) { - return; - } - for (const obj of rg.objects) { - if (obj.type === 'brush_line') { - obj.points = obj.points.map((point) => point * scale); - obj.strokeWidth *= scale; - } else if (obj.type === 'eraser_line') { - obj.points = obj.points.map((point) => point * scale); - obj.strokeWidth *= scale; - } else if (obj.type === 'rect') { - obj.x *= scale; - obj.y *= scale; - obj.height *= scale; - obj.width *= scale; - } - } - rg.position = position; - rg.bboxNeedsUpdate = true; - state.layers.imageCache = null; - }, - rgBboxChanged: (state, action: PayloadAction<{ id: string; bbox: IRect | null }>) => { - const { id, bbox } = action.payload; - const rg = selectRG(state, id); - if (rg) { - rg.bbox = bbox; - rg.bboxNeedsUpdate = false; - } - }, rgDeleted: (state, action: PayloadAction<{ id: string }>) => { const { id } = action.payload; state.regions.entities = state.regions.entities.filter((ca) => ca.id !== id); @@ -232,25 +194,20 @@ export const regionsReducers = { } rg.ipAdapters = rg.ipAdapters.filter((ipAdapter) => ipAdapter.id !== ipAdapterId); }, - rgIPAdapterImageChanged: { - reducer: ( - state, - action: PayloadAction<{ id: string; ipAdapterId: string; imageDTO: ImageDTO | null; objectId: string }> - ) => { - const { id, ipAdapterId, imageDTO, objectId } = action.payload; - const rg = selectRG(state, id); - if (!rg) { - return; - } - const ipa = rg.ipAdapters.find((ipa) => ipa.id === ipAdapterId); - if (!ipa) { - return; - } - ipa.imageObject = imageDTO ? imageDTOToImageObject(id, objectId, imageDTO) : null; - }, - prepare: (payload: { id: string; ipAdapterId: string; imageDTO: ImageDTO | null }) => ({ - payload: { ...payload, objectId: uuidv4() }, - }), + rgIPAdapterImageChanged: ( + state, + action: PayloadAction<{ id: string; ipAdapterId: string; imageDTO: ImageDTO | null; objectId: string }> + ) => { + const { id, ipAdapterId, imageDTO } = action.payload; + const rg = selectRG(state, id); + if (!rg) { + return; + } + const ipa = rg.ipAdapters.find((ipa) => ipa.id === ipAdapterId); + if (!ipa) { + return; + } + ipa.imageObject = imageDTO ? imageDTOToImageObject(imageDTO) : null; }, rgIPAdapterWeightChanged: (state, action: PayloadAction<{ id: string; ipAdapterId: string; weight: number }>) => { const { id, ipAdapterId, weight } = action.payload; @@ -337,7 +294,6 @@ export const regionsReducers = { } rg.objects.push(brushLine); - rg.bboxNeedsUpdate = true; state.layers.imageCache = null; }, rgEraserLineAdded: (state, action: PayloadAction<{ id: string; eraserLine: CanvasEraserLineState }>) => { @@ -348,7 +304,6 @@ export const regionsReducers = { } rg.objects.push(eraserLine); - rg.bboxNeedsUpdate = true; state.layers.imageCache = null; }, rgRectAdded: (state, action: PayloadAction<{ id: string; rect: CanvasRectState }>) => { @@ -359,10 +314,9 @@ export const regionsReducers = { } rg.objects.push(rect); - rg.bboxNeedsUpdate = true; state.layers.imageCache = null; }, - regionMaskRasterized: (state, action: PayloadAction) => { + rgRasterized: (state, action: PayloadAction) => { const { id, imageObject, position } = action.payload; const rg = selectRG(state, id); if (!rg) { diff --git a/invokeai/frontend/web/src/features/controlLayers/store/types.ts b/invokeai/frontend/web/src/features/controlLayers/store/types.ts index 5fa10f9d85..993294832a 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/types.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/types.ts @@ -656,13 +656,11 @@ export const zCanvasRegionalGuidanceState = z.object({ type: z.literal('regional_guidance'), isEnabled: z.boolean(), position: zCoordinate, - bbox: zRect.nullable(), - bboxNeedsUpdate: z.boolean(), objects: z.array(zCanvasObjectState), + fill: zRgbColor, positivePrompt: zParameterPositivePrompt.nullable(), negativePrompt: zParameterNegativePrompt.nullable(), ipAdapters: z.array(zCanvasIPAdapterState), - fill: zRgbColor, autoNegative: zAutoNegative, imageCache: zImageWithDims.nullable(), }); @@ -682,10 +680,8 @@ const zCanvasInpaintMaskState = z.object({ type: z.literal('inpaint_mask'), isEnabled: z.boolean(), position: zCoordinate, - bbox: zRect.nullable(), - bboxNeedsUpdate: z.boolean(), - objects: z.array(zCanvasObjectState), fill: zRgbColor, + objects: z.array(zCanvasObjectState), imageCache: zImageWithDims.nullable(), }); export type CanvasInpaintMaskState = z.infer; @@ -705,8 +701,6 @@ const zCanvasControlAdapterStateBase = z.object({ type: z.literal('control_adapter'), isEnabled: z.boolean(), position: zCoordinate, - bbox: zRect.nullable(), - bboxNeedsUpdate: z.boolean(), opacity: zOpacity, filters: z.array(zFilter), weight: z.number().gte(-1).lte(2),