| import React from 'react'; | |
| import { StyleSheet } from 'react-native'; | |
| import Animated, { useAnimatedReaction, runOnJS, useAnimatedStyle } from 'react-native-reanimated'; | |
| import { COLORS } from '../constants/colors'; | |
| interface ScoreCounterProps { | |
| scoreProgress: Animated.SharedValue<number>; | |
| targetScore: number; | |
| } | |
| export const ScoreCounter: React.FC<ScoreCounterProps> = ({ scoreProgress, targetScore }) => { | |
| const [displayScore, setDisplayScore] = React.useState(0); | |
| useAnimatedReaction( | |
| () => { | |
| 'worklet'; | |
| return Math.round(scoreProgress.value * targetScore); | |
| }, | |
| (currentScore, previousScore) => { | |
| 'worklet'; | |
| if (currentScore !== previousScore) { | |
| runOnJS(setDisplayScore)(currentScore); | |
| } | |
| }, | |
| [targetScore] | |
| ); | |
| return ( | |
| <Animated.Text style={styles.scoreText}> | |
| {displayScore.toLocaleString()} | |
| </Animated.Text> | |
| ); | |
| }; | |
| const styles = StyleSheet.create({ | |
| scoreText: { | |
| fontSize: 64, | |
| fontWeight: '900', | |
| color: COLORS.text, | |
| textAlign: 'center', | |
| textShadowColor: COLORS.primary + '40', | |
| textShadowOffset: { width: 0, height: 0 }, | |
| textShadowRadius: 20, | |
| marginVertical: 8, | |
| fontVariant: ['tabular-nums'], | |
| letterSpacing: 2, | |
| }, | |
| }); | |