mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
refactor(ui): node manager handles more tedious annoying stuff
This commit is contained in:
parent
f41539532f
commit
3b864921ac
@ -1,3 +1,4 @@
|
|||||||
|
import type { KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
||||||
import { renderBackgroundLayer } from 'features/controlLayers/konva/renderers/background';
|
import { renderBackgroundLayer } from 'features/controlLayers/konva/renderers/background';
|
||||||
import {
|
import {
|
||||||
renderDocumentBoundsOverlay,
|
renderDocumentBoundsOverlay,
|
||||||
@ -32,7 +33,7 @@ import {
|
|||||||
import { PREVIEW_TOOL_GROUP_ID } from './naming';
|
import { PREVIEW_TOOL_GROUP_ID } from './naming';
|
||||||
|
|
||||||
type Arg = {
|
type Arg = {
|
||||||
stage: Konva.Stage;
|
manager: KonvaNodeManager;
|
||||||
getToolState: () => CanvasV2State['tool'];
|
getToolState: () => CanvasV2State['tool'];
|
||||||
getCurrentFill: () => RgbaColor;
|
getCurrentFill: () => RgbaColor;
|
||||||
setTool: (tool: Tool) => void;
|
setTool: (tool: Tool) => void;
|
||||||
@ -135,7 +136,7 @@ const maybeAddNextPoint = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const setStageEventHandlers = ({
|
export const setStageEventHandlers = ({
|
||||||
stage,
|
manager,
|
||||||
getToolState,
|
getToolState,
|
||||||
getCurrentFill,
|
getCurrentFill,
|
||||||
setTool,
|
setTool,
|
||||||
@ -164,16 +165,14 @@ export const setStageEventHandlers = ({
|
|||||||
onBrushWidthChanged: onBrushSizeChanged,
|
onBrushWidthChanged: onBrushSizeChanged,
|
||||||
onEraserWidthChanged: onEraserSizeChanged,
|
onEraserWidthChanged: onEraserSizeChanged,
|
||||||
}: Arg): (() => void) => {
|
}: Arg): (() => void) => {
|
||||||
|
const stage = manager.stage;
|
||||||
|
|
||||||
//#region mouseenter
|
//#region mouseenter
|
||||||
stage.on('mouseenter', (e) => {
|
stage.on('mouseenter', () => {
|
||||||
const stage = e.target.getStage();
|
|
||||||
if (!stage) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const tool = getToolState().selected;
|
const tool = getToolState().selected;
|
||||||
stage.findOne<Konva.Layer>(`#${PREVIEW_TOOL_GROUP_ID}`)?.visible(tool === 'brush' || tool === 'eraser');
|
stage.findOne<Konva.Layer>(`#${PREVIEW_TOOL_GROUP_ID}`)?.visible(tool === 'brush' || tool === 'eraser');
|
||||||
renderToolPreview(
|
renderToolPreview(
|
||||||
stage,
|
manager,
|
||||||
getToolState(),
|
getToolState(),
|
||||||
getCurrentFill(),
|
getCurrentFill(),
|
||||||
getSelectedEntity(),
|
getSelectedEntity(),
|
||||||
@ -186,10 +185,6 @@ export const setStageEventHandlers = ({
|
|||||||
|
|
||||||
//#region mousedown
|
//#region mousedown
|
||||||
stage.on('mousedown', (e) => {
|
stage.on('mousedown', (e) => {
|
||||||
const stage = e.target.getStage();
|
|
||||||
if (!stage) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setIsMouseDown(true);
|
setIsMouseDown(true);
|
||||||
const toolState = getToolState();
|
const toolState = getToolState();
|
||||||
const pos = updateLastCursorPos(stage, setLastCursorPos);
|
const pos = updateLastCursorPos(stage, setLastCursorPos);
|
||||||
@ -307,7 +302,7 @@ export const setStageEventHandlers = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
renderToolPreview(
|
renderToolPreview(
|
||||||
stage,
|
manager,
|
||||||
getToolState(),
|
getToolState(),
|
||||||
getCurrentFill(),
|
getCurrentFill(),
|
||||||
getSelectedEntity(),
|
getSelectedEntity(),
|
||||||
@ -319,11 +314,7 @@ export const setStageEventHandlers = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
//#region mouseup
|
//#region mouseup
|
||||||
stage.on('mouseup', (e) => {
|
stage.on('mouseup', () => {
|
||||||
const stage = e.target.getStage();
|
|
||||||
if (!stage) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setIsMouseDown(false);
|
setIsMouseDown(false);
|
||||||
const pos = getLastCursorPos();
|
const pos = getLastCursorPos();
|
||||||
const selectedEntity = getSelectedEntity();
|
const selectedEntity = getSelectedEntity();
|
||||||
@ -360,7 +351,7 @@ export const setStageEventHandlers = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderToolPreview(
|
renderToolPreview(
|
||||||
stage,
|
manager,
|
||||||
getToolState(),
|
getToolState(),
|
||||||
getCurrentFill(),
|
getCurrentFill(),
|
||||||
getSelectedEntity(),
|
getSelectedEntity(),
|
||||||
@ -372,11 +363,7 @@ export const setStageEventHandlers = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
//#region mousemove
|
//#region mousemove
|
||||||
stage.on('mousemove', (e) => {
|
stage.on('mousemove', () => {
|
||||||
const stage = e.target.getStage();
|
|
||||||
if (!stage) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const toolState = getToolState();
|
const toolState = getToolState();
|
||||||
const pos = updateLastCursorPos(stage, setLastCursorPos);
|
const pos = updateLastCursorPos(stage, setLastCursorPos);
|
||||||
const selectedEntity = getSelectedEntity();
|
const selectedEntity = getSelectedEntity();
|
||||||
@ -481,7 +468,7 @@ export const setStageEventHandlers = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderToolPreview(
|
renderToolPreview(
|
||||||
stage,
|
manager,
|
||||||
getToolState(),
|
getToolState(),
|
||||||
getCurrentFill(),
|
getCurrentFill(),
|
||||||
getSelectedEntity(),
|
getSelectedEntity(),
|
||||||
@ -493,11 +480,7 @@ export const setStageEventHandlers = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
//#region mouseleave
|
//#region mouseleave
|
||||||
stage.on('mouseleave', (e) => {
|
stage.on('mouseleave', () => {
|
||||||
const stage = e.target.getStage();
|
|
||||||
if (!stage) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const pos = updateLastCursorPos(stage, setLastCursorPos);
|
const pos = updateLastCursorPos(stage, setLastCursorPos);
|
||||||
setIsDrawing(false);
|
setIsDrawing(false);
|
||||||
setLastCursorPos(null);
|
setLastCursorPos(null);
|
||||||
@ -525,7 +508,7 @@ export const setStageEventHandlers = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderToolPreview(
|
renderToolPreview(
|
||||||
stage,
|
manager,
|
||||||
getToolState(),
|
getToolState(),
|
||||||
getCurrentFill(),
|
getCurrentFill(),
|
||||||
getSelectedEntity(),
|
getSelectedEntity(),
|
||||||
@ -574,13 +557,13 @@ export const setStageEventHandlers = ({
|
|||||||
stage.scaleY(newScale);
|
stage.scaleY(newScale);
|
||||||
stage.position(newPos);
|
stage.position(newPos);
|
||||||
setStageAttrs({ ...newPos, width: stage.width(), height: stage.height(), scale: newScale });
|
setStageAttrs({ ...newPos, width: stage.width(), height: stage.height(), scale: newScale });
|
||||||
renderBackgroundLayer(stage);
|
renderBackgroundLayer(manager);
|
||||||
scaleToolPreview(stage, getToolState());
|
scaleToolPreview(manager, getToolState());
|
||||||
renderDocumentBoundsOverlay(stage, getDocument);
|
renderDocumentBoundsOverlay(manager, getDocument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
renderToolPreview(
|
renderToolPreview(
|
||||||
stage,
|
manager,
|
||||||
getToolState(),
|
getToolState(),
|
||||||
getCurrentFill(),
|
getCurrentFill(),
|
||||||
getSelectedEntity(),
|
getSelectedEntity(),
|
||||||
@ -600,10 +583,10 @@ export const setStageEventHandlers = ({
|
|||||||
height: stage.height(),
|
height: stage.height(),
|
||||||
scale: stage.scaleX(),
|
scale: stage.scaleX(),
|
||||||
});
|
});
|
||||||
renderBackgroundLayer(stage);
|
renderBackgroundLayer(manager);
|
||||||
renderDocumentBoundsOverlay(stage, getDocument);
|
renderDocumentBoundsOverlay(manager, getDocument);
|
||||||
renderToolPreview(
|
renderToolPreview(
|
||||||
stage,
|
manager,
|
||||||
getToolState(),
|
getToolState(),
|
||||||
getCurrentFill(),
|
getCurrentFill(),
|
||||||
getSelectedEntity(),
|
getSelectedEntity(),
|
||||||
@ -625,7 +608,7 @@ export const setStageEventHandlers = ({
|
|||||||
scale: stage.scaleX(),
|
scale: stage.scaleX(),
|
||||||
});
|
});
|
||||||
renderToolPreview(
|
renderToolPreview(
|
||||||
stage,
|
manager,
|
||||||
getToolState(),
|
getToolState(),
|
||||||
getCurrentFill(),
|
getCurrentFill(),
|
||||||
getSelectedEntity(),
|
getSelectedEntity(),
|
||||||
@ -656,12 +639,12 @@ export const setStageEventHandlers = ({
|
|||||||
} else if (e.key === 'r') {
|
} else if (e.key === 'r') {
|
||||||
const stageAttrs = fitDocumentToStage(stage, getDocument());
|
const stageAttrs = fitDocumentToStage(stage, getDocument());
|
||||||
setStageAttrs(stageAttrs);
|
setStageAttrs(stageAttrs);
|
||||||
scaleToolPreview(stage, getToolState());
|
scaleToolPreview(manager, getToolState());
|
||||||
renderBackgroundLayer(stage);
|
renderBackgroundLayer(manager);
|
||||||
renderDocumentBoundsOverlay(stage, getDocument);
|
renderDocumentBoundsOverlay(manager, getDocument);
|
||||||
}
|
}
|
||||||
renderToolPreview(
|
renderToolPreview(
|
||||||
stage,
|
manager,
|
||||||
getToolState(),
|
getToolState(),
|
||||||
getCurrentFill(),
|
getCurrentFill(),
|
||||||
getSelectedEntity(),
|
getSelectedEntity(),
|
||||||
@ -688,7 +671,7 @@ export const setStageEventHandlers = ({
|
|||||||
setSpaceKey(false);
|
setSpaceKey(false);
|
||||||
}
|
}
|
||||||
renderToolPreview(
|
renderToolPreview(
|
||||||
stage,
|
manager,
|
||||||
getToolState(),
|
getToolState(),
|
||||||
getCurrentFill(),
|
getCurrentFill(),
|
||||||
getSelectedEntity(),
|
getSelectedEntity(),
|
||||||
|
@ -1,4 +1,19 @@
|
|||||||
import type { BrushLine, EraserLine, ImageObject, RectShape } from 'features/controlLayers/store/types';
|
import { createBackgroundLayer } from 'features/controlLayers/konva/renderers/background';
|
||||||
|
import {
|
||||||
|
createBboxPreview,
|
||||||
|
createDocumentOverlay,
|
||||||
|
createPreviewLayer,
|
||||||
|
createToolPreview,
|
||||||
|
} from 'features/controlLayers/konva/renderers/preview';
|
||||||
|
import type {
|
||||||
|
BrushLine,
|
||||||
|
CanvasEntity,
|
||||||
|
CanvasV2State,
|
||||||
|
EraserLine,
|
||||||
|
ImageObject,
|
||||||
|
Rect,
|
||||||
|
RectShape,
|
||||||
|
} from 'features/controlLayers/store/types';
|
||||||
import type Konva from 'konva';
|
import type Konva from 'konva';
|
||||||
|
|
||||||
export type BrushLineObjectRecord = {
|
export type BrushLineObjectRecord = {
|
||||||
@ -37,26 +52,78 @@ type ObjectRecord = BrushLineObjectRecord | EraserLineObjectRecord | RectShapeOb
|
|||||||
|
|
||||||
export class KonvaNodeManager {
|
export class KonvaNodeManager {
|
||||||
stage: Konva.Stage;
|
stage: Konva.Stage;
|
||||||
adapters: Map<string, EntityKonvaAdapter>;
|
adapters: Map<string, KonvaEntityAdapter>;
|
||||||
|
background: { layer: Konva.Layer };
|
||||||
|
preview: {
|
||||||
|
layer: Konva.Layer;
|
||||||
|
bbox: {
|
||||||
|
group: Konva.Group;
|
||||||
|
rect: Konva.Rect;
|
||||||
|
transformer: Konva.Transformer;
|
||||||
|
};
|
||||||
|
tool: {
|
||||||
|
group: Konva.Group;
|
||||||
|
brush: {
|
||||||
|
group: Konva.Group;
|
||||||
|
fill: Konva.Circle;
|
||||||
|
innerBorder: Konva.Circle;
|
||||||
|
outerBorder: Konva.Circle;
|
||||||
|
};
|
||||||
|
rect: {
|
||||||
|
rect: Konva.Rect;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
documentOverlay: {
|
||||||
|
group: Konva.Group;
|
||||||
|
innerRect: Konva.Rect;
|
||||||
|
outerRect: Konva.Rect;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
constructor(stage: Konva.Stage) {
|
constructor(
|
||||||
|
stage: Konva.Stage,
|
||||||
|
getBbox: () => CanvasV2State['bbox'],
|
||||||
|
onBboxTransformed: (bbox: Rect) => void,
|
||||||
|
getShiftKey: () => boolean,
|
||||||
|
getCtrlKey: () => boolean,
|
||||||
|
getMetaKey: () => boolean,
|
||||||
|
getAltKey: () => boolean
|
||||||
|
) {
|
||||||
this.stage = stage;
|
this.stage = stage;
|
||||||
this.adapters = new Map();
|
this.adapters = new Map();
|
||||||
|
|
||||||
|
this.background = { layer: createBackgroundLayer() };
|
||||||
|
this.stage.add(this.background.layer);
|
||||||
|
|
||||||
|
this.preview = {
|
||||||
|
layer: createPreviewLayer(),
|
||||||
|
bbox: createBboxPreview(stage, getBbox, onBboxTransformed, getShiftKey, getCtrlKey, getMetaKey, getAltKey),
|
||||||
|
tool: createToolPreview(stage),
|
||||||
|
documentOverlay: createDocumentOverlay(),
|
||||||
|
};
|
||||||
|
this.preview.layer.add(this.preview.bbox.group);
|
||||||
|
this.preview.layer.add(this.preview.tool.group);
|
||||||
|
this.preview.layer.add(this.preview.documentOverlay.group);
|
||||||
|
this.stage.add(this.preview.layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
add(id: string, konvaLayer: Konva.Layer, konvaObjectGroup: Konva.Group): EntityKonvaAdapter {
|
add(entity: CanvasEntity, konvaLayer: Konva.Layer, konvaObjectGroup: Konva.Group): KonvaEntityAdapter {
|
||||||
const adapter = new EntityKonvaAdapter(id, konvaLayer, konvaObjectGroup, this);
|
const adapter = new KonvaEntityAdapter(entity, konvaLayer, konvaObjectGroup, this);
|
||||||
this.adapters.set(id, adapter);
|
this.adapters.set(adapter.id, adapter);
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
get(id: string): EntityKonvaAdapter | undefined {
|
get(id: string): KonvaEntityAdapter | undefined {
|
||||||
return this.adapters.get(id);
|
return this.adapters.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAll(): EntityKonvaAdapter[] {
|
getAll(type?: CanvasEntity['type']): KonvaEntityAdapter[] {
|
||||||
|
if (type) {
|
||||||
|
return Array.from(this.adapters.values()).filter((adapter) => adapter.entityType === type);
|
||||||
|
} else {
|
||||||
return Array.from(this.adapters.values());
|
return Array.from(this.adapters.values());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
destroy(id: string): boolean {
|
destroy(id: string): boolean {
|
||||||
const adapter = this.get(id);
|
const adapter = this.get(id);
|
||||||
@ -68,15 +135,17 @@ export class KonvaNodeManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EntityKonvaAdapter {
|
export class KonvaEntityAdapter {
|
||||||
id: string;
|
id: string;
|
||||||
|
entityType: CanvasEntity['type'];
|
||||||
konvaLayer: Konva.Layer; // Every entity is associated with a konva layer
|
konvaLayer: Konva.Layer; // Every entity is associated with a konva layer
|
||||||
konvaObjectGroup: Konva.Group; // Every entity's nodes are part of an object group
|
konvaObjectGroup: Konva.Group; // Every entity's nodes are part of an object group
|
||||||
objectRecords: Map<string, ObjectRecord>;
|
objectRecords: Map<string, ObjectRecord>;
|
||||||
manager: KonvaNodeManager;
|
manager: KonvaNodeManager;
|
||||||
|
|
||||||
constructor(id: string, konvaLayer: Konva.Layer, konvaObjectGroup: Konva.Group, manager: KonvaNodeManager) {
|
constructor(entity: CanvasEntity, konvaLayer: Konva.Layer, konvaObjectGroup: Konva.Group, manager: KonvaNodeManager) {
|
||||||
this.id = id;
|
this.id = entity.id;
|
||||||
|
this.entityType = entity.type;
|
||||||
this.konvaLayer = konvaLayer;
|
this.konvaLayer = konvaLayer;
|
||||||
this.konvaObjectGroup = konvaObjectGroup;
|
this.konvaObjectGroup = konvaObjectGroup;
|
||||||
this.objectRecords = new Map();
|
this.objectRecords = new Map();
|
||||||
|
@ -1,27 +1,22 @@
|
|||||||
import { BACKGROUND_LAYER_ID, PREVIEW_LAYER_ID } from 'features/controlLayers/konva/naming';
|
|
||||||
import type { KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
import type { KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
||||||
import type { ControlAdapterEntity, LayerEntity, RegionEntity } from 'features/controlLayers/store/types';
|
import type { ControlAdapterEntity, LayerEntity, RegionEntity } from 'features/controlLayers/store/types';
|
||||||
import type Konva from 'konva';
|
|
||||||
|
|
||||||
export const arrangeEntities = (
|
export const arrangeEntities = (
|
||||||
stage: Konva.Stage,
|
manager: KonvaNodeManager,
|
||||||
layerManager: KonvaNodeManager,
|
|
||||||
layers: LayerEntity[],
|
layers: LayerEntity[],
|
||||||
controlAdapterManager: KonvaNodeManager,
|
|
||||||
controlAdapters: ControlAdapterEntity[],
|
controlAdapters: ControlAdapterEntity[],
|
||||||
regionManager: KonvaNodeManager,
|
|
||||||
regions: RegionEntity[]
|
regions: RegionEntity[]
|
||||||
): void => {
|
): void => {
|
||||||
let zIndex = 0;
|
let zIndex = 0;
|
||||||
stage.findOne<Konva.Layer>(`#${BACKGROUND_LAYER_ID}`)?.zIndex(++zIndex);
|
manager.background.layer.zIndex(++zIndex);
|
||||||
for (const layer of layers) {
|
for (const layer of layers) {
|
||||||
layerManager.get(layer.id)?.konvaLayer.zIndex(++zIndex);
|
manager.get(layer.id)?.konvaLayer.zIndex(++zIndex);
|
||||||
}
|
}
|
||||||
for (const ca of controlAdapters) {
|
for (const ca of controlAdapters) {
|
||||||
controlAdapterManager.get(ca.id)?.konvaLayer.zIndex(++zIndex);
|
manager.get(ca.id)?.konvaLayer.zIndex(++zIndex);
|
||||||
}
|
}
|
||||||
for (const rg of regions) {
|
for (const rg of regions) {
|
||||||
regionManager.get(rg.id)?.konvaLayer.zIndex(++zIndex);
|
manager.get(rg.id)?.konvaLayer.zIndex(++zIndex);
|
||||||
}
|
}
|
||||||
stage.findOne<Konva.Layer>(`#${PREVIEW_LAYER_ID}`)?.zIndex(++zIndex);
|
manager.preview.layer.zIndex(++zIndex);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { getArbitraryBaseColor } from '@invoke-ai/ui-library';
|
import { getArbitraryBaseColor } from '@invoke-ai/ui-library';
|
||||||
import { BACKGROUND_LAYER_ID } from 'features/controlLayers/konva/naming';
|
import { BACKGROUND_LAYER_ID } from 'features/controlLayers/konva/naming';
|
||||||
|
import type { KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
||||||
import Konva from 'konva';
|
import Konva from 'konva';
|
||||||
|
|
||||||
const baseGridLineColor = getArbitraryBaseColor(27);
|
const baseGridLineColor = getArbitraryBaseColor(27);
|
||||||
@ -24,26 +25,17 @@ const getGridSpacing = (scale: number): number => {
|
|||||||
return 256;
|
return 256;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getBackgroundLayer = (stage: Konva.Stage): Konva.Layer => {
|
export const createBackgroundLayer = (): Konva.Layer => new Konva.Layer({ id: BACKGROUND_LAYER_ID, listening: false });
|
||||||
let background = stage.findOne<Konva.Layer>(`#${BACKGROUND_LAYER_ID}`);
|
|
||||||
if (background) {
|
|
||||||
return background;
|
|
||||||
}
|
|
||||||
|
|
||||||
background = new Konva.Layer({ id: BACKGROUND_LAYER_ID });
|
export const renderBackgroundLayer = (manager: KonvaNodeManager): void => {
|
||||||
stage.add(background);
|
const background = manager.background.layer;
|
||||||
return background;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const renderBackgroundLayer = (stage: Konva.Stage): void => {
|
|
||||||
const background = getBackgroundLayer(stage);
|
|
||||||
background.zIndex(0);
|
background.zIndex(0);
|
||||||
const scale = stage.scaleX();
|
const scale = manager.stage.scaleX();
|
||||||
const gridSpacing = getGridSpacing(scale);
|
const gridSpacing = getGridSpacing(scale);
|
||||||
const x = stage.x();
|
const x = manager.stage.x();
|
||||||
const y = stage.y();
|
const y = manager.stage.y();
|
||||||
const width = stage.width();
|
const width = manager.stage.width();
|
||||||
const height = stage.height();
|
const height = manager.stage.height();
|
||||||
const stageRect = {
|
const stageRect = {
|
||||||
x1: 0,
|
x1: 0,
|
||||||
y1: 0,
|
y1: 0,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { LightnessToAlphaFilter } from 'features/controlLayers/konva/filters';
|
import { LightnessToAlphaFilter } from 'features/controlLayers/konva/filters';
|
||||||
import { CA_LAYER_IMAGE_NAME, CA_LAYER_NAME, CA_LAYER_OBJECT_GROUP_NAME } from 'features/controlLayers/konva/naming';
|
import { CA_LAYER_IMAGE_NAME, CA_LAYER_NAME, CA_LAYER_OBJECT_GROUP_NAME } from 'features/controlLayers/konva/naming';
|
||||||
import type { EntityKonvaAdapter, ImageObjectRecord, KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
import type { ImageObjectRecord, KonvaEntityAdapter, KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
||||||
import {
|
import {
|
||||||
createImageObjectGroup,
|
createImageObjectGroup,
|
||||||
createObjectGroup,
|
createObjectGroup,
|
||||||
@ -21,7 +21,7 @@ import { assert } from 'tsafe';
|
|||||||
* @param stage The konva stage
|
* @param stage The konva stage
|
||||||
* @param entity The control adapter layer state
|
* @param entity The control adapter layer state
|
||||||
*/
|
*/
|
||||||
const getControlAdapter = (manager: KonvaNodeManager, entity: ControlAdapterEntity): EntityKonvaAdapter => {
|
const getControlAdapter = (manager: KonvaNodeManager, entity: ControlAdapterEntity): KonvaEntityAdapter => {
|
||||||
const adapter = manager.get(entity.id);
|
const adapter = manager.get(entity.id);
|
||||||
if (adapter) {
|
if (adapter) {
|
||||||
return adapter;
|
return adapter;
|
||||||
@ -33,7 +33,7 @@ const getControlAdapter = (manager: KonvaNodeManager, entity: ControlAdapterEnti
|
|||||||
listening: false,
|
listening: false,
|
||||||
});
|
});
|
||||||
const konvaObjectGroup = createObjectGroup(konvaLayer, CA_LAYER_OBJECT_GROUP_NAME);
|
const konvaObjectGroup = createObjectGroup(konvaLayer, CA_LAYER_OBJECT_GROUP_NAME);
|
||||||
return manager.add(entity.id, konvaLayer, konvaObjectGroup);
|
return manager.add(entity, konvaLayer, konvaObjectGroup);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,7 +103,7 @@ export const renderControlAdapter = async (manager: KonvaNodeManager, entity: Co
|
|||||||
|
|
||||||
export const renderControlAdapters = (manager: KonvaNodeManager, entities: ControlAdapterEntity[]): void => {
|
export const renderControlAdapters = (manager: KonvaNodeManager, entities: ControlAdapterEntity[]): void => {
|
||||||
// Destroy nonexistent layers
|
// Destroy nonexistent layers
|
||||||
for (const adapters of manager.getAll()) {
|
for (const adapters of manager.getAll('control_adapter')) {
|
||||||
if (!entities.find((ca) => ca.id === adapters.id)) {
|
if (!entities.find((ca) => ca.id === adapters.id)) {
|
||||||
manager.destroy(adapters.id);
|
manager.destroy(adapters.id);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
RASTER_LAYER_OBJECT_GROUP_NAME,
|
RASTER_LAYER_OBJECT_GROUP_NAME,
|
||||||
RASTER_LAYER_RECT_SHAPE_NAME,
|
RASTER_LAYER_RECT_SHAPE_NAME,
|
||||||
} from 'features/controlLayers/konva/naming';
|
} from 'features/controlLayers/konva/naming';
|
||||||
import type { EntityKonvaAdapter, KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
import type { KonvaEntityAdapter, KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
||||||
import {
|
import {
|
||||||
createImageObjectGroup,
|
createImageObjectGroup,
|
||||||
createObjectGroup,
|
createObjectGroup,
|
||||||
@ -29,11 +29,11 @@ import Konva from 'konva';
|
|||||||
* @param onPosChanged Callback for when the layer's position changes
|
* @param onPosChanged Callback for when the layer's position changes
|
||||||
*/
|
*/
|
||||||
const getLayer = (
|
const getLayer = (
|
||||||
map: KonvaNodeManager,
|
manager: KonvaNodeManager,
|
||||||
entity: LayerEntity,
|
entity: LayerEntity,
|
||||||
onPosChanged?: (arg: PosChangedArg, entityType: CanvasEntity['type']) => void
|
onPosChanged?: (arg: PosChangedArg, entityType: CanvasEntity['type']) => void
|
||||||
): EntityKonvaAdapter => {
|
): KonvaEntityAdapter => {
|
||||||
const adapter = map.get(entity.id);
|
const adapter = manager.get(entity.id);
|
||||||
if (adapter) {
|
if (adapter) {
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ const getLayer = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const konvaObjectGroup = createObjectGroup(konvaLayer, RASTER_LAYER_OBJECT_GROUP_NAME);
|
const konvaObjectGroup = createObjectGroup(konvaLayer, RASTER_LAYER_OBJECT_GROUP_NAME);
|
||||||
return map.add(entity.id, konvaLayer, konvaObjectGroup);
|
return manager.add(entity, konvaLayer, konvaObjectGroup);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -140,7 +140,7 @@ export const renderLayers = (
|
|||||||
onPosChanged?: (arg: PosChangedArg, entityType: CanvasEntity['type']) => void
|
onPosChanged?: (arg: PosChangedArg, entityType: CanvasEntity['type']) => void
|
||||||
): void => {
|
): void => {
|
||||||
// Destroy nonexistent layers
|
// Destroy nonexistent layers
|
||||||
for (const adapter of manager.getAll()) {
|
for (const adapter of manager.getAll('layer')) {
|
||||||
if (!entities.find((l) => l.id === adapter.id)) {
|
if (!entities.find((l) => l.id === adapter.id)) {
|
||||||
manager.destroy(adapter.id);
|
manager.destroy(adapter.id);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
} from 'features/controlLayers/konva/naming';
|
} from 'features/controlLayers/konva/naming';
|
||||||
import type {
|
import type {
|
||||||
BrushLineObjectRecord,
|
BrushLineObjectRecord,
|
||||||
EntityKonvaAdapter,
|
KonvaEntityAdapter,
|
||||||
EraserLineObjectRecord,
|
EraserLineObjectRecord,
|
||||||
ImageObjectRecord,
|
ImageObjectRecord,
|
||||||
RectShapeObjectRecord,
|
RectShapeObjectRecord,
|
||||||
@ -40,7 +40,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
* @param name The konva name for the line
|
* @param name The konva name for the line
|
||||||
*/
|
*/
|
||||||
export const getBrushLine = (
|
export const getBrushLine = (
|
||||||
adapter: EntityKonvaAdapter,
|
adapter: KonvaEntityAdapter,
|
||||||
brushLine: BrushLine,
|
brushLine: BrushLine,
|
||||||
name: string
|
name: string
|
||||||
): BrushLineObjectRecord => {
|
): BrushLineObjectRecord => {
|
||||||
@ -75,7 +75,7 @@ export const getBrushLine = (
|
|||||||
* @param name The konva name for the line
|
* @param name The konva name for the line
|
||||||
*/
|
*/
|
||||||
export const getEraserLine = (
|
export const getEraserLine = (
|
||||||
adapter: EntityKonvaAdapter,
|
adapter: KonvaEntityAdapter,
|
||||||
eraserLine: EraserLine,
|
eraserLine: EraserLine,
|
||||||
name: string
|
name: string
|
||||||
): EraserLineObjectRecord => {
|
): EraserLineObjectRecord => {
|
||||||
@ -111,7 +111,7 @@ export const getEraserLine = (
|
|||||||
* @param name The konva name for the rect
|
* @param name The konva name for the rect
|
||||||
*/
|
*/
|
||||||
export const getRectShape = (
|
export const getRectShape = (
|
||||||
adapter: EntityKonvaAdapter,
|
adapter: KonvaEntityAdapter,
|
||||||
rectShape: RectShape,
|
rectShape: RectShape,
|
||||||
name: string
|
name: string
|
||||||
): RectShapeObjectRecord => {
|
): RectShapeObjectRecord => {
|
||||||
@ -203,7 +203,7 @@ export const updateImageSource = async (arg: {
|
|||||||
* @returns The konva group for the image placeholder, and callbacks to handle loading and error states
|
* @returns The konva group for the image placeholder, and callbacks to handle loading and error states
|
||||||
*/
|
*/
|
||||||
export const createImageObjectGroup = (arg: {
|
export const createImageObjectGroup = (arg: {
|
||||||
adapter: EntityKonvaAdapter;
|
adapter: KonvaEntityAdapter;
|
||||||
obj: ImageObject;
|
obj: ImageObject;
|
||||||
name: string;
|
name: string;
|
||||||
getImageDTO?: (imageName: string) => Promise<ImageDTO | null>;
|
getImageDTO?: (imageName: string) => Promise<ImageDTO | null>;
|
||||||
|
@ -18,29 +18,15 @@ import {
|
|||||||
PREVIEW_RECT_ID,
|
PREVIEW_RECT_ID,
|
||||||
PREVIEW_TOOL_GROUP_ID,
|
PREVIEW_TOOL_GROUP_ID,
|
||||||
} from 'features/controlLayers/konva/naming';
|
} from 'features/controlLayers/konva/naming';
|
||||||
import { selectRenderableLayers } from 'features/controlLayers/konva/util';
|
import type { KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
||||||
import type { CanvasEntity, CanvasV2State, RgbaColor, Tool } from 'features/controlLayers/store/types';
|
import type { CanvasEntity, CanvasV2State, RgbaColor, Tool } from 'features/controlLayers/store/types';
|
||||||
import Konva from 'konva';
|
import Konva from 'konva';
|
||||||
import type { IRect, Vector2d } from 'konva/lib/types';
|
import type { IRect, Vector2d } from 'konva/lib/types';
|
||||||
import { atom } from 'nanostores';
|
import { atom } from 'nanostores';
|
||||||
import { assert } from 'tsafe';
|
|
||||||
|
|
||||||
/**
|
export const createPreviewLayer = (): Konva.Layer => new Konva.Layer({ id: PREVIEW_LAYER_ID, listening: true });
|
||||||
* Creates the singleton preview layer and all its objects.
|
|
||||||
* @param stage The konva stage
|
|
||||||
*/
|
|
||||||
const getPreviewLayer = (stage: Konva.Stage): Konva.Layer => {
|
|
||||||
let previewLayer = stage.findOne<Konva.Layer>(`#${PREVIEW_LAYER_ID}`);
|
|
||||||
if (previewLayer) {
|
|
||||||
return previewLayer;
|
|
||||||
}
|
|
||||||
// Initialize the preview layer & add to the stage
|
|
||||||
previewLayer = new Konva.Layer({ id: PREVIEW_LAYER_ID, listening: true });
|
|
||||||
stage.add(previewLayer);
|
|
||||||
return previewLayer;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getBboxPreviewGroup = (
|
export const createBboxPreview = (
|
||||||
stage: Konva.Stage,
|
stage: Konva.Stage,
|
||||||
getBbox: () => IRect,
|
getBbox: () => IRect,
|
||||||
onBboxTransformed: (bbox: IRect) => void,
|
onBboxTransformed: (bbox: IRect) => void,
|
||||||
@ -48,14 +34,7 @@ export const getBboxPreviewGroup = (
|
|||||||
getCtrlKey: () => boolean,
|
getCtrlKey: () => boolean,
|
||||||
getMetaKey: () => boolean,
|
getMetaKey: () => boolean,
|
||||||
getAltKey: () => boolean
|
getAltKey: () => boolean
|
||||||
): Konva.Group => {
|
): { group: Konva.Group; rect: Konva.Rect; transformer: Konva.Transformer } => {
|
||||||
const previewLayer = getPreviewLayer(stage);
|
|
||||||
let bboxPreviewGroup = previewLayer.findOne<Konva.Group>(`#${PREVIEW_GENERATION_BBOX_GROUP}`);
|
|
||||||
|
|
||||||
if (bboxPreviewGroup) {
|
|
||||||
return bboxPreviewGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a stash to hold onto the last aspect ratio of the bbox - this allows for locking the aspect ratio when
|
// Create a stash to hold onto the last aspect ratio of the bbox - this allows for locking the aspect ratio when
|
||||||
// transforming the bbox.
|
// transforming the bbox.
|
||||||
const bbox = getBbox();
|
const bbox = getBbox();
|
||||||
@ -63,28 +42,28 @@ export const getBboxPreviewGroup = (
|
|||||||
|
|
||||||
// Use a transformer for the generation bbox. Transformers need some shape to transform, we will use a fully
|
// Use a transformer for the generation bbox. Transformers need some shape to transform, we will use a fully
|
||||||
// transparent rect for this purpose.
|
// transparent rect for this purpose.
|
||||||
bboxPreviewGroup = new Konva.Group({ id: PREVIEW_GENERATION_BBOX_GROUP, listening: false });
|
const group = new Konva.Group({ id: PREVIEW_GENERATION_BBOX_GROUP, listening: false });
|
||||||
const bboxRect = new Konva.Rect({
|
const rect = new Konva.Rect({
|
||||||
id: PREVIEW_GENERATION_BBOX_DUMMY_RECT,
|
id: PREVIEW_GENERATION_BBOX_DUMMY_RECT,
|
||||||
listening: false,
|
listening: false,
|
||||||
strokeEnabled: false,
|
strokeEnabled: false,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
...getBbox(),
|
...getBbox(),
|
||||||
});
|
});
|
||||||
bboxRect.on('dragmove', () => {
|
rect.on('dragmove', () => {
|
||||||
const gridSize = getCtrlKey() || getMetaKey() ? 8 : 64;
|
const gridSize = getCtrlKey() || getMetaKey() ? 8 : 64;
|
||||||
const oldBbox = getBbox();
|
const oldBbox = getBbox();
|
||||||
const newBbox: IRect = {
|
const newBbox: IRect = {
|
||||||
...oldBbox,
|
...oldBbox,
|
||||||
x: roundToMultiple(bboxRect.x(), gridSize),
|
x: roundToMultiple(rect.x(), gridSize),
|
||||||
y: roundToMultiple(bboxRect.y(), gridSize),
|
y: roundToMultiple(rect.y(), gridSize),
|
||||||
};
|
};
|
||||||
bboxRect.setAttrs(newBbox);
|
rect.setAttrs(newBbox);
|
||||||
if (oldBbox.x !== newBbox.x || oldBbox.y !== newBbox.y) {
|
if (oldBbox.x !== newBbox.x || oldBbox.y !== newBbox.y) {
|
||||||
onBboxTransformed(newBbox);
|
onBboxTransformed(newBbox);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const bboxTransformer = new Konva.Transformer({
|
const transformer = new Konva.Transformer({
|
||||||
id: PREVIEW_GENERATION_BBOX_TRANSFORMER,
|
id: PREVIEW_GENERATION_BBOX_TRANSFORMER,
|
||||||
borderDash: [5, 5],
|
borderDash: [5, 5],
|
||||||
borderStroke: 'rgba(212,216,234,1)',
|
borderStroke: 'rgba(212,216,234,1)',
|
||||||
@ -136,11 +115,11 @@ export const getBboxPreviewGroup = (
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
bboxTransformer.on('transform', () => {
|
transformer.on('transform', () => {
|
||||||
// In the transform callback, we calculate the bbox's new dims and pos and update the konva object.
|
// In the transform callback, we calculate the bbox's new dims and pos and update the konva object.
|
||||||
|
|
||||||
// Some special handling is needed depending on the anchor being dragged.
|
// Some special handling is needed depending on the anchor being dragged.
|
||||||
const anchor = bboxTransformer.getActiveAnchor();
|
const anchor = transformer.getActiveAnchor();
|
||||||
if (!anchor) {
|
if (!anchor) {
|
||||||
// Pretty sure we should always have an anchor here?
|
// Pretty sure we should always have an anchor here?
|
||||||
return;
|
return;
|
||||||
@ -163,14 +142,14 @@ export const getBboxPreviewGroup = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The coords should be correct per the anchorDragBoundFunc.
|
// The coords should be correct per the anchorDragBoundFunc.
|
||||||
let x = bboxRect.x();
|
let x = rect.x();
|
||||||
let y = bboxRect.y();
|
let y = rect.y();
|
||||||
|
|
||||||
// Konva transforms by scaling the dims, not directly changing width and height. At this point, the width and height
|
// Konva transforms by scaling the dims, not directly changing width and height. At this point, the width and height
|
||||||
// *have not changed*, only the scale has changed. To get the final height, we need to scale the dims and then snap
|
// *have not changed*, only the scale has changed. To get the final height, we need to scale the dims and then snap
|
||||||
// them to the grid.
|
// them to the grid.
|
||||||
let width = roundToMultipleMin(bboxRect.width() * bboxRect.scaleX(), gridSize);
|
let width = roundToMultipleMin(rect.width() * rect.scaleX(), gridSize);
|
||||||
let height = roundToMultipleMin(bboxRect.height() * bboxRect.scaleY(), gridSize);
|
let height = roundToMultipleMin(rect.height() * rect.scaleY(), gridSize);
|
||||||
|
|
||||||
// If shift is held and we are resizing from a corner, retain aspect ratio - needs special handling. We skip this
|
// 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 alt/opt is held - this requires math too big for my brain.
|
||||||
@ -210,7 +189,7 @@ export const getBboxPreviewGroup = (
|
|||||||
// Update the bboxRect's attrs directly with the new transform, and reset its scale to 1.
|
// Update the bboxRect's attrs directly with the new transform, and reset its scale to 1.
|
||||||
// TODO(psyche): In `renderBboxPreview()` we also call setAttrs, need to do it twice to ensure it renders correctly.
|
// TODO(psyche): In `renderBboxPreview()` we also call setAttrs, need to do it twice to ensure it renders correctly.
|
||||||
// Gotta be a way to avoid setting it twice...
|
// Gotta be a way to avoid setting it twice...
|
||||||
bboxRect.setAttrs({ ...bbox, scaleX: 1, scaleY: 1 });
|
rect.setAttrs({ ...bbox, scaleX: 1, scaleY: 1 });
|
||||||
|
|
||||||
// Update the bbox in internal state.
|
// Update the bbox in internal state.
|
||||||
onBboxTransformed(bbox);
|
onBboxTransformed(bbox);
|
||||||
@ -222,18 +201,17 @@ export const getBboxPreviewGroup = (
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
bboxTransformer.on('transformend', () => {
|
transformer.on('transformend', () => {
|
||||||
// Always update the aspect ratio buffer when the transform ends, so if the next transform starts with shift held,
|
// Always update the aspect ratio buffer when the transform ends, so if the next transform starts with shift held,
|
||||||
// we have the correct aspect ratio to start from.
|
// we have the correct aspect ratio to start from.
|
||||||
$aspectRatioBuffer.set(bboxRect.width() / bboxRect.height());
|
$aspectRatioBuffer.set(rect.width() / rect.height());
|
||||||
});
|
});
|
||||||
|
|
||||||
// The transformer will always be transforming the dummy rect
|
// The transformer will always be transforming the dummy rect
|
||||||
bboxTransformer.nodes([bboxRect]);
|
transformer.nodes([rect]);
|
||||||
bboxPreviewGroup.add(bboxRect);
|
group.add(rect);
|
||||||
bboxPreviewGroup.add(bboxTransformer);
|
group.add(transformer);
|
||||||
previewLayer.add(bboxPreviewGroup);
|
return { group, rect, transformer };
|
||||||
return bboxPreviewGroup;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const ALL_ANCHORS: string[] = [
|
const ALL_ANCHORS: string[] = [
|
||||||
@ -249,79 +227,66 @@ const ALL_ANCHORS: string[] = [
|
|||||||
const CORNER_ANCHORS: string[] = ['top-left', 'top-right', 'bottom-left', 'bottom-right'];
|
const CORNER_ANCHORS: string[] = ['top-left', 'top-right', 'bottom-left', 'bottom-right'];
|
||||||
const NO_ANCHORS: string[] = [];
|
const NO_ANCHORS: string[] = [];
|
||||||
|
|
||||||
export const renderBboxPreview = (
|
export const renderBboxPreview = (manager: KonvaNodeManager, bbox: IRect, tool: Tool): void => {
|
||||||
stage: Konva.Stage,
|
manager.preview.bbox.group.listening(tool === 'bbox');
|
||||||
bbox: IRect,
|
|
||||||
tool: Tool,
|
|
||||||
getBbox: () => CanvasV2State['bbox'],
|
|
||||||
onBboxTransformed: (bbox: IRect) => void,
|
|
||||||
getShiftKey: () => boolean,
|
|
||||||
getCtrlKey: () => boolean,
|
|
||||||
getMetaKey: () => boolean,
|
|
||||||
getAltKey: () => boolean
|
|
||||||
): void => {
|
|
||||||
const bboxGroup = getBboxPreviewGroup(
|
|
||||||
stage,
|
|
||||||
getBbox,
|
|
||||||
onBboxTransformed,
|
|
||||||
getShiftKey,
|
|
||||||
getCtrlKey,
|
|
||||||
getMetaKey,
|
|
||||||
getAltKey
|
|
||||||
);
|
|
||||||
const bboxRect = bboxGroup.findOne<Konva.Rect>(`#${PREVIEW_GENERATION_BBOX_DUMMY_RECT}`);
|
|
||||||
const bboxTransformer = bboxGroup.findOne<Konva.Transformer>(`#${PREVIEW_GENERATION_BBOX_TRANSFORMER}`);
|
|
||||||
bboxGroup.listening(tool === 'bbox');
|
|
||||||
// This updates the bbox during transformation
|
// This updates the bbox during transformation
|
||||||
bboxRect?.setAttrs({ ...bbox, scaleX: 1, scaleY: 1, listening: tool === 'bbox' });
|
manager.preview.bbox.rect.setAttrs({ ...bbox, scaleX: 1, scaleY: 1, listening: tool === 'bbox' });
|
||||||
bboxTransformer?.setAttrs({ listening: tool === 'bbox', enabledAnchors: tool === 'bbox' ? ALL_ANCHORS : NO_ANCHORS });
|
manager.preview.bbox.transformer.setAttrs({
|
||||||
|
listening: tool === 'bbox',
|
||||||
|
enabledAnchors: tool === 'bbox' ? ALL_ANCHORS : NO_ANCHORS,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getToolPreviewGroup = (stage: Konva.Stage): Konva.Group => {
|
export const createToolPreview = (stage: Konva.Stage): KonvaNodeManager['preview']['tool'] => {
|
||||||
const previewLayer = getPreviewLayer(stage);
|
|
||||||
let toolPreviewGroup = previewLayer.findOne<Konva.Group>(`#${PREVIEW_TOOL_GROUP_ID}`);
|
|
||||||
if (toolPreviewGroup) {
|
|
||||||
return toolPreviewGroup;
|
|
||||||
}
|
|
||||||
const scale = stage.scaleX();
|
const scale = stage.scaleX();
|
||||||
toolPreviewGroup = new Konva.Group({ id: PREVIEW_TOOL_GROUP_ID });
|
const group = new Konva.Group({ id: PREVIEW_TOOL_GROUP_ID });
|
||||||
|
|
||||||
// Create the brush preview group & circles
|
// Create the brush preview group & circles
|
||||||
const brushPreviewGroup = new Konva.Group({ id: PREVIEW_BRUSH_GROUP_ID });
|
const brushGroup = new Konva.Group({ id: PREVIEW_BRUSH_GROUP_ID });
|
||||||
const brushPreviewFill = new Konva.Circle({
|
const brushFill = new Konva.Circle({
|
||||||
id: PREVIEW_BRUSH_FILL_ID,
|
id: PREVIEW_BRUSH_FILL_ID,
|
||||||
listening: false,
|
listening: false,
|
||||||
strokeEnabled: false,
|
strokeEnabled: false,
|
||||||
});
|
});
|
||||||
brushPreviewGroup.add(brushPreviewFill);
|
brushGroup.add(brushFill);
|
||||||
const brushPreviewBorderInner = new Konva.Circle({
|
const brushBorderInner = new Konva.Circle({
|
||||||
id: PREVIEW_BRUSH_BORDER_INNER_ID,
|
id: PREVIEW_BRUSH_BORDER_INNER_ID,
|
||||||
listening: false,
|
listening: false,
|
||||||
stroke: BRUSH_BORDER_INNER_COLOR,
|
stroke: BRUSH_BORDER_INNER_COLOR,
|
||||||
strokeWidth: BRUSH_ERASER_BORDER_WIDTH / scale,
|
strokeWidth: BRUSH_ERASER_BORDER_WIDTH / scale,
|
||||||
strokeEnabled: true,
|
strokeEnabled: true,
|
||||||
});
|
});
|
||||||
brushPreviewGroup.add(brushPreviewBorderInner);
|
brushGroup.add(brushBorderInner);
|
||||||
const brushPreviewBorderOuter = new Konva.Circle({
|
const brushBorderOuter = new Konva.Circle({
|
||||||
id: PREVIEW_BRUSH_BORDER_OUTER_ID,
|
id: PREVIEW_BRUSH_BORDER_OUTER_ID,
|
||||||
listening: false,
|
listening: false,
|
||||||
stroke: BRUSH_BORDER_OUTER_COLOR,
|
stroke: BRUSH_BORDER_OUTER_COLOR,
|
||||||
strokeWidth: BRUSH_ERASER_BORDER_WIDTH / scale,
|
strokeWidth: BRUSH_ERASER_BORDER_WIDTH / scale,
|
||||||
strokeEnabled: true,
|
strokeEnabled: true,
|
||||||
});
|
});
|
||||||
brushPreviewGroup.add(brushPreviewBorderOuter);
|
brushGroup.add(brushBorderOuter);
|
||||||
|
|
||||||
// Create the rect preview - this is a rectangle drawn from the last mouse down position to the current cursor position
|
// Create the rect preview - this is a rectangle drawn from the last mouse down position to the current cursor position
|
||||||
const rectPreview = new Konva.Rect({
|
const rect = new Konva.Rect({
|
||||||
id: PREVIEW_RECT_ID,
|
id: PREVIEW_RECT_ID,
|
||||||
listening: false,
|
listening: false,
|
||||||
strokeEnabled: false,
|
strokeEnabled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
toolPreviewGroup.add(rectPreview);
|
group.add(rect);
|
||||||
toolPreviewGroup.add(brushPreviewGroup);
|
group.add(brushGroup);
|
||||||
previewLayer.add(toolPreviewGroup);
|
return {
|
||||||
return toolPreviewGroup;
|
group,
|
||||||
|
brush: {
|
||||||
|
group: brushGroup,
|
||||||
|
fill: brushFill,
|
||||||
|
innerBorder: brushBorderInner,
|
||||||
|
outerBorder: brushBorderOuter,
|
||||||
|
},
|
||||||
|
rect: {
|
||||||
|
rect,
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -336,7 +301,7 @@ export const getToolPreviewGroup = (stage: Konva.Stage): Konva.Group => {
|
|||||||
* @param brushSize The brush size
|
* @param brushSize The brush size
|
||||||
*/
|
*/
|
||||||
export const renderToolPreview = (
|
export const renderToolPreview = (
|
||||||
stage: Konva.Stage,
|
manager: KonvaNodeManager,
|
||||||
toolState: CanvasV2State['tool'],
|
toolState: CanvasV2State['tool'],
|
||||||
currentFill: RgbaColor,
|
currentFill: RgbaColor,
|
||||||
selectedEntity: CanvasEntity | null,
|
selectedEntity: CanvasEntity | null,
|
||||||
@ -345,7 +310,8 @@ export const renderToolPreview = (
|
|||||||
isDrawing: boolean,
|
isDrawing: boolean,
|
||||||
isMouseDown: boolean
|
isMouseDown: boolean
|
||||||
): void => {
|
): void => {
|
||||||
const layerCount = stage.find(selectRenderableLayers).length;
|
const stage = manager.stage;
|
||||||
|
const layerCount = manager.adapters.size;
|
||||||
const tool = toolState.selected;
|
const tool = toolState.selected;
|
||||||
// Update the stage's pointer style
|
// Update the stage's pointer style
|
||||||
if (tool === 'view') {
|
if (tool === 'view') {
|
||||||
@ -372,31 +338,22 @@ export const renderToolPreview = (
|
|||||||
|
|
||||||
stage.draggable(tool === 'view');
|
stage.draggable(tool === 'view');
|
||||||
|
|
||||||
const toolPreviewGroup = getToolPreviewGroup(stage);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!cursorPos ||
|
!cursorPos ||
|
||||||
layerCount === 0 ||
|
layerCount === 0 ||
|
||||||
(selectedEntity?.type !== 'regional_guidance' && selectedEntity?.type !== 'layer')
|
(selectedEntity?.type !== 'regional_guidance' && selectedEntity?.type !== 'layer')
|
||||||
) {
|
) {
|
||||||
// We can bail early if the mouse isn't over the stage or there are no layers
|
// We can bail early if the mouse isn't over the stage or there are no layers
|
||||||
toolPreviewGroup.visible(false);
|
manager.preview.tool.group.visible(false);
|
||||||
} else {
|
} else {
|
||||||
toolPreviewGroup.visible(true);
|
manager.preview.tool.group.visible(true);
|
||||||
|
|
||||||
const brushPreviewGroup = stage.findOne<Konva.Group>(`#${PREVIEW_BRUSH_GROUP_ID}`);
|
|
||||||
assert(brushPreviewGroup, 'Brush preview group not found');
|
|
||||||
|
|
||||||
const rectPreview = stage.findOne<Konva.Rect>(`#${PREVIEW_RECT_ID}`);
|
|
||||||
assert(rectPreview, 'Rect preview not found');
|
|
||||||
|
|
||||||
// No need to render the brush preview if the cursor position or color is missing
|
// No need to render the brush preview if the cursor position or color is missing
|
||||||
if (cursorPos && (tool === 'brush' || tool === 'eraser')) {
|
if (cursorPos && (tool === 'brush' || tool === 'eraser')) {
|
||||||
const scale = stage.scaleX();
|
const scale = stage.scaleX();
|
||||||
// Update the fill circle
|
// Update the fill circle
|
||||||
const brushPreviewFill = brushPreviewGroup.findOne<Konva.Circle>(`#${PREVIEW_BRUSH_FILL_ID}`);
|
|
||||||
const radius = (tool === 'brush' ? toolState.brush.width : toolState.eraser.width) / 2;
|
const radius = (tool === 'brush' ? toolState.brush.width : toolState.eraser.width) / 2;
|
||||||
brushPreviewFill?.setAttrs({
|
manager.preview.tool.brush.fill.setAttrs({
|
||||||
x: cursorPos.x,
|
x: cursorPos.x,
|
||||||
y: cursorPos.y,
|
y: cursorPos.y,
|
||||||
radius,
|
radius,
|
||||||
@ -405,83 +362,74 @@ export const renderToolPreview = (
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Update the inner border of the brush preview
|
// Update the inner border of the brush preview
|
||||||
const brushPreviewInner = brushPreviewGroup.findOne<Konva.Circle>(`#${PREVIEW_BRUSH_BORDER_INNER_ID}`);
|
manager.preview.tool.brush.innerBorder.setAttrs({ x: cursorPos.x, y: cursorPos.y, radius });
|
||||||
brushPreviewInner?.setAttrs({ x: cursorPos.x, y: cursorPos.y, radius });
|
|
||||||
|
|
||||||
// Update the outer border of the brush preview
|
// Update the outer border of the brush preview
|
||||||
const brushPreviewOuter = brushPreviewGroup.findOne<Konva.Circle>(`#${PREVIEW_BRUSH_BORDER_OUTER_ID}`);
|
manager.preview.tool.brush.outerBorder.setAttrs({
|
||||||
brushPreviewOuter?.setAttrs({
|
|
||||||
x: cursorPos.x,
|
x: cursorPos.x,
|
||||||
y: cursorPos.y,
|
y: cursorPos.y,
|
||||||
radius: radius + BRUSH_ERASER_BORDER_WIDTH / scale,
|
radius: radius + BRUSH_ERASER_BORDER_WIDTH / scale,
|
||||||
});
|
});
|
||||||
|
|
||||||
scaleToolPreview(stage, toolState);
|
scaleToolPreview(manager, toolState);
|
||||||
|
|
||||||
brushPreviewGroup.visible(true);
|
manager.preview.tool.brush.group.visible(true);
|
||||||
} else {
|
} else {
|
||||||
brushPreviewGroup.visible(false);
|
manager.preview.tool.brush.group.visible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursorPos && lastMouseDownPos && tool === 'rect') {
|
if (cursorPos && lastMouseDownPos && tool === 'rect') {
|
||||||
const rectPreview = toolPreviewGroup.findOne<Konva.Rect>(`#${PREVIEW_RECT_ID}`);
|
manager.preview.tool.rect.rect.setAttrs({
|
||||||
rectPreview?.setAttrs({
|
|
||||||
x: Math.min(cursorPos.x, lastMouseDownPos.x),
|
x: Math.min(cursorPos.x, lastMouseDownPos.x),
|
||||||
y: Math.min(cursorPos.y, lastMouseDownPos.y),
|
y: Math.min(cursorPos.y, lastMouseDownPos.y),
|
||||||
width: Math.abs(cursorPos.x - lastMouseDownPos.x),
|
width: Math.abs(cursorPos.x - lastMouseDownPos.x),
|
||||||
height: Math.abs(cursorPos.y - lastMouseDownPos.y),
|
height: Math.abs(cursorPos.y - lastMouseDownPos.y),
|
||||||
fill: rgbaColorToString(currentFill),
|
fill: rgbaColorToString(currentFill),
|
||||||
|
visible: true,
|
||||||
});
|
});
|
||||||
rectPreview?.visible(true);
|
|
||||||
} else {
|
} else {
|
||||||
rectPreview?.visible(false);
|
manager.preview.tool.rect.rect.visible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const scaleToolPreview = (stage: Konva.Stage, toolState: CanvasV2State['tool']): void => {
|
export const scaleToolPreview = (manager: KonvaNodeManager, toolState: CanvasV2State['tool']): void => {
|
||||||
const scale = stage.scaleX();
|
const scale = manager.stage.scaleX();
|
||||||
const radius = (toolState.selected === 'brush' ? toolState.brush.width : toolState.eraser.width) / 2;
|
const radius = (toolState.selected === 'brush' ? toolState.brush.width : toolState.eraser.width) / 2;
|
||||||
const brushPreviewGroup = stage.findOne<Konva.Group>(`#${PREVIEW_BRUSH_GROUP_ID}`);
|
manager.preview.tool.brush.innerBorder.strokeWidth(BRUSH_ERASER_BORDER_WIDTH / scale);
|
||||||
brushPreviewGroup
|
manager.preview.tool.brush.outerBorder.setAttrs({
|
||||||
?.findOne<Konva.Circle>(`#${PREVIEW_BRUSH_BORDER_INNER_ID}`)
|
strokeWidth: BRUSH_ERASER_BORDER_WIDTH / scale,
|
||||||
?.strokeWidth(BRUSH_ERASER_BORDER_WIDTH / scale);
|
radius: radius + BRUSH_ERASER_BORDER_WIDTH / scale,
|
||||||
brushPreviewGroup
|
});
|
||||||
?.findOne<Konva.Circle>(`#${PREVIEW_BRUSH_BORDER_OUTER_ID}`)
|
|
||||||
?.setAttrs({ strokeWidth: BRUSH_ERASER_BORDER_WIDTH / scale, radius: radius + BRUSH_ERASER_BORDER_WIDTH / scale });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getDocumentOverlayGroup = (stage: Konva.Stage): Konva.Group => {
|
export const createDocumentOverlay = (): KonvaNodeManager['preview']['documentOverlay'] => {
|
||||||
const previewLayer = getPreviewLayer(stage);
|
const group = new Konva.Group({ id: 'document_overlay_group', listening: false });
|
||||||
let documentOverlayGroup = previewLayer.findOne<Konva.Group>('#document_overlay_group');
|
const outerRect = new Konva.Rect({
|
||||||
if (documentOverlayGroup) {
|
|
||||||
return documentOverlayGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
documentOverlayGroup = new Konva.Group({ id: 'document_overlay_group', listening: false });
|
|
||||||
const documentOverlayOuterRect = new Konva.Rect({
|
|
||||||
id: 'document_overlay_outer_rect',
|
id: 'document_overlay_outer_rect',
|
||||||
listening: false,
|
listening: false,
|
||||||
fill: getArbitraryBaseColor(10),
|
fill: getArbitraryBaseColor(10),
|
||||||
opacity: 0.7,
|
opacity: 0.7,
|
||||||
});
|
});
|
||||||
const documentOverlayInnerRect = new Konva.Rect({
|
const innerRect = new Konva.Rect({
|
||||||
id: 'document_overlay_inner_rect',
|
id: 'document_overlay_inner_rect',
|
||||||
listening: false,
|
listening: false,
|
||||||
fill: 'white',
|
fill: 'white',
|
||||||
globalCompositeOperation: 'destination-out',
|
globalCompositeOperation: 'destination-out',
|
||||||
});
|
});
|
||||||
documentOverlayGroup.add(documentOverlayOuterRect);
|
group.add(outerRect);
|
||||||
documentOverlayGroup.add(documentOverlayInnerRect);
|
group.add(innerRect);
|
||||||
previewLayer.add(documentOverlayGroup);
|
return { group, innerRect, outerRect };
|
||||||
return documentOverlayGroup;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const renderDocumentBoundsOverlay = (stage: Konva.Stage, getDocument: () => CanvasV2State['document']): void => {
|
export const renderDocumentBoundsOverlay = (
|
||||||
|
manager: KonvaNodeManager,
|
||||||
|
getDocument: () => CanvasV2State['document']
|
||||||
|
): void => {
|
||||||
const document = getDocument();
|
const document = getDocument();
|
||||||
const documentOverlayGroup = getDocumentOverlayGroup(stage);
|
const stage = manager.stage;
|
||||||
|
|
||||||
documentOverlayGroup.zIndex(0);
|
manager.preview.documentOverlay.group.zIndex(0);
|
||||||
|
|
||||||
const x = stage.x();
|
const x = stage.x();
|
||||||
const y = stage.y();
|
const y = stage.y();
|
||||||
@ -489,14 +437,14 @@ export const renderDocumentBoundsOverlay = (stage: Konva.Stage, getDocument: ()
|
|||||||
const height = stage.height();
|
const height = stage.height();
|
||||||
const scale = stage.scaleX();
|
const scale = stage.scaleX();
|
||||||
|
|
||||||
documentOverlayGroup.findOne<Konva.Rect>('#document_overlay_outer_rect')?.setAttrs({
|
manager.preview.documentOverlay.outerRect.setAttrs({
|
||||||
offsetX: x / scale,
|
offsetX: x / scale,
|
||||||
offsetY: y / scale,
|
offsetY: y / scale,
|
||||||
width: width / scale,
|
width: width / scale,
|
||||||
height: height / scale,
|
height: height / scale,
|
||||||
});
|
});
|
||||||
|
|
||||||
documentOverlayGroup.findOne<Konva.Rect>('#document_overlay_inner_rect')?.setAttrs({
|
manager.preview.documentOverlay.innerRect.setAttrs({
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: document.width,
|
width: document.width,
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
RG_LAYER_OBJECT_GROUP_NAME,
|
RG_LAYER_OBJECT_GROUP_NAME,
|
||||||
RG_LAYER_RECT_SHAPE_NAME,
|
RG_LAYER_RECT_SHAPE_NAME,
|
||||||
} from 'features/controlLayers/konva/naming';
|
} from 'features/controlLayers/konva/naming';
|
||||||
import type { EntityKonvaAdapter, KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
import type { KonvaEntityAdapter, KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
||||||
import { getLayerBboxFast } from 'features/controlLayers/konva/renderers/bbox';
|
import { getLayerBboxFast } from 'features/controlLayers/konva/renderers/bbox';
|
||||||
import {
|
import {
|
||||||
createObjectGroup,
|
createObjectGroup,
|
||||||
@ -52,7 +52,7 @@ const getRegion = (
|
|||||||
manager: KonvaNodeManager,
|
manager: KonvaNodeManager,
|
||||||
entity: RegionEntity,
|
entity: RegionEntity,
|
||||||
onPosChanged?: (arg: PosChangedArg, entityType: CanvasEntity['type']) => void
|
onPosChanged?: (arg: PosChangedArg, entityType: CanvasEntity['type']) => void
|
||||||
): EntityKonvaAdapter => {
|
): KonvaEntityAdapter => {
|
||||||
const adapter = manager.get(entity.id);
|
const adapter = manager.get(entity.id);
|
||||||
if (adapter) {
|
if (adapter) {
|
||||||
return adapter;
|
return adapter;
|
||||||
@ -74,7 +74,7 @@ const getRegion = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const konvaObjectGroup = createObjectGroup(konvaLayer, RG_LAYER_OBJECT_GROUP_NAME);
|
const konvaObjectGroup = createObjectGroup(konvaLayer, RG_LAYER_OBJECT_GROUP_NAME);
|
||||||
return manager.add(entity.id, konvaLayer, konvaObjectGroup);
|
return manager.add(entity, konvaLayer, konvaObjectGroup);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -242,7 +242,7 @@ export const renderRegions = (
|
|||||||
onPosChanged?: (arg: PosChangedArg, entityType: CanvasEntity['type']) => void
|
onPosChanged?: (arg: PosChangedArg, entityType: CanvasEntity['type']) => void
|
||||||
): void => {
|
): void => {
|
||||||
// Destroy nonexistent layers
|
// Destroy nonexistent layers
|
||||||
for (const adapter of manager.getAll()) {
|
for (const adapter of manager.getAll('regional_guidance')) {
|
||||||
if (!entities.find((rg) => rg.id === adapter.id)) {
|
if (!entities.find((rg) => rg.id === adapter.id)) {
|
||||||
manager.destroy(adapter.id);
|
manager.destroy(adapter.id);
|
||||||
}
|
}
|
||||||
|
@ -248,8 +248,10 @@ export const initializeRenderer = (
|
|||||||
spaceKey = val;
|
spaceKey = val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const manager = new KonvaNodeManager(stage, getBbox, onBboxTransformed, $shift.get, $ctrl.get, $meta.get, $alt.get);
|
||||||
|
|
||||||
const cleanupListeners = setStageEventHandlers({
|
const cleanupListeners = setStageEventHandlers({
|
||||||
stage,
|
manager,
|
||||||
getToolState,
|
getToolState,
|
||||||
setTool,
|
setTool,
|
||||||
setToolBuffer,
|
setToolBuffer,
|
||||||
@ -284,10 +286,6 @@ export const initializeRenderer = (
|
|||||||
// the entire state over when needed.
|
// the entire state over when needed.
|
||||||
const debouncedUpdateBboxes = debounce(updateBboxes, 300);
|
const debouncedUpdateBboxes = debounce(updateBboxes, 300);
|
||||||
|
|
||||||
const regionMap = new KonvaNodeManager(stage);
|
|
||||||
const layerMap = new KonvaNodeManager(stage);
|
|
||||||
const controlAdapterMap = new KonvaNodeManager(stage);
|
|
||||||
|
|
||||||
const renderCanvas = () => {
|
const renderCanvas = () => {
|
||||||
const { canvasV2 } = store.getState();
|
const { canvasV2 } = store.getState();
|
||||||
|
|
||||||
@ -305,7 +303,7 @@ export const initializeRenderer = (
|
|||||||
canvasV2.tool.selected !== prevCanvasV2.tool.selected
|
canvasV2.tool.selected !== prevCanvasV2.tool.selected
|
||||||
) {
|
) {
|
||||||
logIfDebugging('Rendering layers');
|
logIfDebugging('Rendering layers');
|
||||||
renderLayers(layerMap, canvasV2.layers, canvasV2.tool.selected, onPosChanged);
|
renderLayers(manager, canvasV2.layers, canvasV2.tool.selected, onPosChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -316,7 +314,7 @@ export const initializeRenderer = (
|
|||||||
) {
|
) {
|
||||||
logIfDebugging('Rendering regions');
|
logIfDebugging('Rendering regions');
|
||||||
renderRegions(
|
renderRegions(
|
||||||
regionMap,
|
manager,
|
||||||
canvasV2.regions,
|
canvasV2.regions,
|
||||||
canvasV2.settings.maskOpacity,
|
canvasV2.settings.maskOpacity,
|
||||||
canvasV2.tool.selected,
|
canvasV2.tool.selected,
|
||||||
@ -327,27 +325,17 @@ export const initializeRenderer = (
|
|||||||
|
|
||||||
if (isFirstRender || canvasV2.controlAdapters !== prevCanvasV2.controlAdapters) {
|
if (isFirstRender || canvasV2.controlAdapters !== prevCanvasV2.controlAdapters) {
|
||||||
logIfDebugging('Rendering control adapters');
|
logIfDebugging('Rendering control adapters');
|
||||||
renderControlAdapters(controlAdapterMap, canvasV2.controlAdapters);
|
renderControlAdapters(manager, canvasV2.controlAdapters);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFirstRender || canvasV2.document !== prevCanvasV2.document) {
|
if (isFirstRender || canvasV2.document !== prevCanvasV2.document) {
|
||||||
logIfDebugging('Rendering document bounds overlay');
|
logIfDebugging('Rendering document bounds overlay');
|
||||||
renderDocumentBoundsOverlay(stage, getDocument);
|
renderDocumentBoundsOverlay(manager, getDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFirstRender || canvasV2.bbox !== prevCanvasV2.bbox || canvasV2.tool.selected !== prevCanvasV2.tool.selected) {
|
if (isFirstRender || canvasV2.bbox !== prevCanvasV2.bbox || canvasV2.tool.selected !== prevCanvasV2.tool.selected) {
|
||||||
logIfDebugging('Rendering generation bbox');
|
logIfDebugging('Rendering generation bbox');
|
||||||
renderBboxPreview(
|
renderBboxPreview(manager, canvasV2.bbox, canvasV2.tool.selected);
|
||||||
stage,
|
|
||||||
canvasV2.bbox,
|
|
||||||
canvasV2.tool.selected,
|
|
||||||
getBbox,
|
|
||||||
onBboxTransformed,
|
|
||||||
$shift.get,
|
|
||||||
$ctrl.get,
|
|
||||||
$meta.get,
|
|
||||||
$alt.get
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -357,7 +345,7 @@ export const initializeRenderer = (
|
|||||||
canvasV2.regions !== prevCanvasV2.regions
|
canvasV2.regions !== prevCanvasV2.regions
|
||||||
) {
|
) {
|
||||||
logIfDebugging('Updating entity bboxes');
|
logIfDebugging('Updating entity bboxes');
|
||||||
debouncedUpdateBboxes(stage, canvasV2.layers, canvasV2.controlAdapters, canvasV2.regions, onBboxChanged);
|
// debouncedUpdateBboxes(stage, canvasV2.layers, canvasV2.controlAdapters, canvasV2.regions, onBboxChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -367,15 +355,7 @@ export const initializeRenderer = (
|
|||||||
canvasV2.regions !== prevCanvasV2.regions
|
canvasV2.regions !== prevCanvasV2.regions
|
||||||
) {
|
) {
|
||||||
logIfDebugging('Arranging entities');
|
logIfDebugging('Arranging entities');
|
||||||
arrangeEntities(
|
arrangeEntities(manager, canvasV2.layers, canvasV2.controlAdapters, canvasV2.regions);
|
||||||
stage,
|
|
||||||
layerMap,
|
|
||||||
canvasV2.layers,
|
|
||||||
controlAdapterMap,
|
|
||||||
canvasV2.controlAdapters,
|
|
||||||
regionMap,
|
|
||||||
canvasV2.regions
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prevCanvasV2 = canvasV2;
|
prevCanvasV2 = canvasV2;
|
||||||
@ -399,8 +379,8 @@ export const initializeRenderer = (
|
|||||||
height: stage.height(),
|
height: stage.height(),
|
||||||
scale: stage.scaleX(),
|
scale: stage.scaleX(),
|
||||||
});
|
});
|
||||||
renderBackgroundLayer(stage);
|
renderBackgroundLayer(manager);
|
||||||
renderDocumentBoundsOverlay(stage, getDocument);
|
renderDocumentBoundsOverlay(manager, getDocument);
|
||||||
};
|
};
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver(fitStageToContainer);
|
const resizeObserver = new ResizeObserver(fitStageToContainer);
|
||||||
@ -414,7 +394,7 @@ export const initializeRenderer = (
|
|||||||
const stageAttrs = fitDocumentToStage(stage, prevCanvasV2.document);
|
const stageAttrs = fitDocumentToStage(stage, prevCanvasV2.document);
|
||||||
// The HUD displays some of the stage attributes, so we need to update it here.
|
// The HUD displays some of the stage attributes, so we need to update it here.
|
||||||
$stageAttrs.set(stageAttrs);
|
$stageAttrs.set(stageAttrs);
|
||||||
scaleToolPreview(stage, getToolState());
|
scaleToolPreview(manager, getToolState());
|
||||||
renderCanvas();
|
renderCanvas();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user