84 lines
1.9 KiB
TypeScript
84 lines
1.9 KiB
TypeScript
export interface Point {
|
|
x: number;
|
|
y: number;
|
|
}
|
|
|
|
export function calculateCenterOffset(
|
|
corner: string,
|
|
deltaWidth: number,
|
|
deltaHeight: number,
|
|
rotation: number,
|
|
): Point {
|
|
const rad = (rotation * Math.PI) / 180;
|
|
const cos = Math.cos(rad);
|
|
const sin = Math.sin(rad);
|
|
|
|
let localDx = 0;
|
|
let localDy = 0;
|
|
|
|
if (corner.includes('w')) localDx = -deltaWidth / 2;
|
|
else if (corner.includes('e')) localDx = deltaWidth / 2;
|
|
|
|
if (corner.includes('n')) localDy = -deltaHeight / 2;
|
|
else if (corner.includes('s')) localDy = deltaHeight / 2;
|
|
|
|
return {
|
|
x: localDx * cos - localDy * sin,
|
|
y: localDx * sin + localDy * cos,
|
|
};
|
|
}
|
|
|
|
export function constrainToAspectRatio(
|
|
newWidth: number,
|
|
newHeight: number,
|
|
aspectRatio: number,
|
|
): { width: number; height: number } {
|
|
const newRatio = newWidth / newHeight;
|
|
|
|
if (newRatio > aspectRatio) {
|
|
return { width: newHeight * aspectRatio, height: newHeight };
|
|
} else {
|
|
return { width: newWidth, height: newWidth / aspectRatio };
|
|
}
|
|
}
|
|
|
|
export function detectRotationCorner(
|
|
localX: number,
|
|
localY: number,
|
|
halfWidth: number,
|
|
halfHeight: number,
|
|
zoneRadius: number,
|
|
): string | null {
|
|
const corners: Record<string, Point> = {
|
|
nw: { x: -halfWidth, y: -halfHeight },
|
|
ne: { x: halfWidth, y: -halfHeight },
|
|
sw: { x: -halfWidth, y: halfHeight },
|
|
se: { x: halfWidth, y: halfHeight },
|
|
};
|
|
|
|
const isInsideBounds =
|
|
localX >= -halfWidth &&
|
|
localX <= halfWidth &&
|
|
localY >= -halfHeight &&
|
|
localY <= halfHeight;
|
|
|
|
if (isInsideBounds) return null;
|
|
|
|
for (const [name, corner] of Object.entries(corners)) {
|
|
const dx = localX - corner.x;
|
|
const dy = localY - corner.y;
|
|
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
|
|
if (dist > zoneRadius || dist < 3) continue;
|
|
|
|
const isOutwardX =
|
|
(name.includes('w') && dx < 0) || (name.includes('e') && dx > 0);
|
|
const isOutwardY =
|
|
(name.includes('n') && dy < 0) || (name.includes('s') && dy > 0);
|
|
|
|
if (isOutwardX || isOutwardY) return name;
|
|
}
|
|
|
|
return null;
|
|
}
|