diff --git a/app.js b/app.js index 73e293f..922b1fb 100644 --- a/app.js +++ b/app.js @@ -1134,8 +1134,12 @@ document.addEventListener('keydown', (e) => { if (e.key === 'Escape') exitZoom(); }); -// === PHOTO MODE === -let photoMode = false; + // Update energy beam pulse effect + beamPulseTime += 0.02; + beamMaterial.opacity = 0.5 + Math.sin(beamPulseTime) * 0.2; + + // === PHOTO MODE === + let photoMode = false; // Warp effect state let isWarping = false; @@ -1210,6 +1214,9 @@ document.addEventListener('keydown', (e) => { } }); +// Animation variables for energy beam pulse effect +let beamPulseTime = 0; + // === RESIZE HANDLER === window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; @@ -1218,6 +1225,28 @@ window.addEventListener('resize', () => { composer.setSize(window.innerWidth, window.innerHeight); }); +// === BATCAVE TERMINAL ENERGY BEAM === +// Vertical energy beam from Batcave terminal shooting up into the sky +const energyBeamGroup = new THREE.Group(); +energyBeamGroup.position.set(3, 0.1, 3); // Positioned at Batcave terminal area +scene.add(energyBeamGroup); + +// Cylinder geometry for the energy beam +const beamGeometry = new THREE.CylinderGeometry(0.2, 0.2, 50, 32, 32); + +// Emissive material with animated opacity +const beamMaterial = new THREE.MeshBasicMaterial({ + color: 0x00ffff, + transparent: true, + opacity: 0.7, + blending: THREE.AdditiveBlending, + side: THREE.DoubleSide +}); + +const energyBeam = new THREE.Mesh(beamGeometry, beamMaterial); +energyBeam.rotation.x = Math.PI / 2; // Vertical orientation +energyBeamGroup.add(energyBeam); + // === SOVEREIGNTY METER === // Holographic arc gauge floating above the platform; reads from sovereignty-status.json const sovereigntyGroup = new THREE.Group();