Created
September 3, 2018 09:28
-
-
Save wcandillon/288e994cda3216d1dbef9482a9322804 to your computer and use it in GitHub Desktop.
React Native Apple Wallet Animation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { | |
StyleSheet, | |
Text, | |
View, | |
ScrollView, | |
Animated, | |
SafeAreaView, | |
Dimensions | |
} from "react-native"; | |
const cardHeight = 250; | |
const cardTitle = 45; | |
const cardPadding = 10; | |
const { height } = Dimensions.get("window"); | |
const cards = [ | |
{ | |
name: "Shot", | |
color: "#a9d0b6", | |
price: "30 CHF" | |
}, | |
{ | |
name: "Juice", | |
color: "#e9bbd1", | |
price: "64 CHF" | |
}, | |
{ | |
name: "Mighty Juice", | |
color: "#eba65c", | |
price: "80 CHF" | |
}, | |
{ | |
name: "Sandwich", | |
color: "#95c3e4", | |
price: "85 CHF" | |
}, | |
{ | |
name: "Combi", | |
color: "#1c1c1c", | |
price: "145 CHF" | |
}, | |
{ | |
name: "Signature", | |
color: "#a390bc", | |
price: "92 CHF" | |
}, | |
{ | |
name: "Coffee", | |
color: "#fef2a0", | |
price: "47 CHF" | |
} | |
]; | |
export default class App extends React.Component { | |
state = { | |
y: new Animated.Value(0) | |
}; | |
render() { | |
const { y } = this.state; | |
return ( | |
<SafeAreaView style={styles.root}> | |
<View style={styles.container}> | |
<View style={StyleSheet.absoluteFill}> | |
{cards.map((card, i) => { | |
const inputRange = [-cardHeight, 0]; | |
const outputRange = [ | |
cardHeight * i, | |
(cardHeight - cardTitle) * -i | |
]; | |
if (i > 0) { | |
inputRange.push(cardPadding * i); | |
outputRange.push((cardHeight - cardPadding) * -i); | |
} | |
const translateY = y.interpolate({ | |
inputRange, | |
outputRange, | |
extrapolateRight: "clamp" | |
}); | |
return ( | |
<Animated.View | |
key={card.name} | |
style={{ transform: [{ translateY }] }} | |
> | |
<View | |
style={[styles.card, { backgroundColor: card.color }]} | |
/> | |
</Animated.View> | |
); | |
})} | |
</View> | |
<Animated.ScrollView | |
scrollEventThrottle={16} | |
contentContainerStyle={styles.content} | |
showsVerticalScrollIndicator={false} | |
onScroll={Animated.event( | |
[ | |
{ | |
nativeEvent: { | |
contentOffset: { y } | |
} | |
} | |
], | |
{ useNativeDriver: true } | |
)} | |
/> | |
</View> | |
</SafeAreaView> | |
); | |
} | |
} | |
const styles = StyleSheet.create({ | |
root: { | |
flex: 1, | |
margin: 16 | |
}, | |
container: { | |
flex: 1 | |
}, | |
content: { | |
height: height * 2 | |
}, | |
card: { | |
height: cardHeight, | |
borderRadius: 10 | |
} | |
}); |
how can i make the items inside the card clickable, the TouchableOpacity is not working inside the card
I did like this and it worked
<SafeAreaView style={styles.root}>
<View style={styles.container}>
<Animated.ScrollView
scrollEventThrottle={16}
contentContainerStyle={styles.content}
showsVerticalScrollIndicator={false}
onScroll={Animated.event(
[
{
nativeEvent: {
contentOffset: { y }
}
}
],
{ useNativeDriver: true }
)}
>
<View style={StyleSheet.absoluteFill}>
{cards.map((card, i) => {
const inputRange = [-cardHeight, 0];
const outputRange = [
cardHeight * i,
(cardHeight - cardTitle) * -i
];
if (i > 0) {
inputRange.push(cardPadding * i);
outputRange.push((cardHeight - cardPadding) * -i);
}
const translateY = y.interpolate({
inputRange,
outputRange,
extrapolateRight: "clamp"
});
return (
<Animated.View
key={card.name}
style={{ transform: [{ translateY }] }}
>
<View
style={[styles.card, { backgroundColor: card.color }]}
/>
</Animated.View>
);
})}
</View>
</ Animated.ScrollView>
</View>
</SafeAreaView>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is kinda useless because theres noway to click the cards, if you do an overlay touchable opacity and map the coordinates, it works only when they are stacked in the original state, if theres too many cards and you scroll up to minimise the stack then your coordinates change. Just seems very hacky to make clickable items work this way
anyway
with this hack, i have it working, see video and rough code below
https://user-images.githubusercontent.com/1423413/132573698-20f7f5c5-65bf-44d4-b24e-dd263fcc7fab.mov