aboutsummaryrefslogtreecommitdiff
path: root/src/components/CameraController.tsx
blob: 99ca5229644169255ba3a456041c4b8605ae6587 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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";