import { Position, Size } from "@/types/screen"; import { GridSettings } from "@/types/screen-management"; // ๐ŸŽฏ 10px ๊ณ ์ • ๊ฒฉ์ž ์‹œ์Šคํ…œ const GRID_SIZE = 10; // ๊ณ ์ •๊ฐ’ export interface GridInfo { gridSize: number; // ํ•ญ์ƒ 10px totalWidth: number; totalHeight: number; } /** * ๊ฒฉ์ž ์ •๋ณด ๊ณ„์‚ฐ (๋‹จ์ˆœํ™”) */ export function calculateGridInfo( containerWidth: number, containerHeight: number, _gridSettings?: GridSettings, // ํ˜ธํ™˜์„ฑ ์œ ์ง€์šฉ (์‚ฌ์šฉ ์•ˆ ํ•จ) ): GridInfo { return { gridSize: GRID_SIZE, totalWidth: containerWidth, totalHeight: containerHeight, }; } /** * ์œ„์น˜๋ฅผ 10px ๊ฒฉ์ž์— ๋งž์ถค */ export function snapToGrid(position: Position, _gridInfo: GridInfo, gridSettings: GridSettings): Position { if (!gridSettings.snapToGrid) { return position; } return { x: Math.round(position.x / GRID_SIZE) * GRID_SIZE, y: Math.round(position.y / GRID_SIZE) * GRID_SIZE, z: position.z, }; } /** * ํฌ๊ธฐ๋ฅผ 10px ๊ฒฉ์ž์— ๋งž์ถค */ export function snapSizeToGrid(size: Size, _gridInfo: GridInfo, gridSettings: GridSettings): Size { if (!gridSettings.snapToGrid) { return size; } return { width: Math.max(GRID_SIZE, Math.round(size.width / GRID_SIZE) * GRID_SIZE), height: Math.max(GRID_SIZE, Math.round(size.height / GRID_SIZE) * GRID_SIZE), }; } /** * ๊ฒฉ์ž ๊ฐ€์ด๋“œ๋ผ์ธ ์ƒ์„ฑ (10px ๊ฐ„๊ฒฉ) */ export function generateGridLines( containerWidth: number, containerHeight: number, _gridSettings?: GridSettings, ): { verticalLines: number[]; horizontalLines: number[]; } { const verticalLines: number[] = []; for (let x = 0; x <= containerWidth; x += GRID_SIZE) { verticalLines.push(x); } const horizontalLines: number[] = []; for (let y = 0; y <= containerHeight; y += GRID_SIZE) { horizontalLines.push(y); } return { verticalLines, horizontalLines, }; } /** * ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฒฉ์ž ๊ฒฝ๊ณ„์— ์žˆ๋Š”์ง€ ํ™•์ธ */ export function isOnGridBoundary( position: Position, size: Size, gridInfo: GridInfo, gridSettings: GridSettings, tolerance: number = 5, ): boolean { const snappedPos = snapToGrid(position, gridInfo, gridSettings); const snappedSize = snapSizeToGrid(size, gridInfo, gridSettings); const positionMatch = Math.abs(position.x - snappedPos.x) <= tolerance && Math.abs(position.y - snappedPos.y) <= tolerance; const sizeMatch = Math.abs(size.width - snappedSize.width) <= tolerance && Math.abs(size.height - snappedSize.height) <= tolerance; return positionMatch && sizeMatch; } /** * ๊ทธ๋ฃน ๋‚ด๋ถ€ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๊ฒฉ์ž์— ๋งž๊ฒŒ ์ •๋ ฌ */ export function alignGroupChildrenToGrid( children: any[], groupPosition: Position, gridInfo: GridInfo, gridSettings: GridSettings, ): any[] { if (!gridSettings.snapToGrid || children.length === 0) return children; return children.map((child) => { const padding = 16; // 10px ๋‹จ์œ„๋กœ ์Šค๋ƒ… const snappedX = Math.max(padding, Math.round((child.position.x - padding) / GRID_SIZE) * GRID_SIZE + padding); const snappedY = Math.max(padding, Math.round((child.position.y - padding) / GRID_SIZE) * GRID_SIZE + padding); const snappedWidth = Math.max(GRID_SIZE, Math.round(child.size.width / GRID_SIZE) * GRID_SIZE); const snappedHeight = Math.max(GRID_SIZE, Math.round(child.size.height / GRID_SIZE) * GRID_SIZE); return { ...child, position: { x: snappedX, y: snappedY, z: child.position.z || 1, }, size: { width: snappedWidth, height: snappedHeight, }, }; }); } /** * ๊ทธ๋ฃน ์ƒ์„ฑ ์‹œ ์ตœ์ ํ™”๋œ ๊ทธ๋ฃน ํฌ๊ธฐ ๊ณ„์‚ฐ */ export function calculateOptimalGroupSize( children: Array<{ position: Position; size: Size }>, _gridInfo?: GridInfo, _gridSettings?: GridSettings, ): Size { if (children.length === 0) { return { width: GRID_SIZE * 20, height: GRID_SIZE * 10 }; } const bounds = children.reduce( (acc, child) => ({ minX: Math.min(acc.minX, child.position.x), minY: Math.min(acc.minY, child.position.y), maxX: Math.max(acc.maxX, child.position.x + child.size.width), maxY: Math.max(acc.maxY, child.position.y + child.size.height), }), { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity }, ); const contentWidth = bounds.maxX - bounds.minX; const contentHeight = bounds.maxY - bounds.minY; const padding = 16; return { width: contentWidth + padding * 2, height: contentHeight + padding * 2, }; } /** * ๊ทธ๋ฃน ๋‚ด ์ƒ๋Œ€ ์ขŒํ‘œ๋ฅผ ๊ฒฉ์ž ๊ธฐ์ค€์œผ๋กœ ์ •๊ทœํ™” */ export function normalizeGroupChildPositions(children: any[], _gridSettings?: GridSettings): any[] { if (children.length === 0) return children; const minX = Math.min(...children.map((child) => child.position.x)); const minY = Math.min(...children.map((child) => child.position.y)); const padding = 16; return children.map((child) => ({ ...child, position: { x: child.position.x - minX + padding, y: child.position.y - minY + padding, z: child.position.z || 1, }, })); } // ๐Ÿ—‘๏ธ ์ œ๊ฑฐ๋œ ํ•จ์ˆ˜๋“ค (๋” ์ด์ƒ ํ•„์š” ์—†์Œ) // - calculateWidthFromColumns // - updateSizeFromGridColumns // - adjustGridColumnsFromSize // - calculateColumnsFromWidth