aboutsummaryrefslogtreecommitdiff
path: root/src/components/CameraController.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/CameraController.tsx')
-rw-r--r--src/components/CameraController.tsx74
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";