diff --git a/src/App.css b/src/App.css index 8ebca88..baebfdb 100644 --- a/src/App.css +++ b/src/App.css @@ -41,11 +41,16 @@ .content { position: absolute; width: calc(100vw / 0.01); /* Width based on minimum zoom (0.01) */ - height: calc(100vh / 0.01); /* Height based on minimum zoom (0.01) */ + height: calc((100vh - 100px) / 0.01); /* Height based on minimum zoom minus UI height */ transform-origin: 0 0; background-color: white; will-change: transform; contain: layout paint; + /* Add a subtle grid pattern to help with orientation */ + background-image: + linear-gradient(rgba(200, 200, 200, 0.1) 1px, transparent 1px), + linear-gradient(90deg, rgba(200, 200, 200, 0.1) 1px, transparent 1px); + background-size: 50px 50px; } .target { diff --git a/src/types.ts b/src/types.ts index 33a1694..465c559 100644 --- a/src/types.ts +++ b/src/types.ts @@ -43,8 +43,8 @@ export interface Round { export const CONSTANTS = { TARGET_COUNT: 200, - TARGET_MIN_RADIUS: 20, - TARGET_MAX_RADIUS: 40, + TARGET_MIN_RADIUS: 100, + TARGET_MAX_RADIUS: 600, VIRTUAL_CANVAS_SIZE: 50000, ZOOM_LEVELS: { min: 0.01, diff --git a/src/utils/interaction.ts b/src/utils/interaction.ts index 07d1af7..e580cac 100644 --- a/src/utils/interaction.ts +++ b/src/utils/interaction.ts @@ -11,17 +11,23 @@ export const calculateZoomDelta = ( export const calculateInitialViewport = (initialZoom: number): ViewportOffset => { // When fully zoomed out, we want to see the entire content area // The target distribution is sized to match the viewport at minimum zoom - // So at any higher zoom level, we need to position appropriately + // Account for the UI exclusion zone at the top const windowWidth = window.innerWidth; const windowHeight = window.innerHeight; + // Same UI margin as in target generation + const UI_TOP_MARGIN = 100; + // Center the viewport on the target area const areaWidth = windowWidth / CONSTANTS.ZOOM_LEVELS.min; - const areaHeight = windowHeight / CONSTANTS.ZOOM_LEVELS.min; + const areaHeight = (windowHeight - UI_TOP_MARGIN) / CONSTANTS.ZOOM_LEVELS.min; + + // Account for the UI exclusion zone in Y offset + const startY = UI_TOP_MARGIN / CONSTANTS.ZOOM_LEVELS.min; return { x: (areaWidth - windowWidth / initialZoom) / 2, - y: (areaHeight - windowHeight / initialZoom) / 2 + y: startY + (areaHeight - windowHeight / initialZoom) / 2 }; }; diff --git a/src/utils/target.ts b/src/utils/target.ts index 236076c..e5a187f 100644 --- a/src/utils/target.ts +++ b/src/utils/target.ts @@ -3,19 +3,25 @@ import { Target, CONSTANTS } from '../types'; export const generateTargets = () => { const newTargets: Target[] = []; - // Fixed target size for better visibility - const MIN_RADIUS = 100; - const MAX_RADIUS = 600; + // Use the constants from types.ts for consistency + const MIN_RADIUS = CONSTANTS.TARGET_MIN_RADIUS; + const MAX_RADIUS = CONSTANTS.TARGET_MAX_RADIUS; // Get browser window dimensions const windowWidth = window.innerWidth; const windowHeight = window.innerHeight; + // Define UI exclusion zone (top area where UI elements are located) + const UI_TOP_MARGIN = 100; // pixels from top to exclude + // Base the target area on the minimum zoom level // This ensures when fully zoomed out, we see the entire grid const minZoom = CONSTANTS.ZOOM_LEVELS.min; const areaWidth = windowWidth / minZoom; - const areaHeight = windowHeight / minZoom; + const areaHeight = (windowHeight - UI_TOP_MARGIN) / minZoom; + + // Start Y position below the UI elements + const startY = UI_TOP_MARGIN / minZoom; // Create a grid-like distribution const gridSize = Math.ceil(Math.sqrt(CONSTANTS.TARGET_COUNT)); @@ -31,9 +37,9 @@ export const generateTargets = () => { const randomOffsetX = (Math.random() - 0.5) * cellWidth * 0.6; const randomOffsetY = (Math.random() - 0.5) * cellHeight * 0.6; - // Calculate final position + // Calculate final position - add startY to push everything down below UI const x = cellWidth * (gridX + 0.5) + randomOffsetX; - const y = cellHeight * (gridY + 0.5) + randomOffsetY; + const y = startY + cellHeight * (gridY + 0.5) + randomOffsetY; // Random radius const radius = MIN_RADIUS + Math.random() * (MAX_RADIUS - MIN_RADIUS);