React/ReactThreeFiber

Interaction (Event)

최 수빈 2025. 3. 11. 00:35

 

Interaction (Event) in R3F

 

 

3D 인터랙티브 이벤트 처리하

 

인터랙티브 이벤트 : 사용자의 이벤트를 수신하는 방법

 

R3F는 컴포넌트의 콜백함수를 통해서 3D 객체와 상호작용을 추가하여 인터랙티브한 웹 경험을 구현

 

인터렉션(Interaction)

사용자가 3D 객체와 상호 작용하는 방식

  • 클릭
  • 드래그
  • 스크롤
  • 키보드 입력

Events and Interation

 

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),
      ];
};

호버 상태에서 객체의 위치와 회전을 부드럽게 변화

 

 

onClick

 

'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