Add dividing wall for tudengimaja map with button

pull/32/head
v4ltages 4 months ago
parent bf4187220a
commit 57598fc01b
No known key found for this signature in database
GPG Key ID: DC7BC38E0DC642B
  1. 101
      src/app/messiala/page.tsx

@ -3,15 +3,26 @@
import { vipnagorgialla } from "@/components/Vipnagorgialla"; import { vipnagorgialla } from "@/components/Vipnagorgialla";
import * as THREE from "three"; import * as THREE from "three";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { EyeClosed, Eye } from "lucide-react";
// Define interface for the ref with toggle function
interface MountRefCurrent extends HTMLDivElement {
toggleDividers?: (show: boolean) => void;
}
export default function Expo() { export default function Expo() {
const mountRef = useRef<HTMLDivElement>(null); const mountRef = useRef<MountRefCurrent | null>(null);
const [hoveredRoom, setHoveredRoom] = useState<string | null>(null); const [hoveredRoom, setHoveredRoom] = useState<string | null>(null);
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 }); const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
const [showDividers, setShowDividers] = useState<boolean>(true);
useEffect(() => { useEffect(() => {
if (!mountRef.current) return; if (!mountRef.current) return;
// Copy ref to variable to avoid stale closure in cleanup
const mountElement = mountRef.current;
let dividersRef: THREE.Mesh[] = [];
// Scene setup // Scene setup
const scene = new THREE.Scene(); const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0e0f19); scene.background = new THREE.Color(0x0e0f19);
@ -53,7 +64,7 @@ export default function Expo() {
renderer.setSize(width, height); renderer.setSize(width, height);
renderer.shadowMap.enabled = true; renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; renderer.shadowMap.type = THREE.PCFSoftShadowMap;
mountRef.current.appendChild(renderer.domElement); mountElement.appendChild(renderer.domElement);
// Raycaster for mouse interactions // Raycaster for mouse interactions
const raycaster = new THREE.Raycaster(); const raycaster = new THREE.Raycaster();
@ -99,6 +110,7 @@ export default function Expo() {
originalColor: number; originalColor: number;
originalScale: THREE.Vector3; originalScale: THREE.Vector3;
}> = []; }> = [];
const dividers: THREE.Mesh[] = [];
// Define rooms with custom positions, sizes and colors // Define rooms with custom positions, sizes and colors
const roomDefinitions = [ const roomDefinitions = [
@ -130,11 +142,11 @@ export default function Expo() {
name: roomNames[2], name: roomNames[2],
}, // EVAL }, // EVAL
{ {
width: 2, width: 2.2,
height: 0.7, height: 0.7,
depth: 4, depth: 4.5,
x: 5, x: 5,
z: -1.7, z: -2,
color: roomColors[3], color: roomColors[3],
name: roomNames[3], name: roomNames[3],
}, // Redbull }, // Redbull
@ -193,6 +205,35 @@ export default function Expo() {
}); });
}); });
// Create toggleable room dividers
const createTogglableDivider = (
width: number,
height: number,
depth: number,
x: number,
z: number,
) => {
const wallGeometry = new THREE.BoxGeometry(width, height, depth);
const wallMaterial = new THREE.MeshLambertMaterial({
color: 0x555555,
transparent: true,
opacity: 0,
});
const wall = new THREE.Mesh(wallGeometry, wallMaterial);
wall.position.set(x, height / 2, z);
wall.visible = false;
scene.add(wall);
dividers.push(wall);
};
// Add strategic dividers between major areas
createTogglableDivider(10, 2, 2, -2.5, 1.5); // Wall between main entrance
createTogglableDivider(2, 2, 2, 5.5, 1.5); // Wall right next to Mänguklubi & Redbull
// Store dividers reference for later access
dividersRef = [...dividers];
// Ground plane // Ground plane
const groundGeometry = new THREE.PlaneGeometry(14, 10.5); const groundGeometry = new THREE.PlaneGeometry(14, 10.5);
const groundMaterial = new THREE.MeshLambertMaterial({ color: 0xcccccc }); const groundMaterial = new THREE.MeshLambertMaterial({ color: 0xcccccc });
@ -205,7 +246,9 @@ export default function Expo() {
// Second ground plane // Second ground plane
const groundGeometry2 = new THREE.PlaneGeometry(2, 7); const groundGeometry2 = new THREE.PlaneGeometry(2, 7);
const groundMaterial2 = new THREE.MeshLambertMaterial({ color: 0xcccccc }); const groundMaterial2 = new THREE.MeshLambertMaterial({
color: 0xcccccc,
});
const ground2 = new THREE.Mesh(groundGeometry2, groundMaterial2); const ground2 = new THREE.Mesh(groundGeometry2, groundMaterial2);
ground2.rotation.x = -Math.PI / 2; ground2.rotation.x = -Math.PI / 2;
ground2.position.x = -12.2; ground2.position.x = -12.2;
@ -294,17 +337,37 @@ export default function Expo() {
animate(); animate();
// Function to toggle dividers
const toggleDividers = (show: boolean) => {
dividersRef.forEach((divider) => {
divider.visible = show;
(divider.material as THREE.MeshLambertMaterial).opacity = show
? 0.4
: 0;
});
};
// Expose toggle function to parent scope
mountElement.toggleDividers = toggleDividers;
// Cleanup // Cleanup
return () => { return () => {
window.removeEventListener("resize", handleResize); window.removeEventListener("resize", handleResize);
renderer.domElement.removeEventListener("mousemove", onMouseMove); renderer.domElement.removeEventListener("mousemove", onMouseMove);
if (mountRef.current && renderer.domElement) { if (mountElement && renderer.domElement) {
mountRef.current.removeChild(renderer.domElement); mountElement.removeChild(renderer.domElement);
} }
renderer.dispose(); renderer.dispose();
}; };
}, []); }, []);
// Update dividers when showDividers state changes
useEffect(() => {
if (mountRef.current?.toggleDividers) {
mountRef.current.toggleDividers(showDividers);
}
}, [showDividers]);
return ( return (
<div className="flex flex-col min-h-[90vh] m-6 mt-16 md:m-16"> <div className="flex flex-col min-h-[90vh] m-6 mt-16 md:m-16">
<h1 <h1
@ -316,7 +379,7 @@ export default function Expo() {
<h2 className="text-2xl text-[#2A2C3F] dark:text-[#EEE5E5] mb-3"> <h2 className="text-2xl text-[#2A2C3F] dark:text-[#EEE5E5] mb-3">
Tudengimaja Tudengimaja
</h2> </h2>
<div className="flex flex-wrap gap-4"> <div className="flex flex-wrap gap-4 pb-4">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div <div
className="w-4 h-4 border border-gray-300" className="w-4 h-4 border border-gray-300"
@ -381,10 +444,22 @@ export default function Expo() {
</span> </span>
</div> </div>
</div> </div>
</div> <div className="flex flex-col lg:flex-row gap-8 items-start">
<div className="flex flex-col lg:flex-row gap-8 items-start"> <div className="flex-shrink-0 border-3 border-[#1F5673] w-full max-w-[800px] relative">
<div className="flex-shrink-0 border-3 border-[#1F5673] w-full max-w-[800px]"> <div ref={mountRef} className="w-full" />
<div ref={mountRef} className="w-full" /> <button
onClick={() => setShowDividers(!showDividers)}
className={`absolute top-2 right-2 px-3 py-2 bg-[#1F5673] text-white hover:bg-[#2A7A9B] ${vipnagorgialla.className} uppercase italic text-sm font-semibold flex items-center transition-colors shadow-lg z-10`}
>
{showDividers ? (
<EyeClosed className="w-6 h-6 mr-2" />
) : (
<Eye className="w-6 h-6 mr-2" />
)}
{showDividers ? "Peida" : "Näita"}
</button>
</div>
</div> </div>
{/* Tooltip */} {/* Tooltip */}

Loading…
Cancel
Save