import { useEffect, useRef } from 'react'; import { Animated, View, Text } from 'react-native'; /** * Animierter Progress-Bar: aktueller Score vs. persönlicher Rekord. * * - Bar-Breite animiert zu `min(score / max(best, 1), 1) * 100%` * - Bei `isNewBest=true`: Celebration-Animation (Gold-Pulse + Scale-Bounce + 🏆-Label) * - Position direkt unter `` im Game-Layout * * Reusable für Snake / Tetris / Memory — pro Spiel den passenden `score`/`best` * reinreichen. Optional `boardWidth` damit die Bar exakt das Board-Edge matcht. */ export interface ScoreProgressBarProps { score: number; best: number; isNewBest: boolean; boardWidth: number; } export function ScoreProgressBar({ score, best, isNewBest, boardWidth }: ScoreProgressBarProps) { const widthAnim = useRef(new Animated.Value(0)).current; const celebrationAnim = useRef(new Animated.Value(0)).current; // Bar-Breite zum aktuellen Score-Verhältnis useEffect(() => { const target = best > 0 ? Math.min(score / best, 1) : score > 0 ? 1 : 0; Animated.timing(widthAnim, { toValue: target, duration: 280, useNativeDriver: false, }).start(); }, [score, best, widthAnim]); // Celebration-Pulse bei neuem Rekord useEffect(() => { if (!isNewBest) { celebrationAnim.setValue(0); return; } Animated.sequence([ Animated.timing(celebrationAnim, { toValue: 1, duration: 280, useNativeDriver: false }), Animated.timing(celebrationAnim, { toValue: 0, duration: 600, useNativeDriver: false }), ]).start(); }, [isNewBest, celebrationAnim]); const widthInterp = widthAnim.interpolate({ inputRange: [0, 1], outputRange: ['0%', '100%'], }); // Bar-Color: idle blau, beim Celebration-Pulse → gold const barColor = celebrationAnim.interpolate({ inputRange: [0, 1], outputRange: ['#007AFF', '#FFD60A'], }); // Container leicht hochskalieren bei Celebration const containerScale = celebrationAnim.interpolate({ inputRange: [0, 1], outputRange: [1, 1.04], }); return ( {isNewBest ? '🏆 NEW RECORD' : 'PROGRESS'} {score} / {Math.max(best, score)} ); }