import { useRef, useState, type ComponentRef } from "react"; import { Canvas, useFrame, useThree, type ThreeEvent, useLoader, } from "@react-three/fiber"; import { OrbitControls } from "@react-three/drei"; import { FBXLoader } from "three/examples/jsm/Addons.js"; import { Vector3 } from "three"; import "./App.css"; const Room = () => { const controls = useRef>(null); const room = useLoader(FBXLoader, "/room.fbx"); const [focus, setFocus] = useState(null); const cameraPosition = useRef(null); const cameraTarget = useRef(new Vector3(0, 1, 0)); const { camera } = useThree(); useFrame(() => { if (!controls.current) return; if (cameraPosition.current) { camera.position.lerp(cameraPosition.current, 0.09); if (camera.position.distanceTo(cameraPosition.current) < 0.012) { if (!focus) { controls.current.enableZoom = true; controls.current.enableRotate = true; } cameraPosition.current = null; } } controls.current.target.lerp(cameraTarget.current, 0.1); }); const handleClick = (e: ThreeEvent) => { if (!controls.current) return; e.stopPropagation(); if (e.object.name.includes("Poster") && e.object.name !== focus) { const objectPos = new Vector3(); const objectDir = new Vector3(); e.object.getWorldPosition(objectPos); e.object.getWorldDirection(objectDir); cameraPosition.current = objectPos .clone() .add(objectDir.multiplyScalar(-0.65)); cameraTarget.current = objectPos; controls.current.enableZoom = false; controls.current.enableRotate = false; setFocus(e.object.name); } else if (focus) { cameraPosition.current = new Vector3(3, 3, -3); cameraTarget.current = new Vector3(0, 1, 0); setFocus(null); } controls.current.update(); }; return ( <> ); }; export default function App() { return ( ); }