제스쳐를 통한 룰렛 기능 구현 - 2023년 12월 20일 오전 10:00 (GMT+9)

gesture를 사용하기 위해서는 react-native-gesture-handler라이브러리가 필요하다

install

yarn add react-native-gesture-handler

Gesture라는 객체는 제스쳐를 만들 수 있는데 되게 다양한 종류의 제스쳐가 있다.

그 중 Pan 제스쳐를 사용해볼 예정인데, Pan 제스쳐는 드레그를 인식해서 그 움직임을 추적할 수 있다. 룰렛을 돌리려면 위에서 아래로 드레그하는 액션이 필요한데, 이에 알맞는 제스쳐 종류는 Pan이다.

usage

사용법은 간단하다.

import { GestureDetector, Gesture } from 'react-native-gesture-handler';

function App() {
  const pan = Gesture.Pan();

  return (
		<GestureHandlerRootView style={styles.container}>
	    <GestureDetector gesture={pan}>
	      <Animated.View />
	    </GestureDetector>
		</GestureDetector>
  );
}

Gesture.Pan()하면 Pan 제스쳐를 만들었다.

GestureHandlerRootView는 제스쳐와 가까운 곳에 위치해야하고, 일반 View와 같은 동작을 한다.

제스쳐를 감지하기 위해서는 <GestureDetector gesture={pan}> ... </GestureDetector>와 같이 감싸주면 이제 Pan 제스쳐를 감지할 수 있다.

Gesture Event

Gesture에 다양한 이벤트 종류들이 있는데 onBegin 이벤트는 손이 해당 GestureDetector 영역에 닿으면 발생하고 바로 onStart가 실행된다.

onBegin → onStart → onUpdate → onEnd → onFinalize 순으로 진행이된다.

const pan = Gesture.Pan().onUpdate((e) => {
    rotation.value = withSequence(
      withTiming(
        Math.abs(e.velocityY) / 7 + rotation.value,
        {
          duration: 500,
          easing: Easing.linear,
        },
        () => runOnJS(getCurrentColor)(500),
      ),

      withTiming(rotationAngle, {
        duration: ROTATION_TIME,
        easing: Easing.bezier(0.2, 0.8, 0.7, 1),
      }),
    );
  });

제스쳐가 활성화 되어있는 동안에 화면에서의 x 및 y 위치, 움직임의 x 및 y 속도가 포함된 이벤트 데이터를 가져온다.

withSequence는 애니메이션을 연속으로 실행할 수 있는 함수이고, withTiming은 duration에 맞는 애니메이션을 설정할 수 있다.

velocityY는 한 순간에 Y축을 따라 이동한 제스쳐의 속도를 의미하며, Math.abs로 감싼 이유는 한 방향으로만 움직이게 하기 위해서 절대값으로 변경해주었다. 절대값을 없애주면 양방향으로 움직일 수 있다.

그래서 위 애니메이션은 0.5초간 사용자의 제스쳐로 돌린 후 5초동안 빨라졌다가 느려지는 애니메이션이다.