diff --git a/app.js b/app.js index 6e85528..2b3e5ac 100644 --- a/app.js +++ b/app.js @@ -119,6 +119,27 @@ document.addEventListener('mousemove', (e) => { mouseY = (e.clientY / window.innerHeight - 0.5) * 2; }); +// === OVERVIEW MODE (Tab — bird's-eye view of the whole Nexus) === +let overviewMode = false; +let overviewT = 0; // 0 = normal view, 1 = overview + +const NORMAL_CAM = new THREE.Vector3(0, 0, 5); +const OVERVIEW_CAM = new THREE.Vector3(0, 200, 0.1); // overhead; tiny Z offset avoids gimbal lock + +const overviewIndicator = document.getElementById('overview-indicator'); + +document.addEventListener('keydown', (e) => { + if (e.key === 'Tab') { + e.preventDefault(); + overviewMode = !overviewMode; + if (overviewMode) { + overviewIndicator.classList.add('visible'); + } else { + overviewIndicator.classList.remove('visible'); + } + } +}); + // === RESIZE HANDLER === window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; @@ -133,12 +154,19 @@ function animate() { requestAnimationFrame(animate); const elapsed = clock.getElapsedTime(); - // Slow auto-rotation + // Smooth camera transition for overview mode + const targetT = overviewMode ? 1 : 0; + overviewT += (targetT - overviewT) * 0.04; + camera.position.lerpVectors(NORMAL_CAM, OVERVIEW_CAM, overviewT); + camera.lookAt(0, 0, 0); + + // Slow auto-rotation — suppressed during overview so the map stays readable + const rotationScale = 1 - overviewT; targetRotX += (mouseY * 0.3 - targetRotX) * 0.02; targetRotY += (mouseX * 0.3 - targetRotY) * 0.02; - stars.rotation.x = targetRotX + elapsed * 0.01; - stars.rotation.y = targetRotY + elapsed * 0.015; + stars.rotation.x = (targetRotX + elapsed * 0.01) * rotationScale; + stars.rotation.y = (targetRotY + elapsed * 0.015) * rotationScale; constellationLines.rotation.x = stars.rotation.x; constellationLines.rotation.y = stars.rotation.y; diff --git a/index.html b/index.html index 2006413..26344f3 100644 --- a/index.html +++ b/index.html @@ -36,6 +36,11 @@ +