diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBackgroundModule.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBackgroundModule.ts index b700392c05f..cbc964cd292 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBackgroundModule.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBackgroundModule.ts @@ -161,36 +161,52 @@ export class CanvasBackgroundModule extends CanvasModuleBase { let _x = 0; let _y = 0; - this.konva.linesGroup.destroyChildren(); - this.konva.lines = []; + const totalLines = xSteps + ySteps; + this.konva.lines.splice(totalLines).forEach((line) => line.destroy()); + + let lineIndex = 0; for (let i = 0; i < xSteps; i++) { _x = gridFullRect.x1 + i * gridSpacing; - const line = new Konva.Line({ + const line = + this.konva.lines[lineIndex] ?? + new Konva.Line({ + listening: false, + perfectDrawEnabled: false, + }); + line.setAttrs({ x: _x, y: gridFullRect.y1, points: [0, 0, 0, ySize], stroke: _x % 64 ? this.config.GRID_LINE_COLOR_FINE : this.config.GRID_LINE_COLOR_COARSE, strokeWidth, - listening: false, - perfectDrawEnabled: false, }); - this.konva.lines.push(line); - this.konva.linesGroup.add(line); + this.konva.lines[lineIndex] = line; + if (line.getParent() !== this.konva.linesGroup) { + this.konva.linesGroup.add(line); + } + lineIndex += 1; } for (let i = 0; i < ySteps; i++) { _y = gridFullRect.y1 + i * gridSpacing; - const line = new Konva.Line({ + const line = + this.konva.lines[lineIndex] ?? + new Konva.Line({ + listening: false, + perfectDrawEnabled: false, + }); + line.setAttrs({ x: gridFullRect.x1, y: _y, points: [0, 0, xSize, 0], stroke: _y % 64 ? this.config.GRID_LINE_COLOR_FINE : this.config.GRID_LINE_COLOR_COARSE, strokeWidth, - listening: false, - perfectDrawEnabled: false, }); - this.konva.lines.push(line); - this.konva.linesGroup.add(line); + this.konva.lines[lineIndex] = line; + if (line.getParent() !== this.konva.linesGroup) { + this.konva.linesGroup.add(line); + } + lineIndex += 1; } }; diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStageModule.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStageModule.ts index b205d724555..e28f17be47e 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStageModule.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStageModule.ts @@ -7,6 +7,7 @@ import type { Coordinate, Dimensions, Rect, StageAttrs } from 'features/controlL import Konva from 'konva'; import type { KonvaEventObject } from 'konva/lib/Node'; import { atom, computed } from 'nanostores'; +import rafThrottle from 'raf-throttle'; import type { Logger } from 'roarr'; type CanvasStageModuleConfig = { @@ -488,9 +489,13 @@ export class CanvasStageModule extends CanvasModuleBase { return; } - this.syncStageAttrs(); + this.syncStageAttrsThrottled(); }; + syncStageAttrsThrottled = rafThrottle(() => { + this.syncStageAttrs(); + }); + onStageDragEnd = (e: KonvaEventObject) => { if (e.target !== this.konva.stage) { return; @@ -592,6 +597,7 @@ export class CanvasStageModule extends CanvasModuleBase { destroy = () => { this.log.debug('Destroying module'); + this.syncStageAttrsThrottled.cancel(); this.subscriptions.forEach((unsubscribe) => unsubscribe()); this.subscriptions.clear(); if (this.resizeObserver) {