createAnimatedComponent()
를 이용)// Problem
const Y = new Animated.Value(0);
// Resolve
const Y = useRef(new Animated.Value(0)).current;
const opacity = Y_POSITION.interpolate({
inputRange: [-300, 0, 300],
outputRange: [1, 0.5, 1],
});
const borderRadius = Y_POSITION.interpolate({
inputRange: [-300, 300],
outputRange: [100, 0],
});
Y_POSITION.addListener(() => console.log(opacity));
return (
<Container>
<Pressable onPress={moveUp}>
<AnimatedBox
style={{
borderRadius,
opacity,
transform: [{ translateY: Y_POSITION }],
}}
/>
</Pressable>
</Container>
);
}
const POSITION = useRef(
new Animated.ValueXY({
x: -SCREEN_WIDTH / 2 + 100,
y: -SCREEN_HEIGHT / 2 + 100,
})
).current;
const topLeft = Animated.timing(POSITION, {
toValue: {
x: -SCREEN_WIDTH / 2 + 100,
y: -SCREEN_HEIGHT / 2 + 100,
},
useNativeDriver: false,
});
const moveUp = () => {
Animated.loop(
Animated.sequence([bottomLeft, bottomRight, topRight, topLeft])
).start();
};
PanResponder
는 손가락의 제스쳐나 움직임을 감지할 수 있게 해줌onStartShouldSetPanResponder
을 true
로 줘야함onPanResponderMove
으로 받아와야 함...
const panResponder = useRef(
PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: (_, { dx, dy }) => {
POSITION.setValue({
x: dx,
y: dy,
});
},
})
).current;
return (
<Container>
<AnimatedBox
{...panResponder.panHandlers}
style={{
borderRadius,
backgroundColor: bgColor,
transform: [...POSITION.getTranslateTransform()],
}}
/>
</Container>
);
}
onPanResponderGrant
: 터치가 시작될 때 실행되는 핸들러onPanResponderMove
: 제스처가 이동하고 있을 때 실행되는 핸들러onPanResponderRelease
: 터치가 끝날 때 실행되는 핸들러const panResponder = useRef(
PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderGrant: () => {
POSITION.setOffset({
x: POSITION.x._value,
y: POSITION.y._value,
});
},
onPanResponderMove: (_, { dx, dy }) => {
POSITION.setValue({
x: dx,
y: dy,
});
},
onPanResponderRelease: () => {
POSITION.flattenOffset();
},
})
).current;
https://reactnative.dev/docs/animated
https://reactnative.dev/docs/panresponder