I want to implement a flip effect in my React Native app, similar like described here:
https://www.codementor.io/reactjs/tutorial/building-a-flipper-using-react-js-and-less-css
My question is. Can I achieve it somehow with the help of some library like 'Animations' https://facebook.github.io/react-native/docs/animations.html or I have to play with 'plain' CSS styles.
What is the 'good practive' for such animations in React Native?
class CardBack extends Component {
render() {
return (
<TouchableOpacity onPress={this.flip}>
<View style={styles.scrumCardBorder}>
<View style={styles.cardBack}>
</View>
</View>
</TouchableOpacity>
);
}
flip() {
this.setState({flipped: !this.state.flipped})
}
}
class CardFront extends Component {
render() {
return (
<TouchableOpacity>
<View style={styles.scrumCardBorder}>
<View style={styles.cardFront}>
<Text style={styles.cardValue}>5</Text>
</View>
</View>
</TouchableOpacity>
);
}
}
We can use transform and Interpolate to make 3D rotate Animation.
class RotateAnimation extends React.Component {
_rotateValue = new Animated.Value(0);
startAnimated = () => {
Animated.timing(this._rotateValue, {
toValue: 360,
duration: 800,
useNativeDriver: true
}).start()
}
getTransform = () => {
const rotate = this._rotateValue.interpolate({
inputRange: [0, 180, 360],
outputRange: ['0deg', '180deg', '360deg'],
extrapolate: 'clamp',
})
if (this.props.horizontal) {
return {
transform: {
perspective: WINDOW_WIDTH,
rotateX: rotate
}
}
}
return {
transform: {
perspective: WINDOW_WIDTH,
rotateY: rotate
}
}
}
render() {
return (<Animated.View style={[style, ]} />
{this.props.children}
</Animated.View>)
}
}
If you want to use transform around a certain point. Can try this.
Use Animated api for these transformations.
Note: Rotation along the axis(ie, rotateX or rotateY) with perspective will give you the feel of flipping.
Always use useNativeDriver: true for better performance.
Example code:
import React, {Component} from 'react';
import {View, Animated, StyleSheet, Button} from 'react-native';
export default class Container extends Component {
constructor() {
super();
this.animation = new Animated.ValueXY({x: 0, y: 0});
const inputRange = [0, 1];
const outputRange = ['0deg', '180deg'];
this.rotateX = this.animation.x.interpolate({inputRange, outputRange});
this.rotateY = this.animation.y.interpolate({inputRange, outputRange});
}
flip = (val) => {
this.animation[val].setValue(0);
Animated.timing(this.animation[val], {
toValue: 1,
duration: 500,
useNativeDriver: true,
}).start();
};
render() {
const {rotateX, rotateY} = this;
return (
<View style={styles.container}>
<Animated.View
style={{
...styles.item,
transform: [{rotateX}, {rotateY}, {perspective: 500}],
}}
/>
<Button title="flip x " onPress={() => this.flip('x')} />
<Button title="flip y " onPress={() => this.flip('y')} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {flex: 1, alignItems: 'center', justifyContent: 'center'},
item: {
height: 200,
width: 200,
backgroundColor: 'red',
marginBottom: 20,
},
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With