Skip to content

Instantly share code, notes, and snippets.

@Kida007
Created March 26, 2020 22:08
Show Gist options
  • Save Kida007/3507907920b878bae12642289d1d1ca8 to your computer and use it in GitHub Desktop.
Save Kida007/3507907920b878bae12642289d1d1ca8 to your computer and use it in GitHub Desktop.
/* eslint-disable react-native/no-inline-styles */
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
*/
import React from 'react';
import {
SafeAreaView,
StyleSheet,
Image,
ScrollView,
View,
Text,
StatusBar,
Animated,
Easing,
TouchableOpacity,
} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {
Header,
LearnMoreLinks,
Colors,
DebugInstructions,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
const Data = [
{
id: 1,
color: ['#E44D26', '#BD3F32'],
image:
'https://cdn.freebiesupply.com/logos/large/2x/visa-1-logo-png-transparent.png',
tintColor: '#fff',
cardNumber: [2133, 9823, 2938, 9901],
expires: '02/23',
},
{
id: 2,
color: ['#673AB7', '#512DA8'],
image:
'https://upload.wikimedia.org/wikipedia/commons/thumb/2/2a/Mastercard-logo.svg/200px-Mastercard-logo.svg.png',
cardNumber: [1016, 9019, 8811, 6612],
expires: '07/27',
},
{
id: 3,
color: ['#00bf8f', '#01614a'],
image:
'https://cdn.freebiesupply.com/logos/large/2x/visa-1-logo-png-transparent.png',
tintColor: '#fff',
cardNumber: [8891, 8819, 7721, 6541],
expires: '01/22',
},
{
id: 4,
color: ['#ffb347', '#ffcc33'],
cardNumber: [4312, 3210, 9711, 2311],
image:
'https://upload.wikimedia.org/wikipedia/commons/thumb/2/2a/Mastercard-logo.svg/200px-Mastercard-logo.svg.png',
expires: '09/28',
},
];
class App extends React.Component {
state = {top: Data.length - 1};
constructor(props) {
super(props);
this.animationControl = new Animated.Value(0);
}
animate = () => {
const {top} = this.state;
this.animationControl.setValue(0);
Animated.timing(this.animationControl, {
toValue: 1,
duration: 500,
easing: Easing.bezier(0.27, 0.71, 0.72, 0.46),
}).start(() => {
console.log('finished');
this.setState({top: top - 1 >= 0 ? top - 1 : Data.length - 1}, () => {
this.animationControl.setValue(0);
});
});
};
render() {
const opacity = this.animationControl.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
});
const {top} = this.state;
return (
<View
style={{
flex: 1,
backgroundColor: '#0F2027',
}}>
<StatusBar barStyle="light-content" />
<LinearGradient
style={{
flex: 1,
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: 50,
}}
colors={['#0F2027', '#203A43']}>
<View />
<View>
<View style={{width: 350, aspectRatio: 1.45}}>
{Data.map((datum, index) => {
const effectiveIndex =
index > top
? index - top - 1
: Data.length - 1 - (this.state.top - index);
const yOffset = this.animationControl.interpolate({
inputRange: [0, 1],
outputRange: [
(Data.length - effectiveIndex) * 20,
effectiveIndex === Data.length - 1
? Data.length * 20
: (Data.length - effectiveIndex - 1) * 20,
],
});
const scaleIndex = 1 - (Data.length - effectiveIndex) * 0.05;
//const effectiveScaleIndex = 1 - Data.length * 0.05;
const effectiveScaleIndex = 1 - Data.length * 0.05;
console.log(
effectiveIndex,
index,
scaleIndex,
effectiveScaleIndex,
);
const AnimatedScale = this.animationControl.interpolate({
inputRange:
effectiveIndex === Data.length - 1 ? [0, 0.5, 1] : [0, 1],
outputRange:
effectiveIndex === Data.length - 1
? [scaleIndex, scaleIndex, effectiveScaleIndex]
: [scaleIndex, scaleIndex + 0.05],
});
const rotation = this.animationControl.interpolate({
inputRange: [0, 0.5, 1],
outputRange: [
'0deg',
effectiveIndex === Data.length - 1 ? '15deg' : '0deg',
'0deg',
],
});
const translation = this.animationControl.interpolate({
inputRange: [0, 0.5, 1],
outputRange: [
0,
effectiveIndex === Data.length - 1 ? 0.69 * 350 + 80 : 0,
0,
],
});
const reverseTranslation = this.animationControl.interpolate({
inputRange: [0, 0.5, 1],
outputRange: [
0,
effectiveIndex === Data.length - 1 ? 50 : 0,
0,
],
});
const ZIndex = this.animationControl.interpolate({
inputRange:
effectiveIndex === Data.length - 1
? [0, 0.5, 0.501, 1]
: [0, 1],
outputRange:
effectiveIndex === Data.length - 1
? [effectiveIndex, effectiveIndex, 0, 0]
: [effectiveIndex, effectiveIndex + 1],
});
return (
<Animated.View
key={datum.id}
style={[
styles.item,
{zIndex: ZIndex, transform: [{translateY: yOffset}]},
]}>
<Animated.View
key={datum.id}
style={[
{
transform: [
{scale: AnimatedScale},
{rotateZ: rotation},
{translateY: Animated.multiply(translation, -1)},
{
translateX: Animated.multiply(
reverseTranslation,
-1,
),
},
],
borderRadius: 20,
overflow: 'hidden',
width: 350,
aspectRatio: 1.45,
},
]}>
<LinearGradient
style={{
flex: 1,
paddingHorizontal: 40,
paddingVertical: 20,
}}
colors={datum.color}>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
}}>
<Image
source={require('./sim.png')}
style={{height: 60, width: 50}}
resizeMode="contain"
/>
<Image
source={{uri: datum.image}}
style={{
height: 70,
width: 70,
tintColor: datum.tintColor,
}}
resizeMode={'contain'}
/>
</View>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 20,
}}>
<Text style={styles.cardNumber}>
{datum.cardNumber[0]}
</Text>
<Text style={styles.cardNumber}>
{datum.cardNumber[1]}
</Text>
<Text style={styles.cardNumber}>
{datum.cardNumber[2]}
</Text>
<Text style={styles.cardNumber}>
{datum.cardNumber[3]}
</Text>
</View>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 50,
}}>
<Text style={styles.mutedHeading}>CARD HOLDER</Text>
<Text style={styles.mutedHeading}>EXPIRY</Text>
</View>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 5,
}}>
<Text style={styles.Heading}>PIYUSH GUPTA</Text>
<Text style={styles.Heading}>{datum.expires}</Text>
</View>
</LinearGradient>
</Animated.View>
</Animated.View>
);
})}
</View>
</View>
<TouchableOpacity onPress={() => this.animate()}>
<View
style={{
paddingVertical: 20,
paddingHorizontal: 30,
borderRadius: 5,
alignSelf: 'center',
borderColor: '#fff',
borderWidth: 1,
}}>
<Text style={{color: '#fff', fontWeight: '900'}}>Press Me</Text>
</View>
</TouchableOpacity>
</LinearGradient>
</View>
);
}
}
const styles = StyleSheet.create({
item: {
justifyContent: 'flex-end',
shadowColor: '#000',
shadowOpacity: 0.3,
shadowOffset: {height: 2, width: 0},
...StyleSheet.absoluteFillObject,
},
cardNumber: {
color: '#fff',
fontSize: 16,
fontFamily: 'Menlo',
fontWeight: '500',
letterSpacing: 1.5,
},
mutedHeading: {
color: '#fff',
opacity: 0.6,
fontWeight: '600',
fontFamily: 'Courier',
fontSize: 12,
},
Heading: {
color: '#fff',
fontWeight: '600',
fontFamily: 'Courier',
fontSize: 16,
},
});
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment