react-native Webview 환경에서 화면이 이동될 때 노출되는 로딩 이미지를 애니메이션으로 구현.
나는 이미지 3개를 순차적으로 같이 노출 시키기 위해 zoom과 흐릿한 효과를 추가 했다.
애니메이션을 사용하기 위해 react-native-animatable 설치
npm install --save react-native-animatable
LoadingScreen.js
import React, {useEffect, useState} from 'react';
import {View, StyleSheet, Image} from 'react-native';
import * as Animatable from 'react-native-animatable';
/* 로딩이미지 */
const BlurryImage = ({source, delay}) => {
const [isImgLoaded, setIsImgLoaded] = useState(false);
useEffect(() => {
setTimeout(() => {
setIsImgLoaded(true);
}, delay); // 이미지가 나타나기 전 0.5초 동안 흐릿한 효과를 위해 딜레이 적용
}, []);
return (
<Animatable.View
style={[
styles.item,
styles.imageContainer,
{opacity: isImgLoaded ? 1 : 0},
]} // 초기에는 투명도를 0으로 설정하여 숨김
animation={{
from: {opacity: 0, scale: 0.7},
to: {opacity: isImgLoaded ? 1 : 0, scale: isImgLoaded ? 1 : 0.8},
}}
duration={2500}
delay={delay} // delay 속성 적용
iterationCount="infinite" // 애니메이션 반복 설정
useNativeDriver>
<Image source={source} style={styles.image} />
</Animatable.View>
);
};
const LoadingScreen = () => {
return (
<View style={styles.loadingWrap}>
<View style={styles.loading_n}>
<View style={styles.itemWrap}>
<BlurryImage source={require('/assets/ico_loading1.png')} delay={0} />
<BlurryImage
source={require('/assets/ico_loading2.png')}
delay={350}
/>
<BlurryImage
source={require('/assets/ico_loading3.png')}
delay={700}
/>
</View>
</View>
</View>
);
};
//로딩바 스타일
const styles = StyleSheet.create({
loadingWrap: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'rgba(255, 255, 255, 0.6)',
},
loading_n: {zIndex: 999},
itemWrap: {
position: 'relative',
alignItems: 'center',
justifyContent: 'center',
},
item: {position: 'absolute', alignItems: 'center', justifyContent: 'center'},
imageContainer: {alignItems: 'center', justifyContent: 'center'},
});
export default LoadingScreen;
Home.js
import LoadingScreen from '/screens/LoadingScreen';
...
function Home() {
const [isLoaded, setIsLoaded] = useState(false);
// 페이지 로딩 구분
onLoadProgress = event => {
if (event.nativeEvent.progress === 1) {
setIsLoaded(false);
} else {
setIsLoaded(true);
}
};
return (
<>
<SafeAreaView style={{flex: 1}}>
<ScrollView contentContainerStyle={{flex: 1}}>
<WebView
source={{uri: webviewUri}}
...
onLoadProgress={onLoadProgress}
/>
{isLoaded && (
/* 로딩화면 */
<LoadingScreen />
)}
</ScrollView>
</SafeAreaView>
</>
);
}
기존에는 onNavigationStateChange(IOS), onLoadProgress(Android)로 구분 해서 사용 했는데 어느 순간 IOS에서도 onNavigationStateChange가 먹지 않는 현상이 발생... 원인은 모르겠다
그래서 그냥 onLoadProgress로 통합했다.
'react-native' 카테고리의 다른 글
[RN] react-native-orientation 화면 고정 (0) | 2023.08.18 |
---|---|
[RN] react-native-pin-view PIN CODE 구현 (0) | 2023.08.11 |
[RN] react-native-vector-icons 사용하기 (0) | 2023.08.11 |
[RN] react-native 생체인증 구현, biometrics와 touch-id (1) | 2023.08.09 |
[RN] react-native-keychain 구현 (0) | 2023.08.09 |