Files
InvokeAI/invokeai/frontend/web/src/features/controlLayers/konva/CanvasObject/CanvasObjectEraserLine.ts
2024-09-08 21:55:26 +10:00

91 lines
2.9 KiB
TypeScript

import { deepClone } from 'common/util/deepClone';
import type { CanvasEntityBufferObjectRenderer } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityBufferObjectRenderer';
import type { CanvasEntityObjectRenderer } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityObjectRenderer';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import { CanvasModuleBase } from 'features/controlLayers/konva/CanvasModuleBase';
import type { CanvasEraserLineState } from 'features/controlLayers/store/types';
import Konva from 'konva';
import type { Logger } from 'roarr';
export class CanvasObjectEraserLine extends CanvasModuleBase {
readonly type = 'object_eraser_line';
readonly id: string;
readonly path: string[];
readonly parent: CanvasEntityObjectRenderer | CanvasEntityBufferObjectRenderer;
readonly manager: CanvasManager;
readonly log: Logger;
state: CanvasEraserLineState;
konva: {
group: Konva.Group;
line: Konva.Line;
};
constructor(state: CanvasEraserLineState, parent: CanvasEntityObjectRenderer | CanvasEntityBufferObjectRenderer) {
super();
this.id = state.id;
this.parent = parent;
this.manager = parent.manager;
this.path = this.manager.buildPath(this);
this.log = this.manager.buildLogger(this);
this.log.debug({ state }, 'Creating eraser line renderer module');
this.konva = {
group: new Konva.Group({
name: `${this.type}:group`,
clip: state.clip,
listening: false,
}),
line: new Konva.Line({
name: `${this.type}:line`,
listening: false,
shadowForStrokeEnabled: false,
stroke: 'red', // Eraser lines use compositing, does not matter what color they have
tension: 0.3,
lineCap: 'round',
lineJoin: 'round',
globalCompositeOperation: 'destination-out',
}),
};
this.konva.group.add(this.konva.line);
this.state = state;
}
update(state: CanvasEraserLineState, force = false): boolean {
if (force || this.state !== state) {
this.log.trace({ state }, 'Updating eraser line');
const { points, strokeWidth } = state;
this.konva.line.setAttrs({
// A line with only one point will not be rendered, so we duplicate the points to make it visible
points: points.length === 2 ? [...points, ...points] : points,
strokeWidth,
});
this.state = state;
return true;
}
return false;
}
setVisibility(isVisible: boolean): void {
this.log.trace({ isVisible }, 'Setting brush line visibility');
this.konva.group.visible(isVisible);
}
destroy = () => {
this.log.debug('Destroying module');
this.konva.group.destroy();
};
repr = () => {
return {
id: this.id,
type: this.type,
path: this.path,
parent: this.parent.id,
state: deepClone(this.state),
};
};
}