diff options
Diffstat (limited to 'src/components/Scene.tsx')
| -rw-r--r-- | src/components/Scene.tsx | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/components/Scene.tsx b/src/components/Scene.tsx new file mode 100644 index 0000000..fd70708 --- /dev/null +++ b/src/components/Scene.tsx @@ -0,0 +1,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> + ); +}; |