[React Native] Animation
2021. 1. 4. 01:05ㆍReact/React Native
1. XY Animation
1) 기본
import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import AnimOne from './src/Animation01'
class App extends Component {
render() {
return (
<View style={styles.container}>
<AnimOne/>
</View>
)
}
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFF'
}
});
export default App;
import React, { Component } from 'react';
import { View, Text, StyleSheet, Animated } from 'react-native';
class AnimOne extends Component {
constructor() {
super();
this.mySquare = new Animated.ValueXY(0, 0);
}
componentDidMount() {
Animated.spring(this.mySquare, {
toValue: {x:50, y: 300}
}).start();
}
render() {
return (
<Animated.View
style={this.mySquare.getLayout()}
// style={{
// left: this.mySquare.x,
// top: this.mySquare.y
// }}
>
<View style={styles.square}>
</View>
</Animated.View>
)
}
};
const styles = StyleSheet.create({
square: {
width: 100,
height: 100,
backgroundColor: 'skyblue'
}
});
export default AnimOne;
코드 | 설명 |
componentDidMount() | render 함수 이후 가장 나중에 실행되는 함수 |
2) 응용
다양한 효과는 공식 문서(reactnative.dev/docs/animated#configuring-animations)에서 확인할 수 있다.
import { View, Text, StyleSheet, Animated, Easing } from 'react-native';
...
componentDidMount() {
Animated.timing(this.mySquare, {
toValue: {x:50, y: 300},
duration: 2000, // 2초
delay: 1500, // 1.5 초
easing: Easing.bounce
}).start();
}
...
3) 버튼
버튼을 클릭했을 때, 애니매이션이 동작하도록 설정할 수 있다.
import React, { Component } from 'react';
import { View, Text, StyleSheet, Animated, Easing, Button } from 'react-native';
class AnimOne extends Component {
constructor() {
super();
this.state = {
mySquare: new Animated.ValueXY(0, 0)
}
}
runAnimation = () => {
Animated.timing(this.state.mySquare, {
toValue: {x:50, y: 300},
duration: 2000, // 2초
delay: 1500, // 1.5 초
easing: Easing.bounce
}).start();
}
render() {
return (
<View>
<Animated.View
style={this.state.mySquare.getLayout()}
>
<View style={styles.square}>
</View>
</Animated.View>
<Button
title="Animation Start"
onPress={this.runAnimation}
/>
</View>
)
}
};
const styles = StyleSheet.create({
square: {
width: 100,
height: 100,
backgroundColor: 'skyblue'
}
});
export default AnimOne;
2. 그 외 Animation
1) 투명도
투명도는 0(투명)에서 1(불투명)의 값을 가진다. 투명해지는 소스는 다음과 같다.
import React, { Component } from 'react';
import { View, Text, StyleSheet, Animated, Easing, Button } from 'react-native';
class AnimOne extends Component {
constructor() {
super();
this.state = {
mySquare: new Animated.Value(1)
}
}
runAnimation = () => {
Animated.timing(this.state.mySquare, {
toValue: 0,
duration: 2000, // 2초
delay: 1500, // 1.5 초
}).start();
}
render() {
return (
<View>
<Animated.View
// style={this.state.mySquare.getLayout()}
style={{
opacity: this.state.mySquare
}}
>
<View style={styles.square}>
</View>
</Animated.View>
<Button
title="Animation Start"
onPress={this.runAnimation}
/>
</View>
)
}
};
const styles = StyleSheet.create({
square: {
width: 100,
height: 100,
backgroundColor: 'skyblue'
}
});
export default AnimOne;
2) Interpolation
XY 애니매이션과 투명 효과를 동시에 적용하는 방법은 다음과 같다. 단, 주의해야할 점으로는 inputRange의 값은 반드시 작은 수에서 큰 수 순서대로 작성이 되어야하며, outputRange는 inputRange의 배열에 맞게 작성되어야한다.
예를 들어 위에서 아래로 이동하면서 투명해지는 효과의 경우, 투명도가 1 일 때 y 축 좌표가 0이여야하며, 투명도가 0 일 때 y축 좌표가 700이여야 한다.
import React, { Component } from 'react';
import { View, Text, StyleSheet, Animated, Easing, Button } from 'react-native';
class AnimOne extends Component {
constructor() {
super();
this.state = {
mySquare: new Animated.Value(1)
}
}
runAnimation = () => {
Animated.timing(this.state.mySquare, {
toValue: 0,
duration: 2000, // 2초
delay: 1500, // 1.5 초
}).start();
}
render() {
return (
<View>
<Animated.View
// style={this.state.mySquare.getLayout()}
style={{
opacity: this.state.mySquare,
top: this.state.mySquare.interpolate({
inputRange: [0, 1], // 투명도 효과
outputRange: [700, 0] // 동시 효과
})
}}
>
<View style={styles.square}>
</View>
</Animated.View>
<Button
title="Animation Start"
onPress={this.runAnimation}
/>
</View>
)
}
};
const styles = StyleSheet.create({
square: {
width: 100,
height: 100,
backgroundColor: 'skyblue'
}
});
export default AnimOne;
그리고, style에서 top 속성이 아닌 transform 속성을 통해 부여가 가능하다.
...
<Animated.View
style={{
opacity: this.state.mySquare,
transform: [{
translateY: this.state.mySquare.interpolate({
inputRange: [0, 1], // 투명도 효과
outputRange: [700, 0] // 동시 효과
})
}]
}}
>
<View style={styles.square}>
</View>
</Animated.View>
...
3) Interpolation 응용
도형이 회전하는 효과와 텍스트 효과는 다음과 같다.
import React, { Component } from 'react';
import { View, Text, StyleSheet, Animated, Easing, Button } from 'react-native';
class AnimOne extends Component {
constructor() {
super();
this.state = {
mySquare: new Animated.Value(1)
}
}
runAnimation = () => {
Animated.timing(this.state.mySquare, {
toValue: 0,
duration: 2000, // 2초
delay: 1500, // 1.5 초
}).start();
}
render() {
return (
<View>
<Animated.View
// style={this.state.mySquare.getLayout()}
style={{
opacity: this.state.mySquare,
transform: [
{
rotateX: this.state.mySquare.interpolate({
inputRange: [0, 0.5, 1], // 투명도 효과
outputRange: ['0deg', '180deg', '360deg'] // 동시 효과
})
},
{
translateX: this.state.mySquare.interpolate({
inputRange: [0, 0.5, 1], // 투명도 효과
outputRange: [300, 150, 0] // 동시 효과
})
}
]
}}
>
<View style={styles.square}>
</View>
</Animated.View>
<Animated.Text
style={{
fontSize: this.state.mySquare.interpolate({
inputRange: [0, 0.5, 1], // 투명도 효과
outputRange: [40, 30, 20] // 동시 효과
}),
color: this.state.mySquare.interpolate({
inputRange: [0, 0.5, 1],
outputRange: ['red', 'green', 'blue']
})
}}
>
<Text>Animated Text</Text>
</Animated.Text>
<Button
title="Animation Start"
onPress={this.runAnimation}
/>
</View>
)
}
};
const styles = StyleSheet.create({
square: {
width: 100,
height: 100,
backgroundColor: 'skyblue'
}
});
export default AnimOne;
4) 효과 순서 설정
import React, { Component } from 'react';
import { View, Text, StyleSheet, Animated, Easing, Button } from 'react-native';
class AnimTwo extends Component {
constructor() {
super();
this.state = {
redSquare: new Animated.Value(1),
greenSquare: new Animated.ValueXY(0, 0),
blueSquare: new Animated.ValueXY(0, 0)
}
}
runAnimation = () => {
Animated.sequence([ // 순서
Animated.timing(this.state.redSquare, {
toValue: 0
}),
Animated.parallel([ // 동시 적용 효과
Animated.spring(this.state.greenSquare, {
toValue: {x: 200, y: 0}
}),
Animated.spring(this.state.blueSquare, {
toValue: {x: 200, y: 400}
})
])
]).start();
}
render() {
return (
<View>
<Animated.View
style={{
opacity: this.state.redSquare
}}
>
<View style={styles.redSquare}>
</View>
</Animated.View>
<Animated.View
style={this.state.greenSquare.getLayout()}
>
<View style={styles.greenSquare}>
</View>
</Animated.View>
<Animated.View
style={this.state.blueSquare.getLayout()}
>
<View style={styles.blueSquare}>
</View>
</Animated.View>
<Button
title="Animation Start"
onPress={this.runAnimation}
/>
</View>
)
}
};
const styles = StyleSheet.create({
redSquare: {
width: 100,
height: 100,
backgroundColor: 'red'
},
greenSquare: {
width: 100,
height: 100,
backgroundColor: 'green'
},
blueSquare: {
width: 100,
height: 100,
backgroundColor: 'blue'
},
});
export default AnimTwo;
728x90
'React > React Native' 카테고리의 다른 글
[React Native] 재사용 가능한 Component (0) | 2021.01.04 |
---|---|
[React Native] Debugger (0) | 2021.01.04 |
[React Native] 연락처 접근 (0) | 2021.01.02 |
[React Native] Image Picker (1) | 2020.12.31 |