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 92 93 94 | 75x 75x 75x 47x 47x 47x 47x 47x 75x | /**
* useCombatLayout Hook - Optimized Layout Calculations
*
* Custom hook for managing responsive combat screen layout calculations.
* Optimizes layout recalculations by minimizing dependencies and memoizing
* complex calculations.
*
* Performance:
* - Reduces recalculations by checking only breakpoint changes, not exact dimensions
* - Memoizes arena bounds to prevent cascading re-renders
* - Targets <1ms execution time for layout calculations
*
* @param width - Screen width
* @param height - Screen height
*
* @returns Layout constants and arena bounds
*
* @example
* ```typescript
* const { layoutConstants, arenaBounds, isMobile } = useCombatLayout(1200, 800);
* ```
*/
import { useMemo } from "react";
export interface LayoutConstants {
readonly padding: number;
readonly hudHeight: number;
readonly controlsHeight: number;
readonly footerHeight: number;
readonly healthBarHeight: number;
}
export interface ArenaBounds {
readonly x: number;
readonly y: number;
readonly width: number;
readonly height: number;
}
export interface CombatLayout {
readonly layoutConstants: LayoutConstants;
readonly arenaBounds: ArenaBounds;
readonly isMobile: boolean;
}
/**
* Custom hook for combat screen layout calculations
* Optimized to reduce recalculations and improve 60fps performance
*/
export function useCombatLayout(width: number, height: number): CombatLayout {
// Performance: Only recalculate when crossing mobile breakpoint (768px)
// This prevents recalculation on every pixel change during resize
const isMobile = useMemo(() => width < 768, [width]);
// Centralized layout constants for easier tweaking
// Optimized: Only depends on isMobile boolean, not exact width
const layoutConstants = useMemo<LayoutConstants>(() => ({
padding: 10,
hudHeight: isMobile ? 100 : 140,
controlsHeight: isMobile ? 140 : 180,
footerHeight: isMobile ? 25 : 30,
healthBarHeight: isMobile ? 50 : 60,
}), [isMobile]);
// Fixed player positions for 2-player combat with proper bounds
// Arena bounds should account for HUD at top and controls at bottom
// Optimized: Separate calculation dependencies to reduce recalculation frequency
const arenaBounds = useMemo<ArenaBounds>(() => {
const arenaY = layoutConstants.hudHeight + layoutConstants.padding;
// Break down complex calculation for clarity and maintainability
const totalReservedHeight =
layoutConstants.hudHeight +
layoutConstants.controlsHeight +
layoutConstants.footerHeight;
const totalPadding = layoutConstants.padding * 3;
const arenaHeight = height - totalReservedHeight - totalPadding;
return {
x: width * 0.1,
y: arenaY,
width: width * 0.8,
height: arenaHeight,
};
}, [width, height, layoutConstants]);
return {
layoutConstants,
arenaBounds,
isMobile,
};
}
|