Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | 5x 5x 5x 28x 28x | /**
* Shared constants for orientation-aware responsive layout.
*
* Extracted so that `useCombatLayout` and `useTrainingLayout` compute the
* same portrait "bottom band" and share a single source of truth for the
* portrait-forcing hysteresis and the reserved control-column heights.
*
* 반응형 레이아웃 상수
*
* @module utils/responsiveOrientationConstants
* @category Layout
*/
/**
* Hysteresis factor for portrait detection.
*
* A viewport is treated as portrait when `height > width × FACTOR`. The
* factor is < 1.0 so near-square viewports (e.g. `1024×1000`) settle into
* one orientation and don't flap on every pixel of resize.
*
* @public
*/
export const PORTRAIT_HYSTERESIS_FACTOR = 0.9;
/**
* Maximum width at which a portrait viewport is force-promoted to the mobile
* layout branch even if the user-agent reports a desktop browser. Matches the
* tablet breakpoint used elsewhere in the codebase (1024px).
*
* This makes devtools emulation of a rotated phone/tablet behave identically
* to a real device.
*
* @public
*/
export const PORTRAIT_FORCE_MAX_WIDTH_PX = 1024;
/**
* Height reserved at the bottom of a mobile portrait viewport for the
* on-screen virtual controls (D-Pad + action buttons rendered by
* `MobileControlsWrapper`). Used as a conservative upper bound so the
* 3D arena never ends up drawn behind the controls.
*
* Two values are provided so that very small phones (iPhone SE class,
* width < 380) can still fit a playable arena.
*
* Combat uses the larger 200/160 band because its Mobile controls stack
* D-Pad + action buttons + the persistent technique bar. Training uses
* the smaller 180/140 band because its on-screen controls are lighter.
*
* @public
*/
export const MOBILE_CONTROLS_RESERVED_HEIGHT_PX = {
/** D-Pad + action buttons + technique bar on combat (standard phones) */
combatStandard: 200,
/** Combat controls on extra-small phones (width < 380) */
combatExtraSmall: 160,
/** Training on-screen controls (standard phones) */
trainingStandard: 180,
/** Training on-screen controls (extra-small phones) */
trainingExtraSmall: 140,
} as const;
/**
* Total bottom clearance to reserve in portrait mode = control/technique
* bar height + footer height + the on-screen virtual controls band.
*
* @param controlsHeight - layout constant for technique/control bar
* @param footerHeight - layout constant for footer
* @param isExtraSmall - true when the viewport is < 380px wide
* @param variant - "combat" or "training" (differs in control band size)
*
* @public
*/
export function portraitMobileControlsBottomBand(
controlsHeight: number,
footerHeight: number,
isExtraSmall: boolean,
variant: "combat" | "training",
): number {
const band =
variant === "combat"
? isExtraSmall
? MOBILE_CONTROLS_RESERVED_HEIGHT_PX.combatExtraSmall
: MOBILE_CONTROLS_RESERVED_HEIGHT_PX.combatStandard
: isExtraSmall
? MOBILE_CONTROLS_RESERVED_HEIGHT_PX.trainingExtraSmall
: MOBILE_CONTROLS_RESERVED_HEIGHT_PX.trainingStandard;
return controlsHeight + footerHeight + band;
}
|