Created
September 1, 2021 14:59
-
-
Save akulsr0/90b72d2786da21e006827b73f7be1b89 to your computer and use it in GitHub Desktop.
RNAnims - Winner 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 * as React from "react"; | |
import { | |
View, | |
Animated, | |
Image, | |
TouchableOpacity, | |
Text, | |
Dimensions, | |
StyleSheet, | |
} from "react-native"; | |
const TROPHY_IMG_URI = | |
"https://www.starpng.com/public/uploads/preview/no1-trophy-png-image-115770293491lf3regicw.png"; | |
const getUserImage = (n: number): string => | |
`https://randomuser.me/api/portraits/men/${n}.jpg`; | |
const WinnerScreen = () => { | |
// Positions for user1 image, user2 image and trophy image. | |
const pos1 = new Animated.ValueXY({ x: 0, y: 0 }); | |
const pos2 = new Animated.ValueXY({ x: 0, y: 0 }); | |
const trophyPos = new Animated.ValueXY({ x: 0, y: 0 }); | |
// Reset positions for user1 image, user2 image and trophy image. | |
const resetWinner = () => { | |
pos1.setValue({ x: 0, y: 0 }); | |
pos2.setValue({ x: 0, y: 0 }); | |
trophyPos.setValue({ x: 0, y: 0 }); | |
}; | |
// Decides a random winner and start corresponding animation. | |
const getRandomWinner = () => { | |
const randomWinner = Math.floor(Math.random() * 10) % 2; | |
const windowWidth = Dimensions.get("window").width; | |
// Displacement for X axis | |
// Remove padding -> 20 each side -> windowWidth - 40 | |
// Center it -> Divide by 2 | |
// Remove half image width also to center -> -75 | |
const disX = (windowWidth - 40) / 2 - 75; | |
// Displacement for Y axis | |
// We want to move up so taking negative value | |
// Magnitude will be image height (150) + some extra space (30) = 180 | |
const disY = -180; | |
// Displacement for trophy X axis | |
// Center it -> windowWidth/2 | |
// Add half image width also to center -> +30 | |
const trophyDisX = windowWidth / 2 + 30; | |
// Resets winner incase there is already one. | |
resetWinner(); | |
if (randomWinner) { | |
// Animate User1 for winning | |
Animated.spring(pos1, { | |
toValue: { x: disX, y: disY }, | |
useNativeDriver: true, | |
speed: 2, | |
bounciness: 5, | |
}).start(); | |
} else { | |
// Animate User2 for winning | |
Animated.spring(pos2, { | |
toValue: { x: -disX, y: disY }, | |
useNativeDriver: true, | |
speed: 2, | |
bounciness: 5, | |
}).start(); | |
} | |
// Animate tropy to come in center | |
Animated.spring(trophyPos, { | |
toValue: { x: trophyDisX, y: 0 }, | |
useNativeDriver: true, | |
speed: 3 / 4, | |
bounciness: 10, | |
}).start(); | |
}; | |
return ( | |
<View style={Styles.container}> | |
<Animated.View | |
style={{ | |
left: -60, | |
zIndex: 100, | |
transform: [{ translateX: trophyPos.x }, { translateY: trophyPos.y }], | |
}} | |
> | |
<Image source={{ uri: TROPHY_IMG_URI }} style={Styles.trophyImage} /> | |
</Animated.View> | |
<View style={Styles.usersView}> | |
<Animated.View | |
style={{ | |
transform: [{ translateX: pos1.x }, { translateY: pos1.y }], | |
}} | |
> | |
<Image style={Styles.userImage} source={{ uri: getUserImage(1) }} /> | |
</Animated.View> | |
<Animated.View | |
style={{ | |
transform: [{ translateX: pos2.x }, { translateY: pos2.y }], | |
}} | |
> | |
<Image style={Styles.userImage} source={{ uri: getUserImage(2) }} /> | |
</Animated.View> | |
</View> | |
<View style={Styles.buttonsView}> | |
<TouchableOpacity style={Styles.button} onPress={getRandomWinner}> | |
<Text style={Styles.buttonText}>Random Winner</Text> | |
</TouchableOpacity> | |
<TouchableOpacity | |
style={[Styles.button, { marginLeft: 10 }]} | |
onPress={resetWinner} | |
> | |
<Text style={Styles.buttonText}>Reset Winner</Text> | |
</TouchableOpacity> | |
</View> | |
</View> | |
); | |
}; | |
const Styles = StyleSheet.create({ | |
container: { | |
display: "flex", | |
flex: 1, | |
justifyContent: "center", | |
}, | |
trophyImage: { | |
width: 60, | |
height: 60, | |
}, | |
usersView: { | |
display: "flex", | |
flexDirection: "row", | |
justifyContent: "space-between", | |
paddingHorizontal: 20, | |
}, | |
userImage: { | |
width: 150, | |
height: 150, | |
borderRadius: 10, | |
}, | |
buttonsView: { | |
display: "flex", | |
flexDirection: "row", | |
justifyContent: "center", | |
marginTop: 30, | |
}, | |
button: { | |
backgroundColor: "#333", | |
display: "flex", | |
flexDirection: "row", | |
padding: 10, | |
paddingHorizontal: 20, | |
borderRadius: 4, | |
}, | |
buttonText: { | |
fontSize: 16, | |
fontWeight: "500", | |
color: "white", | |
}, | |
}); | |
export default WinnerScreen; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment