mirror of
https://github.com/Lapikud/tipilan.git
synced 2026-03-23 13:24:21 +00:00
Add dividing wall for tudengimaja map with button
This commit is contained in:
@@ -3,15 +3,26 @@
|
||||
import { vipnagorgialla } from "@/components/Vipnagorgialla";
|
||||
import * as THREE from "three";
|
||||
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() {
|
||||
const mountRef = useRef<HTMLDivElement>(null);
|
||||
const mountRef = useRef<MountRefCurrent | null>(null);
|
||||
const [hoveredRoom, setHoveredRoom] = useState<string | null>(null);
|
||||
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
|
||||
const [showDividers, setShowDividers] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (!mountRef.current) return;
|
||||
|
||||
// Copy ref to variable to avoid stale closure in cleanup
|
||||
const mountElement = mountRef.current;
|
||||
let dividersRef: THREE.Mesh[] = [];
|
||||
|
||||
// Scene setup
|
||||
const scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0x0e0f19);
|
||||
@@ -53,7 +64,7 @@ export default function Expo() {
|
||||
renderer.setSize(width, height);
|
||||
renderer.shadowMap.enabled = true;
|
||||
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
||||
mountRef.current.appendChild(renderer.domElement);
|
||||
mountElement.appendChild(renderer.domElement);
|
||||
|
||||
// Raycaster for mouse interactions
|
||||
const raycaster = new THREE.Raycaster();
|
||||
@@ -99,6 +110,7 @@ export default function Expo() {
|
||||
originalColor: number;
|
||||
originalScale: THREE.Vector3;
|
||||
}> = [];
|
||||
const dividers: THREE.Mesh[] = [];
|
||||
|
||||
// Define rooms with custom positions, sizes and colors
|
||||
const roomDefinitions = [
|
||||
@@ -130,11 +142,11 @@ export default function Expo() {
|
||||
name: roomNames[2],
|
||||
}, // EVAL
|
||||
{
|
||||
width: 2,
|
||||
width: 2.2,
|
||||
height: 0.7,
|
||||
depth: 4,
|
||||
depth: 4.5,
|
||||
x: 5,
|
||||
z: -1.7,
|
||||
z: -2,
|
||||
color: roomColors[3],
|
||||
name: roomNames[3],
|
||||
}, // 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
|
||||
const groundGeometry = new THREE.PlaneGeometry(14, 10.5);
|
||||
const groundMaterial = new THREE.MeshLambertMaterial({ color: 0xcccccc });
|
||||
@@ -205,7 +246,9 @@ export default function Expo() {
|
||||
|
||||
// Second ground plane
|
||||
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);
|
||||
ground2.rotation.x = -Math.PI / 2;
|
||||
ground2.position.x = -12.2;
|
||||
@@ -294,17 +337,37 @@ export default function Expo() {
|
||||
|
||||
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
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
renderer.domElement.removeEventListener("mousemove", onMouseMove);
|
||||
if (mountRef.current && renderer.domElement) {
|
||||
mountRef.current.removeChild(renderer.domElement);
|
||||
if (mountElement && renderer.domElement) {
|
||||
mountElement.removeChild(renderer.domElement);
|
||||
}
|
||||
renderer.dispose();
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Update dividers when showDividers state changes
|
||||
useEffect(() => {
|
||||
if (mountRef.current?.toggleDividers) {
|
||||
mountRef.current.toggleDividers(showDividers);
|
||||
}
|
||||
}, [showDividers]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col min-h-[90vh] m-6 mt-16 md:m-16">
|
||||
<h1
|
||||
@@ -316,7 +379,7 @@ export default function Expo() {
|
||||
<h2 className="text-2xl text-[#2A2C3F] dark:text-[#EEE5E5] mb-3">
|
||||
Tudengimaja
|
||||
</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="w-4 h-4 border border-gray-300"
|
||||
@@ -381,10 +444,22 @@ export default function Expo() {
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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]">
|
||||
<div ref={mountRef} className="w-full" />
|
||||
<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 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>
|
||||
|
||||
{/* Tooltip */}
|
||||
|
||||
Reference in New Issue
Block a user