From 86e1f4e8b04ce0fbdffcc85bbb3ba576c9b297c6 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Mon, 12 Aug 2024 22:02:46 +1000 Subject: [PATCH] feat(ui): more better logging & naming --- .../common/CanvasEntityContainer.tsx | 2 +- .../controlLayers/konva/CanvasBackground.ts | 10 +++- .../controlLayers/konva/CanvasBbox.ts | 58 ++++++++++++------- .../controlLayers/konva/CanvasBrushLine.ts | 12 +--- .../controlLayers/konva/CanvasEraserLine.ts | 11 +--- .../controlLayers/konva/CanvasImage.ts | 25 +++----- .../controlLayers/konva/CanvasLayerAdapter.ts | 9 +-- .../controlLayers/konva/CanvasMaskAdapter.ts | 8 +-- .../konva/CanvasObjectRenderer.ts | 15 ++--- .../konva/CanvasProgressImage.ts | 24 ++++++-- .../controlLayers/konva/CanvasRect.ts | 11 +--- .../controlLayers/konva/CanvasStagingArea.ts | 10 +--- .../controlLayers/konva/CanvasStateApi.ts | 2 +- .../controlLayers/konva/CanvasTool.ts | 50 ++++++++-------- .../controlLayers/konva/CanvasTransformer.ts | 15 ++--- 15 files changed, 126 insertions(+), 136 deletions(-) diff --git a/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityContainer.tsx b/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityContainer.tsx index 5cc84f8a32..2e29a49817 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityContainer.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityContainer.tsx @@ -1,8 +1,8 @@ import { Flex } from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; import { useEntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext'; -import { useEntitySelectionColor } from 'features/controlLayers/hooks/useEntitySelectionColor'; import { useEntityIsSelected } from 'features/controlLayers/hooks/useEntityIsSelected'; +import { useEntitySelectionColor } from 'features/controlLayers/hooks/useEntitySelectionColor'; import { entitySelected } from 'features/controlLayers/store/canvasV2Slice'; import type { PropsWithChildren } from 'react'; import { memo, useCallback } from 'react'; diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBackground.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBackground.ts index 1143b5f130..6dc5462ff9 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBackground.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBackground.ts @@ -1,13 +1,15 @@ import { getArbitraryBaseColor } from '@invoke-ai/ui-library'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; +import { getPrefixedId } from 'features/controlLayers/konva/util'; import Konva from 'konva'; export class CanvasBackground { - static BASE_NAME = 'background'; - static LAYER_NAME = `${CanvasBackground.BASE_NAME}_layer`; + readonly type = 'background_grid'; + static GRID_LINE_COLOR_COARSE = getArbitraryBaseColor(27); static GRID_LINE_COLOR_FINE = getArbitraryBaseColor(18); + id: string; manager: CanvasManager; konva: { @@ -20,8 +22,10 @@ export class CanvasBackground { subscriptions: Set<() => void> = new Set(); constructor(manager: CanvasManager) { + this.id = getPrefixedId(this.type); this.manager = manager; - this.konva = { layer: new Konva.Layer({ name: CanvasBackground.LAYER_NAME, listening: false }) }; + this.konva = { layer: new Konva.Layer({ name: `${this.type}:layer`, listening: false }) }; + this.subscriptions.add( this.manager.stateApi.$stageAttrs.listen(() => { this.render(); diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBbox.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBbox.ts index 18defa079f..983e574b63 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBbox.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBbox.ts @@ -1,31 +1,35 @@ +import type { JSONObject } from 'common/types'; import { roundToMultiple, roundToMultipleMin } from 'common/util/roundDownToMultiple'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasPreview } from 'features/controlLayers/konva/CanvasPreview'; +import { getPrefixedId } from 'features/controlLayers/konva/util'; import type { Rect } from 'features/controlLayers/store/types'; import Konva from 'konva'; import { atom } from 'nanostores'; +import type { Logger } from 'roarr'; import { assert } from 'tsafe'; -export class CanvasBbox { - static BASE_NAME = 'bbox'; - static GROUP_NAME = `${CanvasBbox.BASE_NAME}_group`; - static RECT_NAME = `${CanvasBbox.BASE_NAME}_rect`; - static TRANSFORMER_NAME = `${CanvasBbox.BASE_NAME}_transformer`; - static ALL_ANCHORS: string[] = [ - 'top-left', - 'top-center', - 'top-right', - 'middle-right', - 'middle-left', - 'bottom-left', - 'bottom-center', - 'bottom-right', - ]; - static CORNER_ANCHORS: string[] = ['top-left', 'top-right', 'bottom-left', 'bottom-right']; - static NO_ANCHORS: string[] = []; +const ALL_ANCHORS: string[] = [ + 'top-left', + 'top-center', + 'top-right', + 'middle-right', + 'middle-left', + 'bottom-left', + 'bottom-center', + 'bottom-right', +]; +const CORNER_ANCHORS: string[] = ['top-left', 'top-right', 'bottom-left', 'bottom-right']; +const NO_ANCHORS: string[] = []; +export class CanvasBbox { + readonly type = 'generation_bbox'; + + id: string; + path: string[]; parent: CanvasPreview; manager: CanvasManager; + log: Logger; konva: { group: Konva.Group; @@ -34,19 +38,25 @@ export class CanvasBbox { }; constructor(parent: CanvasPreview) { + this.id = getPrefixedId(this.type); this.parent = parent; this.manager = this.parent.manager; + this.path = this.manager.path.concat(this.id); + this.log = this.manager.buildLogger(this.getLoggingContext); + + this.log.trace('Creating bbox'); + // Create a stash to hold onto the last aspect ratio of the bbox - this allows for locking the aspect ratio when // transforming the bbox. const bbox = this.manager.stateApi.getBbox(); const $aspectRatioBuffer = atom(bbox.rect.width / bbox.rect.height); this.konva = { - group: new Konva.Group({ name: CanvasBbox.GROUP_NAME, listening: false }), + group: new Konva.Group({ name: `${this.type}:group`, listening: false }), // Use a transformer for the generation bbox. Transformers need some shape to transform, we will use a fully // transparent rect for this purpose. rect: new Konva.Rect({ - name: CanvasBbox.RECT_NAME, + name: `${this.type}:rect`, listening: false, strokeEnabled: false, draggable: true, @@ -56,7 +66,7 @@ export class CanvasBbox { height: bbox.rect.height, }), transformer: new Konva.Transformer({ - name: CanvasBbox.TRANSFORMER_NAME, + name: `${this.type}:transformer`, borderDash: [5, 5], borderStroke: 'rgba(212,216,234,1)', borderEnabled: true, @@ -160,7 +170,7 @@ export class CanvasBbox { // If shift is held and we are resizing from a corner, retain aspect ratio - needs special handling. We skip this // if alt/opt is held - this requires math too big for my brain. - if (shift && CanvasBbox.CORNER_ANCHORS.includes(anchor) && !alt) { + if (shift && CORNER_ANCHORS.includes(anchor) && !alt) { // Fit the bbox to the last aspect ratio let fittedWidth = Math.sqrt(width * height * $aspectRatioBuffer.get()); let fittedHeight = fittedWidth / $aspectRatioBuffer.get(); @@ -237,7 +247,11 @@ export class CanvasBbox { }); this.konva.transformer.setAttrs({ listening: toolState.selected === 'bbox', - enabledAnchors: toolState.selected === 'bbox' ? CanvasBbox.ALL_ANCHORS : CanvasBbox.NO_ANCHORS, + enabledAnchors: toolState.selected === 'bbox' ? ALL_ANCHORS : NO_ANCHORS, }); } + + getLoggingContext = (): JSONObject => { + return { ...this.manager.getLoggingContext(), path: this.path.join('.') }; + }; } diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBrushLine.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBrushLine.ts index 68d4e9ce2f..4cb6ca52b0 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBrushLine.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBrushLine.ts @@ -7,13 +7,8 @@ import type { CanvasBrushLineState } from 'features/controlLayers/store/types'; import Konva from 'konva'; import type { Logger } from 'roarr'; -const TYPE = 'brush_line'; - export class CanvasBrushLineRenderer { - static GROUP_NAME = `${TYPE}_group`; - static LINE_NAME = `${TYPE}_line`; - - readonly type = TYPE; + readonly type = 'brush_line_renderer'; id: string; path: string[]; @@ -33,19 +28,18 @@ export class CanvasBrushLineRenderer { this.parent = parent; this.manager = parent.manager; this.path = this.parent.path.concat(this.id); - this.log = this.manager.buildLogger(this.getLoggingContext); this.log.trace({ state }, 'Creating brush line'); this.konva = { group: new Konva.Group({ - name: CanvasBrushLineRenderer.GROUP_NAME, + name: `${this.type}:group`, clip, listening: false, }), line: new Konva.Line({ - name: CanvasBrushLineRenderer.LINE_NAME, + name: `${this.type}:line`, listening: false, shadowForStrokeEnabled: false, strokeWidth, diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEraserLine.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEraserLine.ts index 953c94144a..4417348557 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEraserLine.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEraserLine.ts @@ -8,13 +8,8 @@ import { RGBA_RED } from 'features/controlLayers/store/types'; import Konva from 'konva'; import type { Logger } from 'roarr'; -const TYPE = 'eraser_line'; - export class CanvasEraserLineRenderer { - static GROUP_NAME = `${TYPE}_group`; - static LINE_NAME = `${TYPE}_line`; - - readonly type = TYPE; + readonly type = 'eraser_line_renderer'; id: string; path: string[]; @@ -40,12 +35,12 @@ export class CanvasEraserLineRenderer { this.konva = { group: new Konva.Group({ - name: CanvasEraserLineRenderer.GROUP_NAME, + name: `${this.type}:group`, clip, listening: false, }), line: new Konva.Line({ - name: CanvasEraserLineRenderer.LINE_NAME, + name: `${this.type}:line`, listening: false, shadowForStrokeEnabled: false, strokeWidth, diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasImage.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasImage.ts index 30b9c75df6..9b691dcdb2 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasImage.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasImage.ts @@ -1,6 +1,7 @@ import { Mutex } from 'async-mutex'; import type { JSONObject } from 'common/types'; import { deepClone } from 'common/util/deepClone'; +import type { CanvasFilter } from 'features/controlLayers/konva/CanvasFilter'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasObjectRenderer } from 'features/controlLayers/konva/CanvasObjectRenderer'; import type { CanvasStagingArea } from 'features/controlLayers/konva/CanvasStagingArea'; @@ -12,20 +13,12 @@ import Konva from 'konva'; import type { Logger } from 'roarr'; import { getImageDTO } from 'services/api/endpoints/images'; -const TYPE = 'image'; - export class CanvasImageRenderer { - static GROUP_NAME = `${TYPE}_group`; - static IMAGE_NAME = `${TYPE}_image`; - static PLACEHOLDER_GROUP_NAME = `${TYPE}_placeholder-group`; - static PLACEHOLDER_RECT_NAME = `${TYPE}_placeholder-rect`; - static PLACEHOLDER_TEXT_NAME = `${TYPE}_placeholder-text`; - - readonly type = TYPE; + readonly type = 'image_renderer'; id: string; path: string[]; - parent: CanvasObjectRenderer | CanvasStagingArea; + parent: CanvasObjectRenderer | CanvasStagingArea | CanvasFilter; manager: CanvasManager; log: Logger; @@ -40,7 +33,7 @@ export class CanvasImageRenderer { isError: boolean = false; mutex = new Mutex(); - constructor(state: CanvasImageState, parent: CanvasObjectRenderer | CanvasStagingArea) { + constructor(state: CanvasImageState, parent: CanvasObjectRenderer | CanvasStagingArea | CanvasFilter) { const { id, image } = state; const { width, height } = image; this.id = id; @@ -52,18 +45,18 @@ export class CanvasImageRenderer { this.log.trace({ state }, 'Creating image'); this.konva = { - group: new Konva.Group({ name: CanvasImageRenderer.GROUP_NAME, listening: false }), + group: new Konva.Group({ name: `${this.type}:group`, listening: false }), placeholder: { - group: new Konva.Group({ name: CanvasImageRenderer.PLACEHOLDER_GROUP_NAME, listening: false }), + group: new Konva.Group({ name: `${this.type}:placeholder_group`, listening: false }), rect: new Konva.Rect({ - name: CanvasImageRenderer.PLACEHOLDER_RECT_NAME, + name: `${this.type}:placeholder_rect`, fill: 'hsl(220 12% 45% / 1)', // 'base.500' width, height, listening: false, }), text: new Konva.Text({ - name: CanvasImageRenderer.PLACEHOLDER_TEXT_NAME, + name: `${this.type}:placeholder_text`, fill: 'hsl(220 12% 10% / 1)', // 'base.900' width, height, @@ -135,7 +128,7 @@ export class CanvasImageRenderer { } else { this.log.trace('Creating new Konva image'); this.konva.image = new Konva.Image({ - name: CanvasImageRenderer.IMAGE_NAME, + name: `${this.type}:image`, listening: false, image: this.imageElement, width, diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasLayerAdapter.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasLayerAdapter.ts index 7b9dd47ea2..5217e8f687 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasLayerAdapter.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasLayerAdapter.ts @@ -8,10 +8,8 @@ import Konva from 'konva'; import { get } from 'lodash-es'; import type { Logger } from 'roarr'; -const TYPE = 'layer'; - export class CanvasLayerAdapter { - readonly type = TYPE; + readonly type = 'layer_adapter'; id: string; path: string[]; @@ -34,6 +32,7 @@ export class CanvasLayerAdapter { this.path = this.manager.path.concat(this.id); this.log = this.manager.buildLogger(this.getLoggingContext); this.log.debug({ state }, 'Creating layer'); + this.state = state; this.konva = { layer: new Konva.Layer({ @@ -48,15 +47,13 @@ export class CanvasLayerAdapter { this.renderer = new CanvasObjectRenderer(this); this.transformer = new CanvasTransformer(this); - - this.state = state; } /** * Get this entity's entity identifier */ getEntityIdentifier = (): CanvasEntityIdentifier => { - return { id: this.id, type: this.type }; + return { id: this.id, type: this.state.type }; }; destroy = (): void => { diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasMaskAdapter.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasMaskAdapter.ts index 28b8e9ac0c..550e15fa00 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasMaskAdapter.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasMaskAdapter.ts @@ -14,9 +14,10 @@ import { get } from 'lodash-es'; import type { Logger } from 'roarr'; export class CanvasMaskAdapter { + readonly type = 'mask_adapter'; + id: string; path: string[]; - type: CanvasInpaintMaskState['type'] | CanvasRegionalGuidanceState['type']; manager: CanvasManager; log: Logger; @@ -34,11 +35,11 @@ export class CanvasMaskAdapter { constructor(state: CanvasMaskAdapter['state'], manager: CanvasMaskAdapter['manager']) { this.id = state.id; - this.type = state.type; this.manager = manager; this.path = this.manager.path.concat(this.id); this.log = this.manager.buildLogger(this.getLoggingContext); this.log.debug({ state }, 'Creating mask'); + this.state = state; this.konva = { layer: new Konva.Layer({ @@ -54,7 +55,6 @@ export class CanvasMaskAdapter { this.renderer = new CanvasObjectRenderer(this); this.transformer = new CanvasTransformer(this); - this.state = state; this.maskOpacity = this.manager.stateApi.getMaskOpacity(); } @@ -62,7 +62,7 @@ export class CanvasMaskAdapter { * Get this entity's entity identifier */ getEntityIdentifier = (): CanvasEntityIdentifier => { - return { id: this.id, type: this.type }; + return { id: this.id, type: this.state.type }; }; destroy = (): void => { diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasObjectRenderer.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasObjectRenderer.ts index acef42c850..5b95330245 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasObjectRenderer.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasObjectRenderer.ts @@ -33,16 +33,11 @@ type AnyObjectRenderer = CanvasBrushLineRenderer | CanvasEraserLineRenderer | Ca */ type AnyObjectState = CanvasBrushLineState | CanvasEraserLineState | CanvasImageState | CanvasRectState; -const TYPE = 'object_renderer'; - /** * Handles rendering of objects for a canvas entity. */ export class CanvasObjectRenderer { - static KONVA_OBJECT_GROUP_NAME = `${TYPE}:object_group`; - static KONVA_COMPOSITING_RECT_NAME = `${TYPE}:compositing_rect`; - - readonly type = TYPE; + readonly type = 'object_renderer'; id: string; path: string[]; @@ -93,7 +88,7 @@ export class CanvasObjectRenderer { }; constructor(parent: CanvasLayerAdapter | CanvasMaskAdapter) { - this.id = getPrefixedId(TYPE); + this.id = getPrefixedId(this.type); this.parent = parent; this.path = this.parent.path.concat(this.id); this.manager = parent.manager; @@ -101,15 +96,15 @@ export class CanvasObjectRenderer { this.log.trace('Creating object renderer'); this.konva = { - objectGroup: new Konva.Group({ name: CanvasObjectRenderer.KONVA_OBJECT_GROUP_NAME, listening: false }), + objectGroup: new Konva.Group({ name: `${this.type}:object_group`, listening: false }), compositingRect: null, }; this.parent.konva.layer.add(this.konva.objectGroup); - if (this.parent.type === 'inpaint_mask' || this.parent.type === 'regional_guidance') { + if (this.parent.state.type === 'inpaint_mask' || this.parent.state.type === 'regional_guidance') { this.konva.compositingRect = new Konva.Rect({ - name: CanvasObjectRenderer.KONVA_COMPOSITING_RECT_NAME, + name: `${this.type}:compositing_rect`, globalCompositeOperation: 'source-in', listening: false, strokeEnabled: false, diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasProgressImage.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasProgressImage.ts index 64f16015b0..00c796b2c2 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasProgressImage.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasProgressImage.ts @@ -1,18 +1,20 @@ import { Mutex } from 'async-mutex'; +import type { JSONObject } from 'common/types'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasPreview } from 'features/controlLayers/konva/CanvasPreview'; import { getPrefixedId, loadImage } from 'features/controlLayers/konva/util'; import Konva from 'konva'; +import type { Logger } from 'roarr'; import type { InvocationDenoiseProgressEvent } from 'services/events/types'; export class CanvasProgressImage { - static NAME_PREFIX = 'progress-image'; - static GROUP_NAME = `${CanvasProgressImage.NAME_PREFIX}_group`; - static IMAGE_NAME = `${CanvasProgressImage.NAME_PREFIX}_image`; + readonly type = 'progress_image'; id: string; + path: string[]; parent: CanvasPreview; manager: CanvasManager; + log: Logger; /** * A set of subscriptions that should be cleaned up when the transformer is destroyed. @@ -33,11 +35,16 @@ export class CanvasProgressImage { mutex: Mutex = new Mutex(); constructor(parent: CanvasPreview) { - this.id = getPrefixedId(CanvasProgressImage.NAME_PREFIX); + this.id = getPrefixedId(this.type); this.parent = parent; this.manager = parent.manager; + this.path = this.manager.path.concat(this.id); + this.log = this.manager.buildLogger(this.getLoggingContext); + + this.log.trace('Creating progress image'); + this.konva = { - group: new Konva.Group({ name: CanvasProgressImage.GROUP_NAME, listening: false }), + group: new Konva.Group({ name: `${this.type}:group`, listening: false }), image: null, }; @@ -86,7 +93,7 @@ export class CanvasProgressImage { }); } else { this.konva.image = new Konva.Image({ - name: CanvasProgressImage.IMAGE_NAME, + name: `${this.type}:image`, listening: false, image: this.imageElement, x, @@ -106,9 +113,14 @@ export class CanvasProgressImage { }; destroy = () => { + this.log.trace('Destroying progress image'); for (const unsubscribe of this.subscriptions) { unsubscribe(); } this.konva.group.destroy(); }; + + getLoggingContext = (): JSONObject => { + return { ...this.manager.getLoggingContext(), path: this.path.join('.') }; + }; } diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasRect.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasRect.ts index 19e8b8bd76..9bb7340a4f 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasRect.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasRect.ts @@ -7,13 +7,8 @@ import type { CanvasRectState } from 'features/controlLayers/store/types'; import Konva from 'konva'; import type { Logger } from 'roarr'; -const TYPE = 'rect'; - export class CanvasRectRenderer { - static GROUP_NAME = `${TYPE}_group`; - static RECT_NAME = `${TYPE}_rect`; - - readonly type = TYPE; + readonly type = 'rect_renderer'; id: string; path: string[]; @@ -38,9 +33,9 @@ export class CanvasRectRenderer { this.log.trace({ state }, 'Creating rect'); this.konva = { - group: new Konva.Group({ name: CanvasRectRenderer.GROUP_NAME, listening: false }), + group: new Konva.Group({ name: `${this.type}:group`, listening: false }), rect: new Konva.Rect({ - name: CanvasRectRenderer.RECT_NAME, + name: `${this.type}:rect`, ...rect, listening: false, fill: rgbaColorToString(color), diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStagingArea.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStagingArea.ts index ad72042ec4..c58186a14d 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStagingArea.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStagingArea.ts @@ -7,12 +7,8 @@ import type { StagingAreaImage } from 'features/controlLayers/store/types'; import Konva from 'konva'; import type { Logger } from 'roarr'; -const TYPE = 'staging_area'; - export class CanvasStagingArea { - static GROUP_NAME = `${TYPE}_group`; - - readonly type = TYPE; + readonly type = 'staging_area'; id: string; path: string[]; @@ -31,14 +27,14 @@ export class CanvasStagingArea { subscriptions: Set<() => void> = new Set(); constructor(parent: CanvasPreview) { - this.id = getPrefixedId(TYPE); + this.id = getPrefixedId(this.type); this.parent = parent; this.manager = this.parent.manager; this.path = this.manager.path.concat(this.id); this.log = this.manager.buildLogger(this.getLoggingContext); this.log.debug('Creating staging area'); - this.konva = { group: new Konva.Group({ name: CanvasStagingArea.GROUP_NAME, listening: false }) }; + this.konva = { group: new Konva.Group({ name: `${this.type}:group`, listening: false }) }; this.image = null; this.selectedImage = null; diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts index 0027bdf589..c4397a7336 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts @@ -209,7 +209,7 @@ export class CanvasStateApi { entityAdapter = this.manager.inpaintMask; } - if (entityState && entityAdapter && entityState.type === entityAdapter.type) { + if (entityState && entityAdapter) { return { id: entityState.id, type: entityState.type, diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasTool.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasTool.ts index 9eaa0bcee8..7821d70dc1 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasTool.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasTool.ts @@ -1,3 +1,4 @@ +import type { JSONObject } from 'common/types'; import { rgbaColorToString } from 'common/util/colorCodeTransformers'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasPreview } from 'features/controlLayers/konva/CanvasPreview'; @@ -6,28 +7,19 @@ import { BRUSH_BORDER_OUTER_COLOR, BRUSH_ERASER_BORDER_WIDTH, } from 'features/controlLayers/konva/constants'; -import { alignCoordForTool } from 'features/controlLayers/konva/util'; +import { alignCoordForTool, getPrefixedId } from 'features/controlLayers/konva/util'; import Konva from 'konva'; +import type { Logger } from 'roarr'; export class CanvasTool { - static NAME_PREFIX = 'tool'; - - static GROUP_NAME = `${CanvasTool.NAME_PREFIX}_group`; - - static BRUSH_NAME_PREFIX = `${CanvasTool.NAME_PREFIX}_brush`; - static BRUSH_GROUP_NAME = `${CanvasTool.BRUSH_NAME_PREFIX}_group`; - static BRUSH_FILL_CIRCLE_NAME = `${CanvasTool.BRUSH_NAME_PREFIX}_fill-circle`; - static BRUSH_INNER_BORDER_CIRCLE_NAME = `${CanvasTool.BRUSH_NAME_PREFIX}_inner-border-circle`; - static BRUSH_OUTER_BORDER_CIRCLE_NAME = `${CanvasTool.BRUSH_NAME_PREFIX}_outer-border-circle`; - - static ERASER_NAME_PREFIX = `${CanvasTool.NAME_PREFIX}_eraser`; - static ERASER_GROUP_NAME = `${CanvasTool.ERASER_NAME_PREFIX}_group`; - static ERASER_FILL_CIRCLE_NAME = `${CanvasTool.ERASER_NAME_PREFIX}_fill-circle`; - static ERASER_INNER_BORDER_CIRCLE_NAME = `${CanvasTool.ERASER_NAME_PREFIX}_inner-border-circle`; - static ERASER_OUTER_BORDER_CIRCLE_NAME = `${CanvasTool.ERASER_NAME_PREFIX}_outer-border-circle`; + readonly type = 'tool_preview'; + id: string; + path: string[]; parent: CanvasPreview; manager: CanvasManager; + log: Logger; + konva: { group: Konva.Group; brush: { @@ -50,26 +42,29 @@ export class CanvasTool { subscriptions: Set<() => void> = new Set(); constructor(parent: CanvasPreview) { + this.id = getPrefixedId(this.type); this.parent = parent; this.manager = this.parent.manager; + this.path = this.manager.path.concat(this.id); + this.log = this.manager.buildLogger(this.getLoggingContext); this.konva = { - group: new Konva.Group({ name: CanvasTool.GROUP_NAME }), + group: new Konva.Group({ name: `${this.type}:group` }), brush: { - group: new Konva.Group({ name: CanvasTool.BRUSH_GROUP_NAME }), + group: new Konva.Group({ name: `${this.type}:brush_group` }), fillCircle: new Konva.Circle({ - name: CanvasTool.BRUSH_FILL_CIRCLE_NAME, + name: `${this.type}:brush_fill_circle`, listening: false, strokeEnabled: false, }), innerBorderCircle: new Konva.Circle({ - name: CanvasTool.BRUSH_INNER_BORDER_CIRCLE_NAME, + name: `${this.type}:brush_inner_border_circle`, listening: false, stroke: BRUSH_BORDER_INNER_COLOR, strokeWidth: BRUSH_ERASER_BORDER_WIDTH, strokeEnabled: true, }), outerBorderCircle: new Konva.Circle({ - name: CanvasTool.BRUSH_OUTER_BORDER_CIRCLE_NAME, + name: `${this.type}:brush_outer_border_circle`, listening: false, stroke: BRUSH_BORDER_OUTER_COLOR, strokeWidth: BRUSH_ERASER_BORDER_WIDTH, @@ -77,23 +72,23 @@ export class CanvasTool { }), }, eraser: { - group: new Konva.Group({ name: CanvasTool.ERASER_GROUP_NAME }), + group: new Konva.Group({ name: `${this.type}:eraser_group` }), fillCircle: new Konva.Circle({ - name: CanvasTool.ERASER_FILL_CIRCLE_NAME, + name: `${this.type}:eraser_fill_circle`, listening: false, strokeEnabled: false, fill: 'white', globalCompositeOperation: 'destination-out', }), innerBorderCircle: new Konva.Circle({ - name: CanvasTool.ERASER_INNER_BORDER_CIRCLE_NAME, + name: `${this.type}:eraser_inner_border_circle`, listening: false, stroke: BRUSH_BORDER_INNER_COLOR, strokeWidth: BRUSH_ERASER_BORDER_WIDTH, strokeEnabled: true, }), outerBorderCircle: new Konva.Circle({ - name: CanvasTool.ERASER_OUTER_BORDER_CIRCLE_NAME, + name: `${this.type}:eraser_outer_border_circle`, listening: false, stroke: BRUSH_BORDER_OUTER_COLOR, strokeWidth: BRUSH_ERASER_BORDER_WIDTH, @@ -160,6 +155,7 @@ export class CanvasTool { const isMouseDown = this.manager.stateApi.$isMouseDown.get(); const tool = toolState.selected; + console.log(selectedEntity); const isDrawableEntity = selectedEntity?.state.type === 'regional_guidance' || selectedEntity?.state.type === 'layer' || @@ -258,4 +254,8 @@ export class CanvasTool { } } } + + getLoggingContext = (): JSONObject => { + return { ...this.manager.getLoggingContext(), path: this.path.join('.') }; + }; } diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasTransformer.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasTransformer.ts index 75d4bf95cc..7b71014c35 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasTransformer.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasTransformer.ts @@ -17,10 +17,7 @@ import type { Logger } from 'roarr'; * It renders an outline when dragging and resizing the entity, with transform anchors for resizing and rotation. */ export class CanvasTransformer { - static TYPE = 'entity_transformer'; - static KONVA_TRANSFORMER_NAME = `${CanvasTransformer.TYPE}:transformer`; - static KONVA_PROXY_RECT_NAME = `${CanvasTransformer.TYPE}:proxy_rect`; - static KONVA_OUTLINE_RECT_NAME = `${CanvasTransformer.TYPE}:outline_rect`; + readonly type = 'entity_transformer'; static RECT_CALC_DEBOUNCE_MS = 300; static OUTLINE_PADDING = 0; @@ -38,8 +35,6 @@ export class CanvasTransformer { static ROTATE_ANCHOR_STROKE_COLOR = 'hsl(200 76% 40% / 1)'; // invokeBlue.700 static ROTATE_ANCHOR_SIZE = 12; - readonly type = CanvasTransformer.TYPE; - id: string; path: string[]; parent: CanvasLayerAdapter | CanvasMaskAdapter; @@ -100,7 +95,7 @@ export class CanvasTransformer { }; constructor(parent: CanvasLayerAdapter | CanvasMaskAdapter) { - this.id = getPrefixedId(CanvasTransformer.TYPE); + this.id = getPrefixedId(this.type); this.parent = parent; this.manager = parent.manager; this.path = this.parent.path.concat(this.id); @@ -110,13 +105,13 @@ export class CanvasTransformer { outlineRect: new Konva.Rect({ listening: false, draggable: false, - name: CanvasTransformer.KONVA_OUTLINE_RECT_NAME, + name: `${this.type}:outline_rect`, stroke: CanvasTransformer.OUTLINE_COLOR, perfectDrawEnabled: false, strokeHitEnabled: false, }), transformer: new Konva.Transformer({ - name: CanvasTransformer.KONVA_TRANSFORMER_NAME, + name: `${this.type}:transformer`, // Visibility and listening are managed via activate() and deactivate() visible: false, listening: false, @@ -235,7 +230,7 @@ export class CanvasTransformer { }, }), proxyRect: new Konva.Rect({ - name: CanvasTransformer.KONVA_PROXY_RECT_NAME, + name: `${this.type}:proxy_rect`, listening: false, draggable: true, }),