Skip to content

Commit 533f757

Browse files
committed
Addedd 2 functions to maintain crop area and check for OOB
1 parent e9c6878 commit 533f757

1 file changed

Lines changed: 49 additions & 0 deletions

File tree

src/utils/cropUtils.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,55 @@ export function calculateCenteredCrop(
4040
};
4141
}
4242

43+
function isCropWithinBounds(crop: Crop, imageW: number, imageH: number, rotation: number): boolean {
44+
const cx = imageW / 2;
45+
const cy = imageH / 2;
46+
const rad = (-rotation * Math.PI) / 180;
47+
const cos = Math.cos(rad);
48+
const sin = Math.sin(rad);
49+
const pts = [
50+
{ x: crop.x, y: crop.y },
51+
{ x: crop.x + crop.width, y: crop.y },
52+
{ x: crop.x, y: crop.y + crop.height },
53+
{ x: crop.x + crop.width, y: crop.y + crop.height },
54+
];
55+
for (let i = 0; i < 4; i++) {
56+
const nx = cos * (pts[i].x - cx) - sin * (pts[i].y - cy) + cx;
57+
const ny = sin * (pts[i].x - cx) + cos * (pts[i].y - cy) + cy;
58+
if (nx < -1 || nx > imageW + 1 || ny < -1 || ny > imageH + 1) return false;
59+
}
60+
return true;
61+
}
62+
63+
export function calculateAreaPreservingCrop(
64+
imageWidth: number,
65+
imageHeight: number,
66+
orientationSteps: number,
67+
aspectRatio: number | null,
68+
rotation: number,
69+
currentCrop: Crop | null | undefined,
70+
): Crop | null {
71+
if (!aspectRatio || aspectRatio <= 0 || !currentCrop || !currentCrop.width || !currentCrop.height) return null;
72+
73+
const { width: W, height: H } = getOrientedDimensions(imageWidth, imageHeight, orientationSteps);
74+
75+
const area = currentCrop.width * currentCrop.height;
76+
const newH = Math.sqrt(area / aspectRatio);
77+
const newW = aspectRatio * newH;
78+
const centerX = currentCrop.x + currentCrop.width / 2;
79+
const centerY = currentCrop.y + currentCrop.height / 2;
80+
81+
const candidate: Crop = {
82+
unit: 'px',
83+
x: Math.round(centerX - newW / 2),
84+
y: Math.round(centerY - newH / 2),
85+
width: Math.round(newW),
86+
height: Math.round(newH),
87+
};
88+
89+
return isCropWithinBounds(candidate, W, H, rotation) ? candidate : null;
90+
}
91+
4392
export function rotateCropCenter(
4493
crop: Crop,
4594
orientedWidth: number,

0 commit comments

Comments
 (0)