Reanimated 라이브러리를 사용한 React Native 사용자 지정 진행률 표시기
21500 단어 reanimatedtutorialreactnative
이 자습서의 비디오 버전은 YouTube에서 사용할 수 있습니다.
github 또는 expo snack 에서 다음 템플릿부터 시작하겠습니다.
export const ProgressIndicator: FC<{
count?: number;
itemWidth?: number;
itemHeight?: number;
duration?: number;
itemsOffset?: number;
topScale?: number;
}> = ({
count = 8,
itemWidth = 16,
itemHeight = 4,
duration = 5000,
itemsOffset = 4,
topScale = 4,
}) => {
return (
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
height: itemHeight * topScale,
width: (itemWidth + itemsOffset) * count,
}}
>
{[...Array(count)].map((x, index) => (
<ProgressItem
key={`progressItem${index}`}
index={index}
width={itemWidth}
height={itemHeight}
count={count}
topScale={topScale}
/>
))}
</View>
);
};
export const ProgressItem: FC<{
index: number;
count: number;
width: number;
height: number;
topScale: number;
}> = ({ index, width, height, count, topScale }) => {
return (
<View
style={[
{
width,
height,
backgroundColor: "black",
},
]}
/>
);
};
따라서 기본적으로
ProgressIndicator
구성 요소 중 count
를 렌더링하는 스타일링 소품이 있는 ProgressItem
가 있습니다. ProgressItem
는 단순히 검은색 사각형입니다. 최종 결과를 얻기 위해 사각형의 Y축을 순서대로 확장합니다.먼저 애니메이션 값을 추가하고
react-native-reanimated
라이브러리의 타이밍 애니메이션 함수로 변경해야 합니다.export const ProgressIndicator = ({duration, ...props}) => {
const progress = useSharedValue(0);
useEffect(() => {
progress.value = withTiming(1, {
duration,
});
}, []);
// ...
};
우리는 shared value
progress
값을 0으로 생성했습니다. 그리고 duration
밀리초 안에 withTiming을 0에서 1로 변경하기 시작합니다.이제
progress
값을 ProgressItem
에 전달하고 Y축의 스케일을 애니메이트해 보겠습니다.// ...
<ProgressItem
// ...
progress={progress}
/>
// ...
애니메이션 보기에서 애니메이션 스타일을 사용합니다.
export const ProgressItem = ({ index, width, height, count, topScale, progress }) => {
const animatedStyle = useAnimatedStyle(() => {
const scaleY = interpolate(
progress.value,
[0, 1], // input progress value from 0 to 1
[1, topScale], // output scale from 1 to 4 (topScale = 4)
Extrapolation.CLAMP
);
return {
transform: [{ scaleY }],
};
});
return (
<Animated.View
style={[
{
width,
height,
backgroundColor: "black",
},
animatedStyle
]}
/>
);
};
기본적으로 우리가 interpolate scaleY 값을
duration
밀리초 동안 내부useAnimatedStyle에서 4로 조정했습니다.이제 모든 항목의 크기를 동시에 조정하는 대신 하나씩 수행해 보겠습니다. 이를 위해 항목 수에 대한 애니메이션 진행을 분할해야 합니다.
const scaleY = interpolate(
progress.value,
[index / count, (index + 1) / count],
[1, topScale],
Extrapolation.CLAMP
);
다음 단계는 다음 항목에 애니메이션을 적용하기 전에 축소하는 것입니다. 이 경우 각 항목에 대해 3개의 출력 포인트[1, 4, 1]가 필요합니다.
const scaleY = interpolate(
progress.value,
[index / count, (index + 1) / count, (index + 2) / count],
[1, topScale, 1],
Extrapolation.CLAMP
);
그리고 여기 있습니다
이제 웨이브를 더 부드럽게 만들어 봅시다. 다음 항목 애니메이션을 더 일찍 시작하겠습니다. 이를 위해 각 진행률 조각을 3으로 나눕니다.
const parts = 3;
const wholeCount = count * 3;
const scaleY = interpolate(
progress.value,
[index / wholeCount, (index + parts) / wholeCount, (index + 2 * parts) / wholeCount],
[1, topScale, 1],
Extrapolation.CLAMP
);
거의 우리가 원하는 것이지만 애니메이션이 우리보다 약간 일찍 완료되었습니다
duration
. 전체duration
를 사용하려면 마지막 인덱스에 대한 3포인트 값이 1이어야 합니다.(index + 2 * parts) / wholeCount = 1
// where
index = count - 1
// so
wholeCount = count - 1 + 2 * parts;
그 다음에
const parts = 3;
const wholeCount = count - 1 + 2 * parts;
const scaleY = interpolate(
progress.value,
[index / wholeCount, (index + parts) / wholeCount, (index + 2 * parts) / wholeCount],
[1, topScale, 1],
Extrapolation.CLAMP
);
엄청난! 거의 다 왔습니다. 우리의 애니메이션은 좋아 보이지만 이제 구성 요소 마운트 후 한 번만 재생됩니다. 이 문제를 해결하려면 withRepeat 애니메이션 기능을 사용하십시오. 그리고
withTiming
함수를 다음과 같이 래핑합니다.useEffect(() => {
progress.value = withRepeat(
withTiming(1, { duration }),
-1,
true
);
}, []);
첫 번째 인수는
withTiming
함수입니다. 두 번째는 반복 횟수가 음수이면 무한 루프가 됩니다. 세 번째는 reverse
매개변수로 애니메이션을 앞뒤로 재생합니다. 기본적으로 진행률 값을 0에서 1로 변경한 다음 1에서 0으로 변경하고 반복합니다. reverse
가 false인 경우 값을 0에서 1로 변경하고 뒤로 이동한 다음 다시 0에서 1로 변경합니다.그게 다야! 댓글로 어떻게 생각하는지 알려주시고 질문이 있으면 언제든지 물어보세요. 최종 코드는 snack 및 github에서 사용할 수 있습니다.
Reference
이 문제에 관하여(Reanimated 라이브러리를 사용한 React Native 사용자 지정 진행률 표시기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/dimaportenko/react-native-custom-progress-indicator-with-reanimated-library-46pf텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)