Skip to content

Commit 6d18a72

Browse files
fix(ui): fit to bbox when bbox is not aligned to 64px grid
1 parent af58a75 commit 6d18a72

File tree

1 file changed

+38
-11
lines changed

1 file changed

+38
-11
lines changed

invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityTransformer.ts

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -482,13 +482,24 @@ export class CanvasEntityTransformer extends CanvasModuleBase {
482482
// "contain" means that the entity should be scaled to fit within the bbox, but it should not exceed the bbox.
483483
const scale = Math.min(scaleX, scaleY);
484484

485-
// Center the shape within the bounding box
486-
const offsetX = (rect.width - width * scale) / 2;
487-
const offsetY = (rect.height - height * scale) / 2;
485+
// Calculate the scaled dimensions
486+
const scaledWidth = width * scale;
487+
const scaledHeight = height * scale;
488+
489+
// Calculate centered position
490+
const centerX = rect.x + (rect.width - scaledWidth) / 2;
491+
const centerY = rect.y + (rect.height - scaledHeight) / 2;
492+
493+
// Round to grid and clamp to valid bounds
494+
const roundedX = gridSize > 1 ? roundToMultiple(centerX, gridSize) : centerX;
495+
const roundedY = gridSize > 1 ? roundToMultiple(centerY, gridSize) : centerY;
496+
497+
const x = clamp(roundedX, rect.x, rect.x + rect.width - scaledWidth);
498+
const y = clamp(roundedY, rect.y, rect.y + rect.height - scaledHeight);
488499

489500
this.konva.proxyRect.setAttrs({
490-
x: clamp(roundToMultiple(rect.x + offsetX, gridSize), rect.x, rect.x + rect.width),
491-
y: clamp(roundToMultiple(rect.y + offsetY, gridSize), rect.y, rect.y + rect.height),
501+
x,
502+
y,
492503
scaleX: scale,
493504
scaleY: scale,
494505
rotation: 0,
@@ -513,16 +524,32 @@ export class CanvasEntityTransformer extends CanvasModuleBase {
513524
const scaleX = rect.width / width;
514525
const scaleY = rect.height / height;
515526

516-
// "cover" is the same as "contain", but we choose the larger scale to cover the shape
527+
// "cover" means the entity should cover the entire bbox, potentially overflowing
517528
const scale = Math.max(scaleX, scaleY);
518529

519-
// Center the shape within the bounding box
520-
const offsetX = (rect.width - width * scale) / 2;
521-
const offsetY = (rect.height - height * scale) / 2;
530+
// Calculate the scaled dimensions
531+
const scaledWidth = width * scale;
532+
const scaledHeight = height * scale;
533+
534+
// Calculate position - center only if entity exceeds bbox
535+
let x = rect.x;
536+
let y = rect.y;
537+
538+
// If scaled width exceeds bbox width, center horizontally
539+
if (scaledWidth > rect.width) {
540+
const centerX = rect.x + (rect.width - scaledWidth) / 2;
541+
x = gridSize > 1 ? roundToMultiple(centerX, gridSize) : centerX;
542+
}
543+
544+
// If scaled height exceeds bbox height, center vertically
545+
if (scaledHeight > rect.height) {
546+
const centerY = rect.y + (rect.height - scaledHeight) / 2;
547+
y = gridSize > 1 ? roundToMultiple(centerY, gridSize) : centerY;
548+
}
522549

523550
this.konva.proxyRect.setAttrs({
524-
x: roundToMultiple(rect.x + offsetX, gridSize),
525-
y: roundToMultiple(rect.y + offsetY, gridSize),
551+
x,
552+
y,
526553
scaleX: scale,
527554
scaleY: scale,
528555
rotation: 0,

0 commit comments

Comments
 (0)