[RN] Animation Basic

castellan·2021년 12월 20일
0

The rules of Animation

  • Animation 에 사용되는 변수를 state로 선언하지 않아야 함
  • Animation 에 사용되는 변수 값을 직접 변경하지 않아야 함
    ex) Y = 20;
  • 아무 component 나 Animated 할 수 없고 Animatable component로 만들어야 함 ( createAnimatedComponent() 를 이용)
    Tip) TouchableOpacity 에 직접 Animation 적용 하는 것은 지양해야 함

Animation and State

// Problem
const Y = new Animated.Value(0);

// Resolve
const Y = useRef(new Animated.Value(0)).current;

Interpolation

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

ValueXY

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

  • PanResponder 는 손가락의 제스쳐나 움직임을 감지할 수 있게 해줌
  • 제스쳐 인식을 시작하려면 onStartShouldSetPanRespondertrue로 줘야함
  • 제스쳐 움직임의 좌표를 얻으로면 onPanResponderMove 으로 받아와야 함
    (panHandlers 에는 제스처에 사용되는 많은 함수들이 포함되어 있음)
...
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>
  );
}

Offsets

  • 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

profile
Developer, Trader, Walker

0개의 댓글