원리와 예제를 통한 react-native-reanimated2 입문

Lee young-jun
4 min readSep 29, 2023

--

이 글은 올룰로 Confluence에 작성했던 글을 보관용으로 재포스팅 하는 것이다.

react-native-reanimated1

  • Functional Component 형의 코딩만 지원
  • View Property type number/string만 지원

Worklet

UI Thread에서 JS Thread에 접근 가능한 함수 지정하는 키워드

function workletFunc() {
'worklet';

//...
}
  • View Property를 변경하거나 이벤트에 반응하는 callback

SharedValue

JS / UI Thread 모두에서 접근가능한 변수

UI Thread에서 읽는데 동기로 변경

JS Thread에서는 동기로 변경됨

  • 다음 Rendering에 적용됨

예제

import {useSharedValue} from 'react-native-reanimated';

// in component
...
const sharedValue = useSharedValue(0);
console.log(sharedValue.value);

Example

Pan Gesture로 View가 손가락을 따라 움직이는 애니메이션 구현

// in component

const translateX = useSharedValue(0);
const translateY = useSharedValue(0);

const onGestureEventHandler = useAnimatedGestureHandler<
PanGestureHandlerGestureEvent,
{translateX: number; translateY: number}
>({
onStart: (_, ctx) => {
ctx.translateX = translateX.value;
ctx.translateY = translateY.value;
},
onActive: (e, ctx) => {
translateX.value = clamp(
ctx.translateX + e.translationX,
0,
widthLimit - BOX_WIDTH,
);

translateY.value = clamp(
ctx.translateY + e.translationY,
0,
heightLimit - BOX_HEIGHT,
);
},
onEnd: (e, _) => {
translateX.value = withBouncing(
withDecay({velocity: e.velocityX}),
0,
widthLimit - BOX_WIDTH,
);

translateY.value = withBouncing(
withDecay({velocity: e.velocityY}),
0,
heightLimit - BOX_HEIGHT,
);
},
});

const animStyle = useAnimatedStyle(() => {
return {
transform: [
{translateX: translateX.value},
{translateY: translateY.value},
],
};
});

return (
<View>
<PanGestureHandler onGestureEvent={onGestureEventHandler}>
<Animated.View style={animStyle}>
<DragableView width={VIEW_WIDTH} height={VIEW_HEIGHT} />
</Animated.View>
</PanGestureHandler>
</View>
);

원문

--

--

No responses yet