refboard: fix cropped image offset transforms

This commit is contained in:
Hiren Kangad
2026-03-13 12:36:57 +05:30
parent 4dc338cdb6
commit 18c968b54f
+12 -10
View File
@@ -44,14 +44,16 @@ export function normalizeImageTransformData(data: ImageObject): void {
* Images render from a top-left local origin, so flip uses a compensating position * Images render from a top-left local origin, so flip uses a compensating position
* shift to keep the visible unrotated bounds anchored at data.x/data.y. * shift to keep the visible unrotated bounds anchored at data.x/data.y.
*/ */
export function getImageDisplayTransform(data: Pick<ImageObject, 'x' | 'y' | 'w' | 'h' | 'sx' | 'sy' | 'angle' | 'flipX' | 'flipY'>): ImageDisplayTransform { export function getImageDisplayTransform(data: Pick<ImageObject, 'x' | 'y' | 'w' | 'h' | 'sx' | 'sy' | 'angle' | 'flipX' | 'flipY' | 'crop'>): ImageDisplayTransform {
const sx = Math.abs(data.sx); const sx = Math.abs(data.sx);
const sy = Math.abs(data.sy); const sy = Math.abs(data.sy);
const visibleW = data.crop ? data.crop.w * data.w : data.w;
const visibleH = data.crop ? data.crop.h * data.h : data.h;
const scaleX = sx * (data.flipX ? -1 : 1); const scaleX = sx * (data.flipX ? -1 : 1);
const scaleY = sy * (data.flipY ? -1 : 1); const scaleY = sy * (data.flipY ? -1 : 1);
return { return {
x: data.x + (data.flipX ? data.w * sx : 0), x: data.x + (data.flipX ? visibleW * sx : 0),
y: data.y + (data.flipY ? data.h * sy : 0), y: data.y + (data.flipY ? visibleH * sy : 0),
scaleX, scaleX,
scaleY, scaleY,
angle: data.angle, angle: data.angle,
@@ -64,21 +66,21 @@ function getVisibleLocalRect(data: Pick<ImageObject, 'w' | 'h' | 'crop'>): { x:
return { x: 0, y: 0, w: data.w, h: data.h }; return { x: 0, y: 0, w: data.w, h: data.h };
} }
return { return {
x: crop.x * data.w, x: 0,
y: crop.y * data.h, y: 0,
w: crop.w * data.w, w: crop.w * data.w,
h: crop.h * data.h, h: crop.h * data.h,
}; };
} }
export function applyImageDisplayTransform(displayObject: Container, data: Pick<ImageObject, 'x' | 'y' | 'w' | 'h' | 'sx' | 'sy' | 'angle' | 'flipX' | 'flipY'>): void { export function applyImageDisplayTransform(displayObject: Container, data: Pick<ImageObject, 'x' | 'y' | 'w' | 'h' | 'sx' | 'sy' | 'angle' | 'flipX' | 'flipY' | 'crop'>): void {
const t = getImageDisplayTransform(data); const t = getImageDisplayTransform(data);
displayObject.position.set(t.x, t.y); displayObject.position.set(t.x, t.y);
displayObject.scale.set(t.scaleX, t.scaleY); displayObject.scale.set(t.scaleX, t.scaleY);
displayObject.angle = t.angle; displayObject.angle = t.angle;
} }
function transformLocalPoint(data: Pick<ImageObject, 'x' | 'y' | 'w' | 'h' | 'sx' | 'sy' | 'angle' | 'flipX' | 'flipY'>, localX: number, localY: number): Point2D { function transformLocalPoint(data: Pick<ImageObject, 'x' | 'y' | 'w' | 'h' | 'sx' | 'sy' | 'angle' | 'flipX' | 'flipY' | 'crop'>, localX: number, localY: number): Point2D {
const t = getImageDisplayTransform(data); const t = getImageDisplayTransform(data);
return transformPoint({ x: localX, y: localY }, { return transformPoint({ x: localX, y: localY }, {
x: t.x, x: t.x,
@@ -172,7 +174,7 @@ function getImageViewNormalizedFromLocal(
} }
export function imageViewPointToWorld( export function imageViewPointToWorld(
data: Pick<ImageObject, 'x' | 'y' | 'w' | 'h' | 'sx' | 'sy' | 'angle' | 'flipX' | 'flipY'>, data: Pick<ImageObject, 'x' | 'y' | 'w' | 'h' | 'sx' | 'sy' | 'angle' | 'flipX' | 'flipY' | 'crop'>,
viewX: number, viewX: number,
viewY: number, viewY: number,
): Point2D { ): Point2D {
@@ -181,7 +183,7 @@ export function imageViewPointToWorld(
} }
export function worldToImageViewPoint( export function worldToImageViewPoint(
data: Pick<ImageObject, 'x' | 'y' | 'w' | 'h' | 'sx' | 'sy' | 'angle' | 'flipX' | 'flipY'>, data: Pick<ImageObject, 'x' | 'y' | 'w' | 'h' | 'sx' | 'sy' | 'angle' | 'flipX' | 'flipY' | 'crop'>,
worldX: number, worldX: number,
worldY: number, worldY: number,
): Point2D { ): Point2D {
@@ -197,7 +199,7 @@ export function worldToImageViewPoint(
} }
export function getImageViewRectWorldCorners( export function getImageViewRectWorldCorners(
data: Pick<ImageObject, 'x' | 'y' | 'w' | 'h' | 'sx' | 'sy' | 'angle' | 'flipX' | 'flipY'>, data: Pick<ImageObject, 'x' | 'y' | 'w' | 'h' | 'sx' | 'sy' | 'angle' | 'flipX' | 'flipY' | 'crop'>,
rect: CropRect, rect: CropRect,
): Point2D[] { ): Point2D[] {
return [ return [