diff options
Diffstat (limited to 'src/components/CameraController.tsx')
| -rw-r--r-- | src/components/CameraController.tsx | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/components/CameraController.tsx b/src/components/CameraController.tsx new file mode 100644 index 0000000..99ca522 --- /dev/null +++ b/src/components/CameraController.tsx @@ -0,0 +1,74 @@ +import React, { useRef, useEffect } from "react"; +import { useThree } from "@react-three/fiber"; +import { PerspectiveCamera, OrthographicCamera } from "@react-three/drei"; +import * as THREE from "three"; +import { useStore } from "../store/store.ts"; + +const CameraControllerInner: React.FC = () => { + const cameraView = useStore((state) => state.cameraView); + const { set, size } = useThree(); + const perspectiveRef = useRef<THREE.PerspectiveCamera>(null); + const orthoRef = useRef<THREE.OrthographicCamera>(null); + + useEffect(() => { + if (cameraView === "perspective") { + if (perspectiveRef.current) { + set({ camera: perspectiveRef.current }); + } + return; + } + + if (orthoRef.current) { + const camera = orthoRef.current; + const aspect = size.width / size.height; + const frustum = 150; + + camera.left = -frustum * aspect; + camera.right = frustum * aspect; + camera.top = frustum; + camera.bottom = -frustum; + camera.near = 0.1; + camera.far = 2000; + + switch (cameraView) { + case "ortho-top": + camera.position.set(0, 500, 0); + camera.lookAt(0, 0, 0); + break; + case "ortho-front": + camera.position.set(0, 50, -500); + camera.lookAt(0, 50, 0); + break; + case "ortho-side": + camera.position.set(-500, 50, 0); + camera.lookAt(0, 50, 0); + break; + } + + camera.updateProjectionMatrix(); + set({ camera: camera }); + } + }, [cameraView, set, size]); + + return ( + <> + <PerspectiveCamera + ref={perspectiveRef} + makeDefault={cameraView === "perspective"} + position={[100, 80, 100]} + fov={60} + far={2000} + /> + <OrthographicCamera + ref={orthoRef} + makeDefault={cameraView !== "perspective"} + position={[0, 500, 0]} + zoom={5} + far={2000} + /> + </> + ); +}; + +export const CameraController = React.memo(CameraControllerInner); +CameraController.displayName = "CameraController"; |