feat(ui): reset view fits all visible objects

This commit is contained in:
psychedelicious 2024-08-19 15:42:12 +10:00
parent 8364fa74cf
commit 7a6e8de60f
3 changed files with 57 additions and 3 deletions

View File

@ -28,9 +28,9 @@ export const CanvasResetViewButton = memo(() => {
const onReset = useCallback(() => {
if ($shift.get()) {
resetZoom();
} else {
resetView();
} else {
resetZoom();
}
}, [resetView, resetZoom]);

View File

@ -6,6 +6,7 @@ import { MAX_CANVAS_SCALE, MIN_CANVAS_SCALE } from 'features/controlLayers/konva
import {
getImageDataTransparency,
getPrefixedId,
getRectUnion,
konvaNodeToBlob,
konvaNodeToImageData,
nanoid,
@ -179,9 +180,44 @@ export class CanvasManager {
});
}
getVisibleRect = (): Rect => {
const rects = [];
if (this.inpaintMaskAdapter.state.isEnabled) {
rects.push(this.inpaintMaskAdapter.transformer.getRelativeRect());
}
for (const adapter of this.rasterLayerAdapters.values()) {
if (adapter.state.isEnabled) {
rects.push(adapter.transformer.getRelativeRect());
}
}
for (const adapter of this.controlLayerAdapters.values()) {
if (adapter.state.isEnabled) {
rects.push(adapter.transformer.getRelativeRect());
}
}
for (const adapter of this.regionalGuidanceAdapters.values()) {
if (adapter.state.isEnabled) {
rects.push(adapter.transformer.getRelativeRect());
}
}
const rectUnion = getRectUnion(...rects);
if (rectUnion.width === 0 || rectUnion.height === 0) {
// fall back to the bbox if there is no content
return this.stateApi.getBbox().rect;
} else {
return rectUnion;
}
};
resetView() {
const { width, height } = this.getStageSize();
const { rect } = this.stateApi.getBbox();
const rect = this.getVisibleRect();
const padding = 20; // Padding in absolute pixels

View File

@ -374,6 +374,7 @@ export function getObjectId(type: CanvasObjectState['type'], isBuffer?: boolean)
export const getEmptyRect = (): Rect => {
return { x: 0, y: 0, width: 0, height: 0 };
};
export function snapToNearest(value: number, candidateValues: number[], threshold: number): number {
let closest = value;
let minDiff = Number.MAX_VALUE;
@ -388,3 +389,20 @@ export function snapToNearest(value: number, candidateValues: number[], threshol
return closest;
}
/**
* Gets the union of two rects
* @param rect1 The first rect
* @param rect2 The second rect
* @returns The union of the two rects
*/
export const getRectUnion = (...rects: Rect[]): Rect => {
const rect = rects.reduce<Rect>((acc, r) => {
const x = Math.min(acc.x, r.x);
const y = Math.min(acc.y, r.y);
const width = Math.max(acc.x + acc.width, r.x + r.width) - x;
const height = Math.max(acc.y + acc.height, r.y + r.height) - y;
return { x, y, width, height };
}, getEmptyRect());
return rect;
};