feat(B06): 54-34 횡단 카드 한 줄 수 자동 · 카드 폭 400~800
보기 칸 높이에 첫 줄 + 둘째 줄 절반이 드는 가장 적은 카드 수를 고름 (카드 폭 400~800px 상수는 Section_Common 한 곳). 그림은 px 그대로. 창 크기 · 패널 높이 변화 때 다시 맞춤 (높이만 바뀌면 카드 수가 바뀔 때만 다시 그림). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
/* =============================================================================
|
||||
* B06_Section_UI_Section_Columns.ts
|
||||
* 횡단 카드 한 줄 카드 수 고르기 — 보기 칸 높이에 첫 줄 + 둘째 줄 절반이 들어가는
|
||||
* 가장 적은 카드 수. 카드 폭은 최소~최대 폭 안(그림은 축척 그대로 · 폭만 바뀜).
|
||||
* ========================================================================== */
|
||||
|
||||
import {
|
||||
CROSS_CARD_CHROME,
|
||||
CROSS_GRID_GAP,
|
||||
CROSS_GRID_MAX_WIDTH,
|
||||
CROSS_GRID_MIN_WIDTH,
|
||||
} from "./B06_Section_UI_Section_Common";
|
||||
|
||||
export interface CrossColumns {
|
||||
columns: number;
|
||||
cardWidth: number;
|
||||
}
|
||||
|
||||
const widthFor = (columns: number, viewWidth: number): number =>
|
||||
Math.min(CROSS_GRID_MAX_WIDTH, (viewWidth - (columns - 1) * CROSS_GRID_GAP) / columns);
|
||||
|
||||
/**
|
||||
* `heightsFor(cardWidth, count)` — 그 폭일 때 앞 `count` 장의 카드 자연 높이.
|
||||
* `viewHeight` 가 0 이하(숨김 · 아직 안 잰 칸)면 가장 큰 카드 쪽을 고른다.
|
||||
*/
|
||||
export function pickCrossColumns(
|
||||
viewWidth: number,
|
||||
viewHeight: number,
|
||||
heightsFor: (cardWidth: number, count: number) => number[],
|
||||
): CrossColumns {
|
||||
const unit = CROSS_GRID_MIN_WIDTH + CROSS_GRID_GAP;
|
||||
const most = Math.max(1, Math.floor((viewWidth + CROSS_GRID_GAP) / unit));
|
||||
const fewest = Math.min(
|
||||
most,
|
||||
Math.max(1, Math.ceil((viewWidth + CROSS_GRID_GAP) / (CROSS_GRID_MAX_WIDTH + CROSS_GRID_GAP))),
|
||||
);
|
||||
for (let columns = fewest; columns < most; columns += 1) {
|
||||
const cardWidth = widthFor(columns, viewWidth);
|
||||
if (viewHeight <= 0) return { columns, cardWidth };
|
||||
const heights = heightsFor(cardWidth, columns * 2);
|
||||
const first = Math.max(0, ...heights.slice(0, columns)) + CROSS_CARD_CHROME;
|
||||
const second = Math.max(0, ...heights.slice(columns)) + CROSS_CARD_CHROME;
|
||||
const needed = heights.length > columns ? first + CROSS_GRID_GAP + second / 2 : first;
|
||||
if (needed <= viewHeight) return { columns, cardWidth };
|
||||
}
|
||||
return { columns: most, cardWidth: widthFor(most, viewWidth) };
|
||||
}
|
||||
Reference in New Issue
Block a user