aboutsummaryrefslogtreecommitdiff
path: root/src/components/Scene.tsx
blob: fd70708394355b135b945907ba48cfa8beb0114e (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
75
76
77
78
import React, { useState, useCallback } from "react";
import { Canvas } from "@react-three/fiber";
import { OrbitControls, Grid } from "@react-three/drei";
import { useStore } from "../store/store.ts";
import { Model3DComponent } from "./Model3D.tsx";
import { CameraController } from "./CameraController.tsx";
import { SceneBackground } from "./SceneBackground.tsx";

interface SceneContentProps {
  autoRotate: boolean;
}

const SceneContentInner: React.FC<SceneContentProps> = ({ autoRotate }) => {
  const models = useStore((state) => state.models);

  return (
    <>
      <SceneBackground />
      <CameraController />
      <OrbitControls
        enableDamping
        dampingFactor={0.05}
        minDistance={20}
        maxDistance={500}
        autoRotate={autoRotate}
        autoRotateSpeed={4}
        enableRotate={!autoRotate}
      />

      <Grid
        position={[0, 0, 0]}
        infiniteGrid
        cellSize={10}
        cellThickness={0.5}
        cellColor="#6f6f6f"
        sectionSize={50}
        sectionThickness={1}
        sectionColor="#9d4b4b"
        fadeDistance={500}
        fadeStrength={1}
      />

      {models.map((model) => (
        <Model3DComponent key={model.id} model={model} />
      ))}
    </>
  );
};

const SceneContent = React.memo(SceneContentInner);
SceneContent.displayName = "SceneContent";

export const Scene: React.FC = () => {
  const selectModel = useStore((state) => state.selectModel);
  const [autoRotate, setAutoRotate] = useState(false);

  const handlePointerMissed = useCallback(() => {
    selectModel(null);
  }, [selectModel]);

  const handleToggleAutoRotate = useCallback(() => {
    setAutoRotate((prev) => !prev);
  }, []);

  return (
    <div className="scene-container">
      <Canvas onPointerMissed={handlePointerMissed}>
        <SceneContent autoRotate={autoRotate} />
      </Canvas>
      <button
        className={`spin-button ${autoRotate ? "active" : ""}`}
        onClick={handleToggleAutoRotate}
      >
        {autoRotate ? "Stop" : "Spin"}
      </button>
    </div>
  );
};