Skip to content

Instantly share code, notes, and snippets.

@akulsr0
Created September 1, 2021 14:59
Show Gist options
  • Save akulsr0/90b72d2786da21e006827b73f7be1b89 to your computer and use it in GitHub Desktop.
Save akulsr0/90b72d2786da21e006827b73f7be1b89 to your computer and use it in GitHub Desktop.
RNAnims - Winner Animation
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