import React, { useEffect } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import Animated, { useSharedValue, useAnimatedStyle, withSpring, withDelay, interpolate, } from 'react-native-reanimated'; import { COLORS } from '../constants/colors'; interface ScoreFlyoutProps { points: number; isCorrect: boolean; combo: number; visible: boolean; } export const ScoreFlyout: React.FC = ({ points, isCorrect, combo, visible, }) => { const translateY = useSharedValue(0); const opacity = useSharedValue(0); const scale = useSharedValue(0.5); useEffect(() => { if (visible && points > 0) { translateY.value = 0; opacity.value = 0; scale.value = 0.5; opacity.value = withSpring(1, { damping: 10, stiffness: 200 }); scale.value = withSpring(1, { damping: 8, stiffness: 200 }); translateY.value = withDelay( 400, withSpring(-60, { damping: 12, stiffness: 60 }) ); opacity.value = withDelay(600, withSpring(0, { damping: 10 })); } }, [visible, points]); const animStyle = useAnimatedStyle(() => ({ opacity: opacity.value, transform: [ { translateY: translateY.value }, { scale: scale.value }, ], })); if (!visible || points === 0) return null; return ( {isCorrect ? `+${points}` : 'WRONG'} {isCorrect && combo > 1 && ( 🔥 {combo}x COMBO )} ); }; const styles = StyleSheet.create({ container: { position: 'absolute', top: '30%', alignSelf: 'center', alignItems: 'center', zIndex: 100, }, points: { fontSize: 36, fontWeight: '900', textShadowColor: 'rgba(0,0,0,0.5)', textShadowOffset: { width: 0, height: 2 }, textShadowRadius: 4, }, combo: { fontSize: 14, fontWeight: '800', color: COLORS.accent, marginTop: 4, letterSpacing: 1, }, });