diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/nodeManager.ts b/invokeai/frontend/web/src/features/controlLayers/konva/nodeManager.ts index 7612fbef38..e82f3144ac 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/nodeManager.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/nodeManager.ts @@ -138,13 +138,13 @@ export class KonvaNodeManager { new CanvasDocumentSizeOverlay(), new CanvasStagingArea() ); - this.stage.add(this.preview.konvaLayer); + this.stage.add(this.preview.layer); this.background = new CanvasBackground(); - this.stage.add(this.background.konvaLayer); + this.stage.add(this.background.layer); this.inpaintMask = new CanvasInpaintMask(this.stateApi.getInpaintMaskState(), this.stateApi.onPosChanged); - this.stage.add(this.inpaintMask.konvaLayer); + this.stage.add(this.inpaintMask.layer); this.layers = new Map(); this.regions = new Map(); @@ -167,7 +167,7 @@ export class KonvaNodeManager { if (!adapter) { adapter = new CanvasLayer(entity, this.stateApi.onPosChanged); this.layers.set(adapter.id, adapter); - this.stage.add(adapter.konvaLayer); + this.stage.add(adapter.layer); } adapter.render(entity, toolState.selected); } @@ -192,7 +192,7 @@ export class KonvaNodeManager { if (!adapter) { adapter = new CanvasRegion(entity, this.stateApi.onPosChanged); this.regions.set(adapter.id, adapter); - this.stage.add(adapter.konvaLayer); + this.stage.add(adapter.layer); } adapter.render(entity, toolState.selected, selectedEntity, maskOpacity); } @@ -222,7 +222,7 @@ export class KonvaNodeManager { if (!adapter) { adapter = new CanvasControlAdapter(entity); this.controlAdapters.set(adapter.id, adapter); - this.stage.add(adapter.konvaLayer); + this.stage.add(adapter.layer); } adapter.render(entity); } @@ -234,18 +234,18 @@ export class KonvaNodeManager { const controlAdapters = getControlAdaptersState().entities; const regions = getRegionsState().entities; let zIndex = 0; - this.background.konvaLayer.zIndex(++zIndex); + this.background.layer.zIndex(++zIndex); for (const layer of layers) { - this.layers.get(layer.id)?.konvaLayer.zIndex(++zIndex); + this.layers.get(layer.id)?.layer.zIndex(++zIndex); } for (const ca of controlAdapters) { - this.controlAdapters.get(ca.id)?.konvaLayer.zIndex(++zIndex); + this.controlAdapters.get(ca.id)?.layer.zIndex(++zIndex); } for (const rg of regions) { - this.regions.get(rg.id)?.konvaLayer.zIndex(++zIndex); + this.regions.get(rg.id)?.layer.zIndex(++zIndex); } - this.inpaintMask?.konvaLayer.zIndex(++zIndex); - this.preview.konvaLayer.zIndex(++zIndex); + this.inpaintMask?.layer.zIndex(++zIndex); + this.preview.layer.zIndex(++zIndex); } renderDocumentSizeOverlay() { @@ -297,8 +297,8 @@ export class KonvaNodeManager { } getInpaintMaskLayerClone(): Konva.Layer { - const layerClone = this.inpaintMask.konvaLayer.clone(); - const objectGroupClone = this.inpaintMask.konvaObjectGroup.clone(); + const layerClone = this.inpaintMask.layer.clone(); + const objectGroupClone = this.inpaintMask.group.clone(); layerClone.destroyChildren(); layerClone.add(objectGroupClone); @@ -315,8 +315,8 @@ export class KonvaNodeManager { const canvasRegion = this.regions.get(id); assert(canvasRegion, `Canvas region with id ${id} not found`); - const layerClone = canvasRegion.konvaLayer.clone(); - const objectGroupClone = canvasRegion.konvaObjectGroup.clone(); + const layerClone = canvasRegion.layer.clone(); + const objectGroupClone = canvasRegion.group.clone(); layerClone.destroyChildren(); layerClone.add(objectGroupClone); diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/background.ts b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/background.ts index a4d7521463..77dad03b27 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/background.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/background.ts @@ -29,14 +29,14 @@ const getGridSpacing = (scale: number): number => { }; export class CanvasBackground { - konvaLayer: Konva.Layer; + layer: Konva.Layer; constructor() { - this.konvaLayer = new Konva.Layer({ listening: false }); + this.layer = new Konva.Layer({ listening: false }); } renderBackground(stage: Konva.Stage): void { - this.konvaLayer.zIndex(0); + this.layer.zIndex(0); const scale = stage.scaleX(); const gridSpacing = getGridSpacing(scale); const x = stage.x(); @@ -80,11 +80,11 @@ export class CanvasBackground { let _x = 0; let _y = 0; - this.konvaLayer.destroyChildren(); + this.layer.destroyChildren(); for (let i = 0; i < xSteps; i++) { _x = gridFullRect.x1 + i * gridSpacing; - this.konvaLayer.add( + this.layer.add( new Konva.Line({ x: _x, y: gridFullRect.y1, @@ -97,7 +97,7 @@ export class CanvasBackground { } for (let i = 0; i < ySteps; i++) { _y = gridFullRect.y1 + i * gridSpacing; - this.konvaLayer.add( + this.layer.add( new Konva.Line({ x: gridFullRect.x1, y: _y, diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/controlAdapters.ts b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/controlAdapters.ts index a63ff80269..13f2b3a899 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/controlAdapters.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/controlAdapters.ts @@ -9,31 +9,31 @@ import { KonvaImage } from './objects'; export class CanvasControlAdapter { id: string; - konvaLayer: Konva.Layer; - konvaObjectGroup: Konva.Group; - konvaImageObject: KonvaImage | null; + layer: Konva.Layer; + group: Konva.Group; + image: KonvaImage | null; constructor(entity: ControlAdapterEntity) { const { id } = entity; this.id = id; - this.konvaLayer = new Konva.Layer({ + this.layer = new Konva.Layer({ id, imageSmoothingEnabled: false, listening: false, }); - this.konvaObjectGroup = new Konva.Group({ - id: getObjectGroupId(this.konvaLayer.id(), uuidv4()), + this.group = new Konva.Group({ + id: getObjectGroupId(this.layer.id(), uuidv4()), listening: false, }); - this.konvaLayer.add(this.konvaObjectGroup); - this.konvaImageObject = null; + this.layer.add(this.group); + this.image = null; } async render(entity: ControlAdapterEntity) { const imageObject = entity.processedImageObject ?? entity.imageObject; if (!imageObject) { - if (this.konvaImageObject) { - this.konvaImageObject.destroy(); + if (this.image) { + this.image.destroy(); } return; } @@ -42,8 +42,8 @@ export class CanvasControlAdapter { const visible = entity.isEnabled; const filters = entity.filter === 'LightnessToAlphaFilter' ? [LightnessToAlphaFilter] : []; - if (!this.konvaImageObject) { - this.konvaImageObject = await new KonvaImage({ + if (!this.image) { + this.image = await new KonvaImage({ imageObject, onLoad: (konvaImage) => { konvaImage.filters(filters); @@ -52,25 +52,25 @@ export class CanvasControlAdapter { konvaImage.visible(visible); }, }); - this.konvaObjectGroup.add(this.konvaImageObject.konvaImageGroup); + this.group.add(this.image.konvaImageGroup); } - if (this.konvaImageObject.isLoading || this.konvaImageObject.isError) { + if (this.image.isLoading || this.image.isError) { return; } - if (this.konvaImageObject.imageName !== imageObject.image.name) { - this.konvaImageObject.updateImageSource(imageObject.image.name); + if (this.image.imageName !== imageObject.image.name) { + this.image.updateImageSource(imageObject.image.name); } - if (this.konvaImageObject.konvaImage) { - if (!isEqual(this.konvaImageObject.konvaImage.filters(), filters)) { - this.konvaImageObject.konvaImage.filters(filters); - this.konvaImageObject.konvaImage.cache(); + if (this.image.konvaImage) { + if (!isEqual(this.image.konvaImage.filters(), filters)) { + this.image.konvaImage.filters(filters); + this.image.konvaImage.cache(); } - this.konvaImageObject.konvaImage.opacity(opacity); - this.konvaImageObject.konvaImage.visible(visible); + this.image.konvaImage.opacity(opacity); + this.image.konvaImage.visible(visible); } } destroy(): void { - this.konvaLayer.destroy(); + this.layer.destroy(); } } diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/inpaintMask.ts b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/inpaintMask.ts index db4f7b6cbf..eb7be06742 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/inpaintMask.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/inpaintMask.ts @@ -11,15 +11,15 @@ import { v4 as uuidv4 } from 'uuid'; export class CanvasInpaintMask { id: string; - konvaLayer: Konva.Layer; - konvaObjectGroup: Konva.Group; + layer: Konva.Layer; + group: Konva.Group; compositingRect: Konva.Rect; objects: Map; constructor(entity: InpaintMaskEntity, onPosChanged: StateApi['onPosChanged']) { this.id = entity.id; - this.konvaLayer = new Konva.Layer({ + this.layer = new Konva.Layer({ id: entity.id, draggable: true, dragDistance: 0, @@ -27,21 +27,21 @@ export class CanvasInpaintMask { // When a drag on the layer finishes, update the layer's position in state. During the drag, konva handles changing // the position - we do not need to call this on the `dragmove` event. - this.konvaLayer.on('dragend', function (e) { + this.layer.on('dragend', function (e) { onPosChanged({ id: entity.id, x: Math.floor(e.target.x()), y: Math.floor(e.target.y()) }, 'inpaint_mask'); }); - this.konvaObjectGroup = new Konva.Group({ - id: getObjectGroupId(this.konvaLayer.id(), uuidv4()), + this.group = new Konva.Group({ + id: getObjectGroupId(this.layer.id(), uuidv4()), listening: false, }); - this.konvaLayer.add(this.konvaObjectGroup); + this.layer.add(this.group); this.compositingRect = new Konva.Rect({ listening: false }); - this.konvaLayer.add(this.compositingRect); + this.layer.add(this.compositingRect); this.objects = new Map(); } destroy(): void { - this.konvaLayer.destroy(); + this.layer.destroy(); } async render( @@ -51,7 +51,7 @@ export class CanvasInpaintMask { maskOpacity: number ) { // Update the layer's position and listening state - this.konvaLayer.setAttrs({ + this.layer.setAttrs({ listening: selectedTool === 'move', // The layer only listens when using the move tool - otherwise the stage is handling mouse events x: Math.floor(inpaintMaskState.x), y: Math.floor(inpaintMaskState.y), @@ -81,7 +81,7 @@ export class CanvasInpaintMask { if (!brushLine) { brushLine = new KonvaBrushLine({ brushLine: obj }); this.objects.set(brushLine.id, brushLine); - this.konvaObjectGroup.add(brushLine.konvaLineGroup); + this.group.add(brushLine.konvaLineGroup); groupNeedsCache = true; } @@ -96,7 +96,7 @@ export class CanvasInpaintMask { if (!eraserLine) { eraserLine = new KonvaEraserLine({ eraserLine: obj }); this.objects.set(eraserLine.id, eraserLine); - this.konvaObjectGroup.add(eraserLine.konvaLineGroup); + this.group.add(eraserLine.konvaLineGroup); groupNeedsCache = true; } @@ -111,37 +111,37 @@ export class CanvasInpaintMask { if (!rect) { rect = new KonvaRect({ rectShape: obj }); this.objects.set(rect.id, rect); - this.konvaObjectGroup.add(rect.konvaRect); + this.group.add(rect.konvaRect); groupNeedsCache = true; } } } // Only update layer visibility if it has changed. - if (this.konvaLayer.visible() !== inpaintMaskState.isEnabled) { - this.konvaLayer.visible(inpaintMaskState.isEnabled); + if (this.layer.visible() !== inpaintMaskState.isEnabled) { + this.layer.visible(inpaintMaskState.isEnabled); groupNeedsCache = true; } if (this.objects.size === 0) { // No objects - clear the cache to reset the previous pixel data - this.konvaObjectGroup.clearCache(); + this.group.clearCache(); return; } // We must clear the cache first so Konva will re-draw the group with the new compositing rect - if (this.konvaObjectGroup.isCached()) { - this.konvaObjectGroup.clearCache(); + if (this.group.isCached()) { + this.group.clearCache(); } // The user is allowed to reduce mask opacity to 0, but we need the opacity for the compositing rect to work - this.konvaObjectGroup.opacity(1); + this.group.opacity(1); this.compositingRect.setAttrs({ // The rect should be the size of the layer - use the fast method if we don't have a pixel-perfect bbox already ...(!inpaintMaskState.bboxNeedsUpdate && inpaintMaskState.bbox ? inpaintMaskState.bbox - : getLayerBboxFast(this.konvaLayer)), + : getLayerBboxFast(this.layer)), fill: rgbColor, opacity: maskOpacity, // Draw this rect only where there are non-transparent pixels under it (e.g. the mask shapes) diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/layers.ts b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/layers.ts index c216f978b2..c34155648e 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/layers.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/layers.ts @@ -9,14 +9,14 @@ import { v4 as uuidv4 } from 'uuid'; export class CanvasLayer { id: string; - konvaLayer: Konva.Layer; - konvaObjectGroup: Konva.Group; + layer: Konva.Layer; + group: Konva.Group; objects: Map; constructor(entity: LayerEntity, onPosChanged: StateApi['onPosChanged']) { this.id = entity.id; - this.konvaLayer = new Konva.Layer({ + this.layer = new Konva.Layer({ id: entity.id, draggable: true, dragDistance: 0, @@ -24,25 +24,25 @@ export class CanvasLayer { // When a drag on the layer finishes, update the layer's position in state. During the drag, konva handles changing // the position - we do not need to call this on the `dragmove` event. - this.konvaLayer.on('dragend', function (e) { + this.layer.on('dragend', function (e) { onPosChanged({ id: entity.id, x: Math.floor(e.target.x()), y: Math.floor(e.target.y()) }, 'layer'); }); - const konvaObjectGroup = new Konva.Group({ - id: getObjectGroupId(this.konvaLayer.id(), uuidv4()), + const group = new Konva.Group({ + id: getObjectGroupId(this.layer.id(), uuidv4()), listening: false, }); - this.konvaObjectGroup = konvaObjectGroup; - this.konvaLayer.add(this.konvaObjectGroup); + this.group = group; + this.layer.add(this.group); this.objects = new Map(); } destroy(): void { - this.konvaLayer.destroy(); + this.layer.destroy(); } async render(layerState: LayerEntity, selectedTool: Tool) { // Update the layer's position and listening state - this.konvaLayer.setAttrs({ + this.layer.setAttrs({ listening: selectedTool === 'move', // The layer only listens when using the move tool - otherwise the stage is handling mouse events x: Math.floor(layerState.x), y: Math.floor(layerState.y), @@ -65,7 +65,7 @@ export class CanvasLayer { if (!brushLine) { brushLine = new KonvaBrushLine({ brushLine: obj }); this.objects.set(brushLine.id, brushLine); - this.konvaObjectGroup.add(brushLine.konvaLineGroup); + this.group.add(brushLine.konvaLineGroup); } if (obj.points.length !== brushLine.konvaLine.points().length) { brushLine.konvaLine.points(obj.points); @@ -77,7 +77,7 @@ export class CanvasLayer { if (!eraserLine) { eraserLine = new KonvaEraserLine({ eraserLine: obj }); this.objects.set(eraserLine.id, eraserLine); - this.konvaObjectGroup.add(eraserLine.konvaLineGroup); + this.group.add(eraserLine.konvaLineGroup); } if (obj.points.length !== eraserLine.konvaLine.points().length) { eraserLine.konvaLine.points(obj.points); @@ -89,7 +89,7 @@ export class CanvasLayer { if (!rect) { rect = new KonvaRect({ rectShape: obj }); this.objects.set(rect.id, rect); - this.konvaObjectGroup.add(rect.konvaRect); + this.group.add(rect.konvaRect); } } else if (obj.type === 'image') { let image = this.objects.get(obj.id); @@ -98,7 +98,7 @@ export class CanvasLayer { if (!image) { image = await new KonvaImage({ imageObject: obj }); this.objects.set(image.id, image); - this.konvaObjectGroup.add(image.konvaImageGroup); + this.group.add(image.konvaImageGroup); } if (image.imageName !== obj.image.name) { image.updateImageSource(obj.image.name); @@ -107,8 +107,8 @@ export class CanvasLayer { } // Only update layer visibility if it has changed. - if (this.konvaLayer.visible() !== layerState.isEnabled) { - this.konvaLayer.visible(layerState.isEnabled); + if (this.layer.visible() !== layerState.isEnabled) { + this.layer.visible(layerState.isEnabled); } // const bboxRect = konvaLayer.findOne(`.${LAYER_BBOX_NAME}`) ?? createBboxRect(layerState, konvaLayer); @@ -127,6 +127,6 @@ export class CanvasLayer { // } else { // bboxRect.visible(false); // } - this.konvaObjectGroup.opacity(layerState.opacity); + this.group.opacity(layerState.opacity); } } diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/preview.ts b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/preview.ts index 871e21353e..17051e79cf 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/preview.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/preview.ts @@ -6,7 +6,7 @@ import type { CanvasStagingArea } from './stagingArea'; import type { CanvasTool } from './tool'; export class CanvasPreview { - konvaLayer: Konva.Layer; + layer: Konva.Layer; tool: CanvasTool; bbox: CanvasBbox; documentSizeOverlay: CanvasDocumentSizeOverlay; @@ -18,18 +18,18 @@ export class CanvasPreview { documentSizeOverlay: CanvasDocumentSizeOverlay, stagingArea: CanvasStagingArea ) { - this.konvaLayer = new Konva.Layer({ listening: true }); + this.layer = new Konva.Layer({ listening: true }); this.bbox = bbox; - this.konvaLayer.add(this.bbox.group); + this.layer.add(this.bbox.group); this.tool = tool; - this.konvaLayer.add(this.tool.group); + this.layer.add(this.tool.group); this.documentSizeOverlay = documentSizeOverlay; - this.konvaLayer.add(this.documentSizeOverlay.group); + this.layer.add(this.documentSizeOverlay.group); this.stagingArea = stagingArea; - this.konvaLayer.add(this.stagingArea.group); + this.layer.add(this.stagingArea.group); } } diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/regions.ts b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/regions.ts index 7f6ebd5ddb..be6be27699 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/regions.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/regions.ts @@ -11,15 +11,15 @@ import { v4 as uuidv4 } from 'uuid'; export class CanvasRegion { id: string; - konvaLayer: Konva.Layer; - konvaObjectGroup: Konva.Group; + layer: Konva.Layer; + group: Konva.Group; compositingRect: Konva.Rect; objects: Map; constructor(entity: RegionEntity, onPosChanged: StateApi['onPosChanged']) { this.id = entity.id; - this.konvaLayer = new Konva.Layer({ + this.layer = new Konva.Layer({ id: entity.id, draggable: true, dragDistance: 0, @@ -27,21 +27,21 @@ export class CanvasRegion { // When a drag on the layer finishes, update the layer's position in state. During the drag, konva handles changing // the position - we do not need to call this on the `dragmove` event. - this.konvaLayer.on('dragend', function (e) { + this.layer.on('dragend', function (e) { onPosChanged({ id: entity.id, x: Math.floor(e.target.x()), y: Math.floor(e.target.y()) }, 'regional_guidance'); }); - this.konvaObjectGroup = new Konva.Group({ - id: getObjectGroupId(this.konvaLayer.id(), uuidv4()), + this.group = new Konva.Group({ + id: getObjectGroupId(this.layer.id(), uuidv4()), listening: false, }); - this.konvaLayer.add(this.konvaObjectGroup); + this.layer.add(this.group); this.compositingRect = new Konva.Rect({ listening: false }); - this.konvaLayer.add(this.compositingRect); + this.layer.add(this.compositingRect); this.objects = new Map(); } destroy(): void { - this.konvaLayer.destroy(); + this.layer.destroy(); } async render( @@ -51,7 +51,7 @@ export class CanvasRegion { maskOpacity: number ) { // Update the layer's position and listening state - this.konvaLayer.setAttrs({ + this.layer.setAttrs({ listening: selectedTool === 'move', // The layer only listens when using the move tool - otherwise the stage is handling mouse events x: Math.floor(regionState.x), y: Math.floor(regionState.y), @@ -81,7 +81,7 @@ export class CanvasRegion { if (!brushLine) { brushLine = new KonvaBrushLine({ brushLine: obj }); this.objects.set(brushLine.id, brushLine); - this.konvaObjectGroup.add(brushLine.konvaLineGroup); + this.group.add(brushLine.konvaLineGroup); groupNeedsCache = true; } @@ -96,7 +96,7 @@ export class CanvasRegion { if (!eraserLine) { eraserLine = new KonvaEraserLine({ eraserLine: obj }); this.objects.set(eraserLine.id, eraserLine); - this.konvaObjectGroup.add(eraserLine.konvaLineGroup); + this.group.add(eraserLine.konvaLineGroup); groupNeedsCache = true; } @@ -111,34 +111,34 @@ export class CanvasRegion { if (!rect) { rect = new KonvaRect({ rectShape: obj }); this.objects.set(rect.id, rect); - this.konvaObjectGroup.add(rect.konvaRect); + this.group.add(rect.konvaRect); groupNeedsCache = true; } } } // Only update layer visibility if it has changed. - if (this.konvaLayer.visible() !== regionState.isEnabled) { - this.konvaLayer.visible(regionState.isEnabled); + if (this.layer.visible() !== regionState.isEnabled) { + this.layer.visible(regionState.isEnabled); groupNeedsCache = true; } if (this.objects.size === 0) { // No objects - clear the cache to reset the previous pixel data - this.konvaObjectGroup.clearCache(); + this.group.clearCache(); return; } // We must clear the cache first so Konva will re-draw the group with the new compositing rect - if (this.konvaObjectGroup.isCached()) { - this.konvaObjectGroup.clearCache(); + if (this.group.isCached()) { + this.group.clearCache(); } // The user is allowed to reduce mask opacity to 0, but we need the opacity for the compositing rect to work - this.konvaObjectGroup.opacity(1); + this.group.opacity(1); this.compositingRect.setAttrs({ // The rect should be the size of the layer - use the fast method if we don't have a pixel-perfect bbox already - ...(!regionState.bboxNeedsUpdate && regionState.bbox ? regionState.bbox : getLayerBboxFast(this.konvaLayer)), + ...(!regionState.bboxNeedsUpdate && regionState.bbox ? regionState.bbox : getLayerBboxFast(this.layer)), fill: rgbColor, opacity: maskOpacity, // Draw this rect only where there are non-transparent pixels under it (e.g. the mask shapes)