/* ============================================================================= * B06_Section_UI_Section_Columns.ts * 횡단 카드 열 수 · 폭 · 높이(138-3) — 열 수 = 사용자 값(알림 줄 오른쪽 끝 · 1~6 · 기본 3). * 카드 폭 = (칸 폭 − 간격) ÷ 열 수 · 그래프 높이 = 폭 × (3열 기준 높이 ÷ 3열 폭) — 열 수가 * 바뀌어도 그림 비율 그대로(글자 크기는 그대로). * import 없음 — 시험이 이 파일만 옮겨 돌림(`test_138_cross_columns.py`). * ========================================================================== */ export const CROSS_COLUMNS_MIN = 1; export const CROSS_COLUMNS_MAX = 6; export const CROSS_COLUMNS_DEFAULT = 3; /** 높이 비율의 기준 열 수. */ export const CROSS_COLUMNS_BASE = 3; /** 저장값 → 열 수(정수 · 1~6 · 못 읽으면 기본 3 · 저장값 없음 null 포함). */ export function clampCrossColumns(value: unknown): number { if (value == null) return CROSS_COLUMNS_DEFAULT; const number = typeof value === "string" && value.trim() === "" ? NaN : Number(value); if (!Number.isFinite(number)) return CROSS_COLUMNS_DEFAULT; return Math.min(CROSS_COLUMNS_MAX, Math.max(CROSS_COLUMNS_MIN, Math.round(number))); } /** 카드 폭(px) = (칸 폭 − 간격 × (열 수 − 1)) ÷ 열 수. */ export function crossCardWidth(viewWidth: number, columns: number, gap: number): number { return Math.max(0, (viewWidth - gap * (columns - 1)) / columns); } /** * 카드마다 강제 높이(px) — `baseHeights[i]` = 그 카드를 3열 폭(`baseWidth`)으로 그렸을 때 높이. * 지금 폭으로 비례해 늘리고 · 같은 줄(열 수 단위) 최댓값으로 맞춤. */ export function crossRowHeights( baseHeights: readonly number[], baseWidth: number, cardWidth: number, columns: number, ): number[] { const scale = baseWidth > 0 ? cardWidth / baseWidth : 1; const heights = baseHeights.map((height) => height * scale); return heights.map((_, index) => { const start = index - (index % columns); return Math.max(...heights.slice(start, start + columns)); }); }