import type { PPTElement } from '@openmaic/dsl'; /** * Percentage-based geometry (0-100 coordinate system) * Used by spotlight/laser overlays for responsive positioning. */ export interface PercentageGeometry { x: number; y: number; w: number; h: number; centerX: number; centerY: number; } export function getElementPercentageGeometry( element: PPTElement, viewportSize: number = 1000, viewportRatio: number = 0.5625, ): PercentageGeometry | null { if ( !('left' in element) || !('top' in element) || !('width' in element) || !('height' in element) ) { return null; } const { left, top, width, height } = element; const x = (left / viewportSize) * 100; const y = (top / (viewportSize * viewportRatio)) * 100; const w = (width / viewportSize) * 100; const h = (height / (viewportSize * viewportRatio)) * 100; const centerX = x + w / 2; const centerY = y + h / 2; return { x, y, w, h, centerX, centerY }; } export function findElementGeometry( elements: PPTElement[], elementId: string, viewportSize: number = 1000, viewportRatio: number = 0.5625, ): PercentageGeometry | null { const element = elements.find((el) => el.id === elementId); if (!element) return null; return getElementPercentageGeometry(element, viewportSize, viewportRatio); } export function findNearestCorner(geometry: PercentageGeometry): { x: number; y: number; } { const { centerX, centerY } = geometry; const corners = [ { x: 0, y: 0 }, { x: 100, y: 0 }, { x: 0, y: 100 }, { x: 100, y: 100 }, ]; 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; }