Files
InvokeAI/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBackground.ts
psychedelicious 2ef8a8cf5a feat(ui): add names to all konva objects
Makes troubleshooting much simpler
2024-08-23 19:46:04 +10:00

119 lines
3.2 KiB
TypeScript

import { getArbitraryBaseColor } from '@invoke-ai/ui-library';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import Konva from 'konva';
const baseGridLineColor = getArbitraryBaseColor(27);
const fineGridLineColor = getArbitraryBaseColor(18);
/**
* Gets the grid spacing. The value depends on the stage scale - at higher scales, the grid spacing is smaller.
* @param scale The stage scale
* @returns The grid spacing based on the stage scale
*/
const getGridSpacing = (scale: number): number => {
if (scale >= 2) {
return 8;
}
if (scale >= 1 && scale < 2) {
return 16;
}
if (scale >= 0.5 && scale < 1) {
return 32;
}
if (scale >= 0.25 && scale < 0.5) {
return 64;
}
if (scale >= 0.125 && scale < 0.25) {
return 128;
}
return 256;
};
export class CanvasBackground {
static BASE_NAME = 'background';
static LAYER_NAME = `${CanvasBackground.BASE_NAME}_layer`;
layer: Konva.Layer;
manager: CanvasManager;
constructor(manager: CanvasManager) {
this.manager = manager;
this.layer = new Konva.Layer({ name: CanvasBackground.LAYER_NAME, listening: false });
}
render() {
this.layer.zIndex(0);
const scale = this.manager.stage.scaleX();
const gridSpacing = getGridSpacing(scale);
const x = this.manager.stage.x();
const y = this.manager.stage.y();
const width = this.manager.stage.width();
const height = this.manager.stage.height();
const stageRect = {
x1: 0,
y1: 0,
x2: width,
y2: height,
};
const gridOffset = {
x: Math.ceil(x / scale / gridSpacing) * gridSpacing,
y: Math.ceil(y / scale / gridSpacing) * gridSpacing,
};
const gridRect = {
x1: -gridOffset.x,
y1: -gridOffset.y,
x2: width / scale - gridOffset.x + gridSpacing,
y2: height / scale - gridOffset.y + gridSpacing,
};
const gridFullRect = {
x1: Math.min(stageRect.x1, gridRect.x1),
y1: Math.min(stageRect.y1, gridRect.y1),
x2: Math.max(stageRect.x2, gridRect.x2),
y2: Math.max(stageRect.y2, gridRect.y2),
};
// find the x & y size of the grid
const xSize = gridFullRect.x2 - gridFullRect.x1;
const ySize = gridFullRect.y2 - gridFullRect.y1;
// compute the number of steps required on each axis.
const xSteps = Math.round(xSize / gridSpacing) + 1;
const ySteps = Math.round(ySize / gridSpacing) + 1;
const strokeWidth = 1 / scale;
let _x = 0;
let _y = 0;
this.layer.destroyChildren();
for (let i = 0; i < xSteps; i++) {
_x = gridFullRect.x1 + i * gridSpacing;
this.layer.add(
new Konva.Line({
x: _x,
y: gridFullRect.y1,
points: [0, 0, 0, ySize],
stroke: _x % 64 ? fineGridLineColor : baseGridLineColor,
strokeWidth,
listening: false,
})
);
}
for (let i = 0; i < ySteps; i++) {
_y = gridFullRect.y1 + i * gridSpacing;
this.layer.add(
new Konva.Line({
x: gridFullRect.x1,
y: _y,
points: [0, 0, xSize, 0],
stroke: _y % 64 ? fineGridLineColor : baseGridLineColor,
strokeWidth,
listening: false,
})
);
}
}
}