Preview

투표한사람들비율에맞게애니메이션적용.gif

이전에 투표 기능 개발 했을 때는 애니메이션 없이 그냥 비율에 맞게 색상만 넣어주었다.

코드 리뷰 받으면서 시간 되면 애니메이션 적용도 해달라는 요청이 있어서 적용해보려고 한다.

Install

우선 React-Native reanimated 라이브러리를 사용해서 진행하기에 해당 라이브러리가 설치 되어있어야 한다.

yarn add react-native-reanimated

Usage

애니메이션이 동작하기 위해서는 useSharedValue()로 선언한 변수의 값이 변경이 되어야 원하는 애니메이션을 적용시킬 수 있다.

따라서 비율에 맞게 색상이 차오르는 애니메이션을 적용하기 위해서는 width 값을 useSharedValue로 선언해주면 된다.

import Animated, {
  useSharedValue,
  withTiming,
  Easing,
} from 'react-native-reanimated';

const VoteForm = ({ navigation, route }) => {
	...
	const width = useSharedValue(0);
	...
}

변수 선언이 되었으면 해당 값을 변경시켜줘야 하는데, 투표하기 클릭했을 때 width의 값을 변경시켜주면 된다.

주의해야할 점은 인라인스타일로 width 값을 변경시키면 안된다.

따라서 투표 항목마다의 width를 변경시키기 위해 ActiveItemBar라는 커스텀 컴포넌트를 만들어준 뒤 해당 컴포넌트안에 useSharedValue를 다시 선언해줬다.

그러면 각 투표 항목마다 useSharedValue가 생성되어 독립적으로 값을 변경시킬 수 있다.

// 애니메이션 적용한 투표 항목 컴포넌트
const ActiveItemBar = (props) => {
  const { ratio } = props;
  const width = useSharedValue('0%');
	(() => {
      width.value = withTiming(`${ratio}%`, {
        duration: 500,
        easing: Easing.linear,
      });
    })();
  return (
    <Animated.View
      style={{
        backgroundColor: voteTheme.voteSubmitBtn,
        position: 'absolute',
        width: width,
        height: '100%',
        borderRadius: 11,
      }}
    ></Animated.View>
  );
};

const VoteForm = ({ navigation, route }) => {
	...
	return (
		<View style={{ flex: 1, gap: 8, marginTop: 16 }}>
          {data.vote?.map((item, index) => (
            ...
              {isVote && (
                <ActiveItemBar
                  ratio={
                    (VOTER.filter((v) => v.vote === index).length / VOTER.length) * 100
                  }
                />
              )}
						...
		</View>
}

투표한 항목의 비율을 ratio라는 props로 넘겨주었다.

width는 useSharedValue(’0%’)로 선언해주고, 넘겨 받은 ratio로 값을 변경시켜주면된다.