|
|
|
|
@ -1,9 +1,10 @@ |
|
|
|
|
"use client"; |
|
|
|
|
|
|
|
|
|
import { vipnagorgialla } from "@/components/Vipnagorgialla"; |
|
|
|
|
import {vipnagorgialla} from "@/components/Vipnagorgialla"; |
|
|
|
|
import * as THREE from "three"; |
|
|
|
|
import { useEffect, useRef, useState } from "react"; |
|
|
|
|
import { EyeClosed, Eye } from "lucide-react"; |
|
|
|
|
import {useEffect, useRef, useState} from "react"; |
|
|
|
|
import {EyeClosed, Eye} from "lucide-react"; |
|
|
|
|
import SectionDivider from "@/components/SectionDivider"; |
|
|
|
|
|
|
|
|
|
// Define interface for the ref with toggle function
|
|
|
|
|
interface MountRefCurrent extends HTMLDivElement { |
|
|
|
|
@ -13,7 +14,7 @@ interface MountRefCurrent extends HTMLDivElement { |
|
|
|
|
export default function Expo() { |
|
|
|
|
const mountRef = useRef<MountRefCurrent | 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(() => { |
|
|
|
|
@ -30,17 +31,17 @@ export default function Expo() { |
|
|
|
|
// Get responsive dimensions
|
|
|
|
|
const getResponsiveDimensions = () => { |
|
|
|
|
const container = mountRef.current; |
|
|
|
|
if (!container) return { width: 800, height: 600 }; |
|
|
|
|
if (!container) return {width: 800, height: 600}; |
|
|
|
|
|
|
|
|
|
const containerWidth = container.offsetWidth; |
|
|
|
|
const maxWidth = Math.min(containerWidth, 800); |
|
|
|
|
const width = Math.max(maxWidth, 300); // Minimum width
|
|
|
|
|
const height = (width * 600) / 800; // Maintain aspect ratio
|
|
|
|
|
|
|
|
|
|
return { width, height }; |
|
|
|
|
return {width, height}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const { width, height } = getResponsiveDimensions(); |
|
|
|
|
const {width, height} = getResponsiveDimensions(); |
|
|
|
|
|
|
|
|
|
// Isometric camera setup with responsive sizing
|
|
|
|
|
const aspect = width / height; |
|
|
|
|
@ -60,7 +61,7 @@ export default function Expo() { |
|
|
|
|
camera.lookAt(-1.4, 0, 0); |
|
|
|
|
|
|
|
|
|
// Renderer
|
|
|
|
|
const renderer = new THREE.WebGLRenderer({ antialias: true }); |
|
|
|
|
const renderer = new THREE.WebGLRenderer({antialias: true}); |
|
|
|
|
renderer.setSize(width, height); |
|
|
|
|
renderer.shadowMap.enabled = true; |
|
|
|
|
renderer.shadowMap.type = THREE.PCFSoftShadowMap; |
|
|
|
|
@ -193,7 +194,7 @@ export default function Expo() { |
|
|
|
|
room.position.set(roomDef.x, roomDef.height / 2, roomDef.z); |
|
|
|
|
room.castShadow = true; |
|
|
|
|
room.receiveShadow = true; |
|
|
|
|
room.userData = { name: roomDef.name, originalColor: roomDef.color }; |
|
|
|
|
room.userData = {name: roomDef.name, originalColor: roomDef.color}; |
|
|
|
|
|
|
|
|
|
scene.add(room); |
|
|
|
|
rooms.push(room); |
|
|
|
|
@ -236,7 +237,7 @@ export default function Expo() { |
|
|
|
|
|
|
|
|
|
// Ground plane
|
|
|
|
|
const groundGeometry = new THREE.PlaneGeometry(14, 10.5); |
|
|
|
|
const groundMaterial = new THREE.MeshLambertMaterial({ color: 0xcccccc }); |
|
|
|
|
const groundMaterial = new THREE.MeshLambertMaterial({color: 0xcccccc}); |
|
|
|
|
const ground = new THREE.Mesh(groundGeometry, groundMaterial); |
|
|
|
|
ground.rotation.x = -Math.PI / 2; |
|
|
|
|
ground.position.x = -1.1; |
|
|
|
|
@ -258,7 +259,7 @@ export default function Expo() { |
|
|
|
|
|
|
|
|
|
// Resize handler
|
|
|
|
|
const handleResize = () => { |
|
|
|
|
const { width: newWidth, height: newHeight } = getResponsiveDimensions(); |
|
|
|
|
const {width: newWidth, height: newHeight} = getResponsiveDimensions(); |
|
|
|
|
|
|
|
|
|
// Update camera
|
|
|
|
|
const newAspect = newWidth / newHeight; |
|
|
|
|
@ -285,14 +286,14 @@ export default function Expo() { |
|
|
|
|
mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1; |
|
|
|
|
|
|
|
|
|
// Update mouse position for tooltip
|
|
|
|
|
setMousePosition({ x: event.clientX, y: event.clientY }); |
|
|
|
|
setMousePosition({x: event.clientX, y: event.clientY}); |
|
|
|
|
|
|
|
|
|
// Update raycaster
|
|
|
|
|
raycaster.setFromCamera(mouse, camera); |
|
|
|
|
const intersects = raycaster.intersectObjects(rooms); |
|
|
|
|
|
|
|
|
|
// Reset all rooms to original state
|
|
|
|
|
roomData.forEach(({ mesh, originalColor, originalScale }) => { |
|
|
|
|
roomData.forEach(({mesh, originalColor, originalScale}) => { |
|
|
|
|
(mesh.material as THREE.MeshLambertMaterial).color.setHex( |
|
|
|
|
originalColor, |
|
|
|
|
); |
|
|
|
|
@ -369,6 +370,7 @@ export default function Expo() { |
|
|
|
|
}, [showDividers]); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<div> |
|
|
|
|
<div className="flex flex-col min-h-[90vh] m-6 mt-16 md:m-16"> |
|
|
|
|
<h1 |
|
|
|
|
className={`text-4xl md:text-5xl lg:text-6xl ${vipnagorgialla.className} font-bold italic text-[#2A2C3F] dark:text-[#EEE5E5] mt-8 md:mt-16 mb-4 uppercase`} |
|
|
|
|
@ -383,7 +385,7 @@ export default function Expo() { |
|
|
|
|
<div className="flex items-center gap-2"> |
|
|
|
|
<div |
|
|
|
|
className="w-4 h-4 border border-gray-300" |
|
|
|
|
style={{ backgroundColor: "#ff6b35" }} |
|
|
|
|
style={{backgroundColor: "#ff6b35"}} |
|
|
|
|
></div> |
|
|
|
|
<span className="text-sm text-[#2A2C3F] dark:text-[#EEE5E5]"> |
|
|
|
|
Mänguklubi |
|
|
|
|
@ -392,7 +394,7 @@ export default function Expo() { |
|
|
|
|
<div className="items-center gap-2 hidden"> |
|
|
|
|
<div |
|
|
|
|
className="w-4 h-4 border border-gray-300" |
|
|
|
|
style={{ backgroundColor: "#4ecdc4" }} |
|
|
|
|
style={{backgroundColor: "#4ecdc4"}} |
|
|
|
|
></div> |
|
|
|
|
<span className="text-sm text-[#2A2C3F] dark:text-[#EEE5E5]"> |
|
|
|
|
Baariala |
|
|
|
|
@ -401,7 +403,7 @@ export default function Expo() { |
|
|
|
|
<div className="flex items-center gap-2"> |
|
|
|
|
<div |
|
|
|
|
className="w-4 h-4 border border-gray-300" |
|
|
|
|
style={{ backgroundColor: "#ffe66d" }} |
|
|
|
|
style={{backgroundColor: "#ffe66d"}} |
|
|
|
|
></div> |
|
|
|
|
<span className="text-sm text-[#2A2C3F] dark:text-[#EEE5E5]"> |
|
|
|
|
EVAL |
|
|
|
|
@ -410,7 +412,7 @@ export default function Expo() { |
|
|
|
|
<div className="flex items-center gap-2"> |
|
|
|
|
<div |
|
|
|
|
className="w-4 h-4 border border-gray-300" |
|
|
|
|
style={{ backgroundColor: "#e74c3c" }} |
|
|
|
|
style={{backgroundColor: "#e74c3c"}} |
|
|
|
|
></div> |
|
|
|
|
<span className="text-sm text-[#2A2C3F] dark:text-[#EEE5E5]"> |
|
|
|
|
Redbull |
|
|
|
|
@ -419,7 +421,7 @@ export default function Expo() { |
|
|
|
|
<div className="flex items-center gap-2"> |
|
|
|
|
<div |
|
|
|
|
className="w-4 h-4 border border-gray-300" |
|
|
|
|
style={{ backgroundColor: "#9b59b6" }} |
|
|
|
|
style={{backgroundColor: "#9b59b6"}} |
|
|
|
|
></div> |
|
|
|
|
<span className="text-sm text-[#2A2C3F] dark:text-[#EEE5E5]"> |
|
|
|
|
Võitlusmängu ala |
|
|
|
|
@ -428,7 +430,7 @@ export default function Expo() { |
|
|
|
|
<div className="flex items-center gap-2"> |
|
|
|
|
<div |
|
|
|
|
className="w-4 h-4 border border-gray-300" |
|
|
|
|
style={{ backgroundColor: "#3498db" }} |
|
|
|
|
style={{backgroundColor: "#3498db"}} |
|
|
|
|
></div> |
|
|
|
|
<span className="text-sm text-[#2A2C3F] dark:text-[#EEE5E5]"> |
|
|
|
|
Sony |
|
|
|
|
@ -437,7 +439,7 @@ export default function Expo() { |
|
|
|
|
<div className="flex items-center gap-2"> |
|
|
|
|
<div |
|
|
|
|
className="w-4 h-4 border border-gray-300" |
|
|
|
|
style={{ backgroundColor: "#2ecc71" }} |
|
|
|
|
style={{backgroundColor: "#2ecc71"}} |
|
|
|
|
></div> |
|
|
|
|
<span className="text-sm text-[#2A2C3F] dark:text-[#EEE5E5]"> |
|
|
|
|
Chillimisala |
|
|
|
|
@ -446,15 +448,15 @@ export default function Expo() { |
|
|
|
|
</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] relative"> |
|
|
|
|
<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" /> |
|
|
|
|
<EyeClosed className="w-6 h-6 mr-2"/> |
|
|
|
|
) : ( |
|
|
|
|
<Eye className="w-6 h-6 mr-2" /> |
|
|
|
|
<Eye className="w-6 h-6 mr-2"/> |
|
|
|
|
)} |
|
|
|
|
|
|
|
|
|
{showDividers ? "Peida" : "Näita"} |
|
|
|
|
@ -476,5 +478,8 @@ export default function Expo() { |
|
|
|
|
)} |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<SectionDivider /> |
|
|
|
|
</div> |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|