Animated
Drawer Menu
- 서랍처럼 열고 닫을 수 있는 형태로 일반적인 메뉴 UI로 많이 사용됨
- UI 내용
- 햄버거 버튼이 있는 바깥영역
- 메뉴가 나왔을 때의 메뉴 영역
- 에니메이션 내용
- 메뉴가 열리고 닫히는 과정에서 메뉴가 자연스럽게 움직임
- 메뉴가 열리고 닫히는 과정에서 뒷배경의 컬러의 투명도가 변화
Collapse
- 클릭하면 아래로 펼쳐지고, 다시 누르면 접히는 UI
- 공지사항에서 많이 접하던 UI
Progress Bar
- 상태 값에 맞춰 변화하는 UI
- 다양한 방식으로 바리에이션을 줄 수 있는 UI
Skeleton
- 본격적인 데이터가 뜨기 전 나오는 애니메이션 화면
- 데이터가 뜨기 전 로딩시간이 체감적으로 감소
- 유저가 로딩시간을 짧게 느끼는 스켈레톤 규칙
- 맥박효과 보다는 웨이브효과
- 왼쪽에서 오른쪽으로 움직이는 효과
- 주의를 끄지 않을 만큼의 속도의 애니메이션
react-native-linear-gradient
1 2 3 4 5 6
<LinearGradient start={\{x: 0, y: 0}\} end={\{x: 1, y: 0}\} colors={['#ffffff00', '#ffffff90', '#ffffff00']}> <View style={\{width: 40, height: 100}\} /> </LinearGradient>
Snow Background
- 눈 아이콘을 100개 각각 애니메이션 컨트롤
- 랜덤한 x 좌표
- interpolate 기능으로 top 값을 변경 시키는 애니메이션
LayoutAnimation
LayoutAnimation 개념
- layoutanimation
- new Animated.Value 가 아닌 useState로 변하는 값을 감지해서 애니메이션 효과를 주는것
1 2 3 4
const animation = () => { LayoutAnimation,configureNext(...); setCount(value => value + 1); }
→ useState의 set함수와 함께 호출
android에서는 다음과 같은 초기세팅이 필요함
1 2 3 4 5 6 7
import {UIManager, Platform} from 'react-native'; if (Platform.OS === 'android') { if (UIManager.setLayoutAnimationEnabledExperimental) { UIManager.setLayoutAnimationEnabledExperimental(true); } }
- useState로 컴포넌트가 create, update, delete될 때 작동
- LayoutAnimation은 미리 Native로 코드를 전달해놓고, 상태가 변화할 때마다 애니메이션이 발생시키는 방식
LayoutAnimation 호출 시, 행동할 setState를 같이 핸들링 해줌으로써, 해당 state에 애니메이션을 반영할 수 있음
1 2 3 4 5 6 7 8 9 10 11 12
LayoutAnimation.configureNext( { duration: 300, // type:easeIn, spring, linear // property:opacity, scaleX, scaleY, scaleXY create: {type: 'easeIn', property: 'opacity'}, update: {type: 'spring', property: 'scaleX', springDamping: 0.3}, delete: {type: 'linear', property: 'scaleXY'}, }, () => console.log('end'), () => console.log('fail'), );
다음과 같은 미리 정의된 Presets을 사용가능
1
LayoutAnimation.configureNext(LayoutAnimation.Presets.linear);
Page Header
- 큰 영역의 header, 작은 영역의 header 두 부분의 ui 구현
- ScrollView 컴포넌트로 스크롤이 되는 뷰를 만들것
- ScrollView 컴포넌트의 onLayout 메소드를 이용해 스크롤 높이를 측정하여 일정 높이가 되면 animation 작동
- LayoutAnimation preset을 이용
PanResponder
- 소개
- gesture를 감지해서 response로 터치상태를 콜백해주는 api
- 터치로 핸들링하는 컴포넌트는 많지만, 터치액션을 세세하게 인식해서 콜백해주는 경우는 많지 않음
- ex(ScrollView, Flatlist,SectionList)
- PanResponder는 x,y터치좌표, 누적이동거리, 제스쳐의 속도, 현재 화면에 터치 갯수 등의 정보를 콜백으로 던져줌
- gestureState
- “dx”, “dy” : 터치 시작 후 누적거리, 음수는 왼쪽이나 하단으로이동이며 양수는 오른쪽이나 상단으로 이동했다는 것을 알 수 있음
- “moveX”, “moveY” : 제일 최신에 찍힌 좌표이며 절대값으로 나타냄
- “numberActiveTouches” : 액정에 터치 갯수
- “stateID” : 터치 아이디, 터치가 움직이면 값도 변화함
- “vx”, “vy” : 제스쳐 현재 속도
- “x0”, “y0” : 이동 직전의 좌표, 제스쳐 시작할 때의 메소드에만 찍힘
- Animated를 주로 같이 사용함
기능
- 컴포넌트에 PanResponder 심기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
import React from 'react'; import {PanResponder, Text, View} from 'react-native'; export default () => { const panResponder = PanResponder.create({ // permission method onStartShouldSetPanResponder: () => true, onMoveShouldSetPanResponder: () => true, //움직이는 메소드를 사용할지 // response method onPanResponderGrant: () => {}, //터치응답이 잘 되는지 onPanResponderReject: () => {}, //터치가 잘 안됐을때 response가 옴 // handler method onPanResponderStart: () => {}, //터치액션이 start됐을 때 작동 onPanResponderMove: () => {}, //터치가 제스쳐로 전환될 때 response onPanResponderEnd: () => {}, //터치가 끝났을 때 onPanResponderRelease: () => {}, //터치 액션이 최후로 끝났을 때 }); return ( <View // 컴포넌트에 PanResponder 심기 {...panResponder.panHandlers} style={\{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#ffa100', }\}> <Text>Panresponder Intro</Text> </View> ); };
공던지기
- 공을 터치방향과 속도에 맞추어 던지기
Modal UI
- 저장하기, 좋아요,삭제하기, 닫기 등의 여러개의 선택지가 있는 menu modal UI
- react-native-iphone-x-helper이용
- show-hide될 때 timing 인터렉션 연결
- modal 부분의 (내리는)제스쳐 기반 인터렉션 구현
Banner Slider
- 4개의 영역이 나란하게 화면을 차지
- 하단의 네비게이션 버튼을 누르면 각 영역으로 이동
- 왼쪽 혹은 오른쪽으로 제스쳐를 하면, 슬라이딩 애니메이션 작동
한번에 여러개의 애니메이션이 작동되지 않도록 트리거도 넣기
- useRef로 애니메이션 시작시 false값을 주고, 애니메이션이 끝난후 start()구문 안에 작성한 내용처럼 다시 true로 바꿔줌
- padingRef값이 true여야 애니메이션이 실행됨
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
const pandingRef = useRef(true); if (toRight && pandingRef.current) { pandingRef.current = false; setFocus(focus + 1); Animated.timing(bannerAnim, { toValue: -(focus + 1) * width, duration: 500, useNativeDriver: true, }).start(({finished}) => { if (finished) { pandingRef.current = true; } }); }
Dimensions 활용
- 모바일 화면의 영역크기를 알 수 있음
1 2 3
import {Dimensions} from 'react-native'; const {width} = Dimensions.get('window');
- 빈 배열로 따로 컴포넌트 만들지 않아도 여러개 생성 가능함.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<View style={\{position: 'absolute', left: 0, flexDirection: 'row'}\}> {[...Array(4)].map((value, index) => ( <View key={index} style={\{ width, height: width, backgroundColor: '#ffa100', justifyContent: 'center', alignItems: 'center', }\}> <Text style={\{fontSize: 50, color: '#fff'}\}>{index}</Text> </View> ))} </View>
Font Slider
- 1~4단계의 폰트가 있고, 단계마다 폰트 스타일 값을 가지는 ui
- 다른 단계까지는 클릭으로 이동
- 각 단계까지 슬라이더가 자연스럽게 이동하는 모습구현
- 드래그 엔 드롭 제스쳐로 상태를 바꿀 수 있게 작업
유튜브뮤직 클론 코딩
결과 화면
정리
- 그라데이션 배경 react-native-linear-gradient
<Image source={\{uri: '[https://picsum.photos/300](https://picsum.photos/300)'}\} />
위 링크는 숫자(300)너비만큼의 랜덤 이미지를 뽑아줌
@faker-js/faker
fakerjs 사이트에서 원하는 값을 골라서 사용할 수 있음
- scroll에 따른 애니메이션 ScrollView에서 다음 3가지 옵션들을 활용하여 y좌표 움직임을 확인할 수 있음
1 2 3 4 5 6 7 8 9 10 11
<ScrollView scrollEventThrottle={1} onScrollBeginDrag={e => { console.log(e.nativeEvent.contentOffset.y); }\} onScroll={e => { console.log(e.nativeEvent.contentOffset.y); }\} onScrollEndDrag={e => { console.log(e.nativeEvent.contentOffset.y); }\}>
모바일페이 클론 코딩
결과 화면
정리
- 카드를 옆으로 넘기는 애니메이션
- 카드를 펼치고 카드를 여는 애니메이션