NitishStark's picture
Upload folder using huggingface_hub
c20f20c verified
import type { PPTElement } from '@/lib/types/slides';
import type { PercentageGeometry } from '@/lib/types/action';
/**
* Calculate percentage coordinates (0-100) for an element
*
* @param element - PPT element
* @param viewportSize - Viewport width base, default 1000px
* @returns Percentage geometry info, or null if the element has no position info
*/
export function getElementPercentageGeometry(
element: PPTElement,
viewportSize: number = 1000,
): PercentageGeometry | null {
// Only positioned elements have left/top/width/height
if (
!('left' in element) ||
!('top' in element) ||
!('width' in element) ||
!('height' in element)
) {
return null;
}
const { left, top, width, height } = element;
// Calculate percentage coordinates (relative to viewportSize)
const x = (left / viewportSize) * 100;
const y = (top / (viewportSize * 0.5625)) * 100; // 16:9 ratio
const w = (width / viewportSize) * 100;
const h = (height / (viewportSize * 0.5625)) * 100;
// Calculate center point
const centerX = x + w / 2;
const centerY = y + h / 2;
return {
x,
y,
w,
h,
centerX,
centerY,
};
}
/**
* Find percentage geometry info by scene and element ID
*
* @param scene - Scene object
* @param elementId - Element ID
* @param viewportSize - Viewport width base, default 1000px
* @returns Percentage geometry info, or null if element is not found or has no position info
*/
export function findElementGeometry(
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- scene can be old or new format with different shapes
scene: Record<string, any>,
elementId: string,
viewportSize: number = 1000,
): PercentageGeometry | null {
// Support two scene structures:
// 1. scene.elements (old format)
// 2. scene.content.canvas.elements (new format)
let elements: PPTElement[] | undefined;
if (scene.type === 'slide') {
if (scene.elements) {
// Old format
elements = scene.elements;
} else if (scene.content?.canvas?.elements) {
// New format
elements = scene.content.canvas.elements;
}
}
if (!elements) {
return null;
}
const element = elements.find((el: PPTElement) => el.id === elementId);
if (!element) {
return null;
}
return getElementPercentageGeometry(element, viewportSize);
}
/**
* Calculate which corner has the shortest distance to the element center
*
* @param geometry - Percentage geometry info
* @returns Nearest corner coordinates { x: 0-100, y: 0-100 }
*/
export function findNearestCorner(geometry: PercentageGeometry): {
x: number;
y: number;
} {
const { centerX, centerY } = geometry;
// Coordinates of the four corners
const corners = [
{ x: 0, y: 0 }, // Top-left
{ x: 100, y: 0 }, // Top-right
{ x: 0, y: 100 }, // Bottom-left
{ x: 100, y: 100 }, // Bottom-right
];
// Calculate distances and find the nearest corner
let minDistance = Infinity;
let nearestCorner = corners[0];
for (const corner of corners) {
const distance = Math.sqrt(Math.pow(corner.x - centerX, 2) + Math.pow(corner.y - centerY, 2));
if (distance < minDistance) {
minDistance = distance;
nearestCorner = corner;
}
}
return nearestCorner;
}