Files
Aislo/B06_Section/B06_Section_UI_Section_Columns.ts
T

45 lines
2.1 KiB
TypeScript

/* =============================================================================
* 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));
});
}