Skip to content

Commit

Permalink
fix(ui): round rects when applying transform
Browse files Browse the repository at this point in the history
Due to the limited floating point precision, and konva's `scale` properties, it is possible for the relative rect of an object to have non-integer coordinates and dimensions.

When we go to rasterize and otherwise export images, the HTML canvas API truncates these numbers.

So, we can end up with situations where the relative width and height of a layer are very close to the "real" value, but slightly off.

For example, width and height might be 512px, but the relative rect is calculated to be something like 512.000000003 or 511.9999999997.

In the first case, the truncation results in 512x512 for the dimensions - which is correct. But in the second case, it results in 511x511!

One place where this causes issues is the image action `New Canvas from image -> As Raster Layer (resize)`. For certain input image sizes, this results in an incorrectly resized image. For example, a 1496x1946 input image is resized to 511x511 pixels when the bbox is 512x512.

To fix this, we can round both coords and dimensions of rects when rasterizing.

I've thought through the implications and done some testing. I believe this change will not cause any regressions and only fix edge cases. But, it's possible that something was inadvertently relying on the old behavior.
  • Loading branch information
psychedelicious authored and hipsterusername committed Jan 15, 2025
1 parent 66e04ea commit 15d5fd6
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
getKonvaNodeDebugAttrs,
getPrefixedId,
offsetCoord,
roundRect,
} from 'features/controlLayers/konva/util';
import { selectSelectedEntityIdentifier } from 'features/controlLayers/store/selectors';
import type { Coordinate, Rect, RectWithRotation } from 'features/controlLayers/store/types';
Expand Down Expand Up @@ -773,7 +774,7 @@ export class CanvasEntityTransformer extends CanvasModuleBase {
const rect = this.getRelativeRect();
const rasterizeResult = await withResultAsync(() =>
this.parent.renderer.rasterize({
rect,
rect: roundRect(rect),
replaceObjects: true,
ignoreCache: true,
attrs: { opacity: 1, filters: [] },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -740,3 +740,12 @@ export const getColorAtCoordinate = (stage: Konva.Stage, coord: Coordinate): Rgb

return { r, g, b };
};

export const roundRect = (rect: Rect): Rect => {
return {
x: Math.round(rect.x),
y: Math.round(rect.y),
width: Math.round(rect.width),
height: Math.round(rect.height),
};
};

0 comments on commit 15d5fd6

Please sign in to comment.