-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFlipGrid2024RequireAssets.jsx
97 lines (86 loc) · 2.65 KB
/
FlipGrid2024RequireAssets.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//LOAD FROM MEDIA LIBARY OR URLS
import React, { useState, useEffect } from 'react';
import { View, StyleSheet } from 'react-native';
//need to use Expo Image or else you'll get the dreaded "No suitable URL request handler found for ph://5BC025F5-22D3-4B97-BF17-39321661A5E2/L0/001" err
import { Image } from 'expo-image';
import Animated, { useSharedValue, useAnimatedStyle, withTiming, runOnJS } from 'react-native-reanimated';
const FlipCard2024RequireAssets = ({ images }) => {
const [activeIndex, setActiveIndex] = useState(0);
const handleFlipEnd = index => {
if (index < images.length - 2) {
setActiveIndex(index + 1); // Activate next flip
}
};
return (
<View style={styles.container}>
{images.slice(0, -1).map((_, index) => (
<FlipCard
key={index}
frontImage={images[index]}
backImage={images[index + 1]}
isActive={index === activeIndex}
onFlipEnd={() => handleFlipEnd(index)}
/>
))}
</View>
);
};
const FlipCard = ({ frontImage, backImage, isActive, onFlipEnd }) => {
const animatedValue = useSharedValue(0);
const frontAnimatedStyle = useAnimatedStyle(() => ({
transform: [{ rotateY: `${animatedValue.value}deg` }],
opacity: animatedValue.value % 360 <= 90 ? 1 : 0,
}));
const backAnimatedStyle = useAnimatedStyle(() => ({
transform: [{ rotateY: `${180 + animatedValue.value}deg` }],
opacity: animatedValue.value % 360 > 90 ? 1 : 0,
}));
useEffect(() => {
if (isActive) {
animatedValue.value = withTiming(180, { duration: 1500 }, () => {
runOnJS(onFlipEnd)();
});
}
}, [isActive]);
return isActive ? (
<View style={styles.cardContainer}>
<Animated.View style={[styles.card, frontAnimatedStyle]}>
<Image source={ frontImage } style={styles.image} />
</Animated.View>
<Animated.View style={[styles.card, backAnimatedStyle, { position: 'absolute' }]}>
<Image source={ backImage } style={styles.image} />
</Animated.View>
</View>
) : null;
};
const styles = StyleSheet.create({
container: {
width: 150,
height: 150,
alignItems: 'center',
justifyContent: 'center',
perspective: 1000,
position: 'relative',
},
cardContainer: {
width: '100%',
height: '100%',
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
perspective: 1000,
},
card: {
width: '100%',
height: '100%',
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
backfaceVisibility: 'hidden',
},
image: {
width: '100%',
height: '100%',
}
});
export default FlipCard2024RequireAssets;