Edit Mode (편집 모드) 구현
1. GUI 추가 : 사용자가 모드를 변경할 수 있도록 Canvas 위에 버튼 추가
2. 상태 관리 : EditMode를 관리하는 상태 관리 시스템 구축 (React Context API 활용)
상태 관리 (EditContext) 설정
context 폴더를 만들고 EditContext.jsx 파일 추가
EditContext.jsx
import { createContext, useState } from "react";
export const EditContext = createContext(); // createContext 함수를 사용, EditContext 생성
export const EditProvider = ({ children }) => {
const [isEditMode, setEditMode] = useState(false);
return (
<EditContext.Provider value={{ isEditMode, setEditMode }}>
{children}
</EditContext.Provider>
);
};
isEditMode: 편집 모드 여부를 저장하는 상태
setEditMode: Edit Mode를 켜고 끄는 함수
App에 EditProvider 적용
App.jsx에서 Canvas를 EditProvider로 감싸 전역 상태를 관리
→ Environments 컴포넌트 안에서 useContext를 사용해 EditContext에 접근 가능
App.jsx
import { Canvas } from "@react-three/fiber";
import "./App.css";
import { Environments } from "./components/Environments";
import { EditProvider } from "./context/EditContext";
import { Overlay } from "./components/overlay/Overlay";
function App() {
return (
<EditProvider>
<Canvas camera={{ position: [0, 0, 500] }}>
<Environments />
</Canvas>
<Overlay />
</EditProvider>
);
}
export default App;
EditProvider를 추가하여 EditContext의 상태를 Canvas 및 UI에서 사용 가능하도록 설정
Edit Mode UI 구현
icons 폴더 생성, icons 파일 추가
components/overlay/Overlay.jsx 파일 생성 후 버튼 추가
Overlay.jsx
import { useContext } from "react";
import { EditIcon } from "../icons/EditIcon";
import { EditContext } from "../../context/EditContext";
export const Overlay = () => {
const { setEditMode } = useContext(EditContext);
return (
<div className="overlay">
<EditIcon onClick={() => setEditMode((prev) => !prev)} />
</div>
);
};
EditIcon을 클릭하면 Edit Mode 활성화/비활성화
Grid Helper 추가
isEditMode가 true일 때만 gridHelper를 보여줌
Environments.jsx
import { OrbitControls } from "@react-three/drei";
import { Animal } from "./Animal";
import { ZooMap } from "./ZooMap";
import { Dino } from "./Dino";
import { Suspense, useContext } from "react";
import { Physics, RigidBody } from "@react-three/rapier";
import { EditContext } from "../context/EditContext";
import { useFrame, useThree } from "@react-three/fiber";
const START_Y = 20;
export const Environments = () => {
const { isEditMode } = useContext(EditContext);
const { camera } = useThree();
useFrame(() => {
if (isEditMode) {
camera.position.set(0, 500, 0);
}
});
return (
<>
{isEditMode && <gridHelper args={[500, 50]} position={[0, START_Y, 0]} />}
<ambientLight intensity={4} />
<directionalLight intensity={4} position={[3, 3, 3]} />
<OrbitControls />
<Suspense>
<Physics>
<RigidBody type="fixed" colliders={"trimesh"}>
<ZooMap />
</RigidBody>
<RigidBody lockRotations colliders={"hull"}>
<Animal name={"Alpaca"} position={[-15, START_Y, 0]} />
</RigidBody>
<RigidBody enabledRotations={[false, false, false]} colliders={"hull"}>
<Dino name={"Triceratops"} position={[10, START_Y, 0]} />
</RigidBody>
</Physics>
</Suspense>
</>
);
};
useFrame을 사용해 Edit Mode일 때 카메라를 위에서 내려다보도록 변경
gridHelper를 추가하여 객체 배치가 용이하도록 설정
Edit Mode 스타일 적용
App.css
html,
body,
#root {
margin: 0;
height: 100%;
width: 100%;
}
.overlay {
width: max-content;
height: 100%;
display: flex;
flex-direction: column;
padding: 24px;
position: absolute;
top: 0;
right: 100px;
z-index: 99;
justify-content: center;
gap: 16px;
box-sizing: border-box;
}
overlay를 사용해 Edit Mode 버튼을 화면 우측 배치
✔️ Edit Mode를 활성화하면 gridHelper 표시
✔️ Edit Mode 버튼을 클릭하면 모드가 토글
✔️ Edit Mode일 때 카메라가 위에서 내려다보도록 조정
'React > ReactThreeFiber' 카테고리의 다른 글
Edit Mode 구현 (3) - Object 회전 및 localStorage 저장 기능 추가 (0) | 2025.03.15 |
---|---|
Edit Mode 구현 (2) - 상태 관리 내 데이터 추가, 컴포넌트 물리엔진 적용, Edit Mode에서의 Object 이동, UI 크기 조정과 시각화 개선 (0) | 2025.03.15 |
물리 엔진 추가하기 (0) | 2025.03.14 |
오브젝트 위치 조정 및 애니메이션 적용 (0) | 2025.03.14 |
3D 오브젝트 불러오기 (0) | 2025.03.14 |