Interaction (Event) in R3F
3D 인터랙티브 이벤트 처리하기
인터랙티브 이벤트 : 사용자의 이벤트를 수신하는 방법
R3F는 컴포넌트의 콜백함수를 통해서 3D 객체와 상호작용을 추가하여 인터랙티브한 웹 경험을 구현
인터렉션(Interaction)
사용자가 3D 객체와 상호 작용하는 방식
- 클릭
- 드래그
- 스크롤
- 키보드 입력
Events and Interaction - React Three Fiber
Let's make our meshes react to user input.
r3f.docs.pmnd.rs
@react-spring/three
설치
npm install three @react-spring/three
@react-spring/three@9.7.5 React 16~18까지 지원
@react-three/fiber@9.1.0 React 19 요구 React 18 x
@react-three/drei@10.0.4 React 19 요구 React 18 x
버전 충돌 계속 남ㅡㅡ
React19 작년 3월에 릴리즈 돼서 나름 괜찮다고 생각했는데 ;ㅅ; .. 히잉
rm -rf node_modules package-lock.json
rm -rf ~/.npm
로컬 npm 캐시까지 삭제 안해주니까 계속 충돌 나길래 싸그리 삭제해줌
npm cache clean --force
npm install react@19 react-dom@18
react, react-dom 18버전으로 낮춤
npm install @react-three/fiber@8.12.1 @react-three/drei@9.60.0
@react-three/fiber, @react-three/drei도 React 18 호환 버전으로 다운그레이드
npm install @react-spring/three@9.6.0
@react-spring/three React 18 호환 버전으로 설치
*npm run dev하니까 @react-three/drei 다운그레이드 했더니 Three.js랑 충돌남
npm install three@0.156.1
React-Spring을 활용한 애니메이션 적용
import { useSpring, animated } from "@react-spring/three";
const CardComponent = ({ position, rotationY, rotationZ, imageUrl }) => {
const [hovered, setHovered] = useState(false);
const texture = useLoader(THREE.TextureLoader, imageUrl);
texture.colorSpace = THREE.DisplayP3ColorSpace;
const materials = createMaterials(texture);
const props = useSpring({
scale: hovered ? [1.1, 1.1, 1] : [1, 1, 1],
position: calculatePosition(position, hovered),
rotation: calculateRotation(rotationY, rotationZ, hovered),
config: { mass: 5, tension: 400, friction: 100 },
});
return (
<animated.mesh
castShadow
receiveShadow
onPointerEnter={(e) => {
e.stopPropagation();
setHovered(true);
}}
onPointerLeave={(e) => {
e.stopPropagation();
setHovered(false);
}}
{...props}
material={materials}
>
<boxGeometry args={[1, 1.6, 0.01]} />
</animated.mesh>
);
};
- Mass(질량) : 값이 클수록 더 무겁게 움직이며, 느리고 점진적인 변화를 보임
- Tension(장력) : 값이 클수록 빠르게 반응하며 강한 애니메이션 효과가 나타남
- Friction (마찰) : 마찰이 클수록 애니메이션이 더 빠르게 멈추고, 낮을수록 부드럽게 멈춤
3D 객체 이벤트 처리
R3F에서의 이벤트 리스너
onClick
onPointerOver
onPointerOut
등
기본적인 onClick
이벤트 추가
const onMeshClick = (e) => {
console.log(e);
};
<mesh onClick={onMeshClick} />
클릭 이벤트가 콘솔에 출력됨
객체 크기 변경 이벤트
const onClickEvent = (e) => {
e.object.scale.set(2, 2, 2);
};
이벤트가 실행되면 클릭한 객체의 크기가 두 배로 증가
이벤트 전파 방지
클릭 시 다른 객체에도 영향을 주지 않도록 하려면 stopPropagation()
을 추가
const onClickEvent = (e) => {
e.stopPropagation();
e.object.scale.set(2, 2, 2);
};
React-Spring을 활용한 부드러운 애니메이션 적용
const props = useSpring({
scale: hovered ? [1.1, 1.1, 1] : [1, 1, 1],
position: calculatePosition(position, hovered),
rotation: calculateRotation(rotationY, rotationZ, hovered),
config: { mass: 5, tension: 400, friction: 100 },
});
useSpring
을 사용하여 마우스를 올렸을 때(hovered
) 객체가 부드럽게 확대
Hover 이벤트 추가
onPointerEnter={(e) => {
e.stopPropagation();
setHovered(true);
}}
onPointerLeave={(e) => {
e.stopPropagation();
setHovered(false);
}}
마우스를 올리면 hovered
상태가 true
로 변경되며, 크기가 커지고 위치가 조정
위치 및 회전 조정 함수
const calculatePosition = (position, hovered) => {
return hovered ? [position[0], position[1] + 0.5, position[2]] : position;
};
const adjustRotation = (rotation, adjustment) => {
return rotation === 0 ? rotation : rotation + adjustment;
};
const calculateRotation = (rotationY, rotationZ, hovered) => {
return hovered
? [
0,
THREE.MathUtils.degToRad(adjustRotation(rotationY, 5)),
THREE.MathUtils.degToRad(adjustRotation(rotationZ, rotationZ > 0 ? -5 : 5)),
]
: [
0,
THREE.MathUtils.degToRad(rotationY),
THREE.MathUtils.degToRad(rotationZ),
];
};
호버 상태에서 객체의 위치와 회전을 부드럽게 변화
'React > ReactThreeFiber' 카테고리의 다른 글
CRA(Create React App) (0) | 2025.03.11 |
---|---|
React (1) | 2025.03.11 |
3D 공간에서의 시야 조정 : 카메라 이동과 시점 변경 (0) | 2025.03.10 |
Light & Shadow (0) | 2025.03.07 |
Obj 3D & Transform (0) | 2025.03.06 |