일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 리액트네이티브
- clone coding
- 카트폴
- redux
- ReactNative
- selenium
- 데이터분석
- JavaScript
- 강화학습 기초
- coding
- React
- 사이드프로젝트
- 크롤링
- 머신러닝
- FirebaseV9
- App
- 정치인
- 클론코딩
- kaggle
- 앱개발
- 조코딩
- TeachagleMachine
- Instagrame clone
- Ros
- 강화학습
- python
- pandas
- 딥러닝
- expo
- 전국국밥
- Today
- Total
qcoding
[ReactNative_study_12]Animated 사용법 및 사용규칙 본문
* nomad coder React Native Master class 수강 하면서 정리하는 글
Animation 사용법
1) useRef랑 같이 사용하는 이유
--> UI=Component(state), 로 UI는 state가 변경될 때 component가 다시 렌더링 되게 된다. 이때 리렌더링 되면 값이 초기값으로 적용이 되게 되는데, useRef()를 쓰면 새롭게 렌더링 되지 않고 값이 유지 되게 된다. 애니메이션이 되고 원래 위치로 돌아가는 것을 방지하는 데 사용한다. 즉, 리렌더링 시 값이 초기화 되는 것을 막기 위해서 사용한다.
import React,{useState,useRef} from 'react'
import { Animated,TouchableOpacity,Easing } from 'react-native'
import styled from 'styled-components/native'
const Container=styled.View`
flex:1;
justify-content:center;
align-items:center;
`;
const Box=styled.View`
background-color:red;
width:200px;
height:200px;
`;
const AnimatedBox=Animated.createAnimatedComponent(Box);
const App = () => {
const [up, setUp] = useState(false)
// setUp을 변경하므로 component가 다시 리렌더링 될 때 초기화 되는 것을 막기위해서
// useRef를 사용한다.
const Y = useRef(new Animated.Value(0)).current;
const moveUp = () => {
Animated.timing(Y, {
toValue: up?-200:200,
useNativeDriver: true,
easing: Easing.circle,
}).start(()=>{
// start가 끝나고 callback함수를 정의할 수 있음
setUp((prev) => !prev)
});
};
console.log(up)
return (
<Container>
<TouchableOpacity style={{borderWidth:5,borderColor:"black", height:200}} onPress={moveUp}>
<AnimatedBox
style={{
transform: [{ translateY: Y }],
}}></AnimatedBox>
</TouchableOpacity>
</Container>
)
}
export default App
2) InterPolation --> 말 그대로 inputRange에 따른 outRange가 Interpolation 되서 return 되게 된다.
여기서 Input 과 Output은 array의 형태이며 동일한 length를 가져야 한다.
// Animation의 초기값을 설정한다.
const Y_POSITION = useRef(new Animated.Value(300)).current;
const moveUp = () => {
// timing animation을 적용할 value : Y_POSITION 와 option을 정한다.
// start내에 callback 함수를 등록할 수 있다.
Animated.timing(Y_POSITION, {
toValue: up?300:-300,
useNativeDriver: true,
duration: 1000
}).start(()=>{
setUp((prev) => !prev)
});
};
// 여기서는 Opacity 와 borderRadius 값을 outputRange로 받아서 사용하며,
// Y_POSITION에 따라서 각각 변하는 값을 Inperpolation 한다.
// Inperpolation은 Animated.Value에 쓸 수 있는 함수이다.
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],
});
// Interpolation은 단순히 숫자만 되는 것이 아니라
// 아래처럼 문자와 숫자가 같이있는 곳에도 사용할수 있다.
// 그러나 어떤것은 native driver에서 지원하지않기때문에
// useNativeDriver: false로 바꿔주어야 할 때도 있다.
const rotation = Y_POSITION.interpolate({
inputRange: [-300, 300],
outputRange: ["-360deg", "360deg"],
});
Y_POSITION.addListener(() => {
console.log("Y VALUE:", Y_POSITION);
console.log("opacity VALUE:", opacity);
console.log("borderRadius VALUE:", borderRadius);
});
return (
<Container>
<Pressable style={{borderWidth:5,borderColor:"black"}} onPress={moveUp}>
<AnimatedBox
style={{
borderRadius,
opacity,
transform: [{rotateY:rotation},{ translateY: Y_POSITION }],
}}></AnimatedBox>
</Pressable>
</Container>
)
3) XY좌표/ getTranslateTransform/ Animation Loop / Sequence
- XY좌표
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get("window");
// 화면 왼쪽 상단에서 시작하도록 초기값을 잡음
const POSITION = useRef(
new Animated.ValueXY({
x: -SCREEN_WIDTH / 2 + 100,
y: -SCREEN_HEIGHT / 2 + 100,
})
).current;
-getTranslateTransform : [{translateX: }, {translateY :}] 와 동일하게 한번에 배열로 받아주는 함수
<AnimatedBox
style={{
// X,Y 좌표를 각각 이동할 수 있게 설정하는 것
transform: [{ translateX: POSITION.x }, { translateY: POSITION.y }],
// 이 함수를 이용하면 위의 X,Y 좌표를 받오므로 아래와 같이 한번에 작성가능함
transform: [...POSITION.getTranslateTransform()],
}}
></AnimatedBox>
- Animation Loop / Sequence : Animation을 여러개 만들어서 이것을 sequence로 순서대로 실행하게 할 수 있다.
// 화면의 구석으로 이동시키는 각각의 애니메이션
const topLeft = Animated.timing(POSITION, {
toValue: {
x: -SCREEN_WIDTH / 2 + 100,
y: -SCREEN_HEIGHT / 2 + 100,
},
useNativeDriver: false,
});
const bottomLeft = Animated.timing(POSITION, {
toValue: {
x: -SCREEN_WIDTH / 2 + 100,
y: SCREEN_HEIGHT / 2 - 100,
},
useNativeDriver: false,
});
const bottomRight = Animated.timing(POSITION, {
toValue: {
x: SCREEN_WIDTH / 2 - 100,
y: SCREEN_HEIGHT / 2 - 100,
},
useNativeDriver: false,
});
const topRight = Animated.timing(POSITION, {
toValue: {
x: SCREEN_WIDTH / 2 - 100,
y: -SCREEN_HEIGHT / 2 + 100,
},
useNativeDriver: false,
});
// 여러 애니메이션을 sequnce로 연결해서 실행할 수 있다.
const moveUp = () => {
// loop를 쓰면 반복이 되고, sequnce안에 배열로 animation을 전달
// start()를 써주어야 시작이 됨
Animated.loop(
Animated.sequence([bottomLeft, bottomRight, topRight, topLeft])
).start();
};
Animated 사용의 규칙
1) value를 쓸 때에는 useState 등 을 이용하지 않고 Animated.Value()를 사용한다.
ex) const Y=new Animated.Value(0)
2) value에 절대값을 사용하지 않는다.
ex) let Y=new Animated.Value(0)
Y=20
// 위와같이 Animation에 사용되는 값을 절대값으로 넣지 않음
3) Animated 에서 사용되는 components는 정해져 있다.
< 사용가능한 components>
- Animated.Image
- Animated.ScrollView
- Animated.Text
- Animated.View
- Animated.FlatList
- Animated.SectionList
* 만일 새롭게 만든 component를 사용하려면 createAnimatedComponent 메서드를 사용해야 한다.
* styeld-component 사용 & createAnimatedComponent 를 사용하는 2가지 방법
1)
// TouchableOpacity를 불러와야함
import { Animated,TouchableOpacity} from 'react-native'
const Box=styled(Animated.createAnimatedComponent(TouchableOpacity))`
background-color:red;
width:200px;
height:200px;
`;
2)
import { Animated } from 'react-native'
const Box=styled.TouchableOpacity`
background-color:red;
width:200px;
height:200px;
`;
// 위에서 만든 Box를 가지고 Animatiton에서 사용될 Box를 새로만듦
const AnimatedBox=Animated.createAnimatedComponent(Box);
'ReactNative' 카테고리의 다른 글
[ReactNative_study_14] useContext , Realm SDK DB (0) | 2021.12.20 |
---|---|
[ReactNative_study_13]PanResponder (스크린 화면 터치감지) (0) | 2021.12.12 |
[ReactNative_Study_11]무한스크롤 구현 (Flat List & React query) (0) | 2021.12.06 |
[React_Native_Study_10]React query 사용하여 검색기능 활용 (0) | 2021.11.30 |
[ReactNative_Study_9]React_query (0) | 2021.11.28 |