import { Text } from '@/aesthetics/Text'; import { font as fontSizes, getScoreColor, getScoreLabel, spacing, useColors, } from '@/aesthetics/styles'; import { Canvas, Group, Path, Skia } from '@shopify/react-native-skia'; import { useEffect } from 'react'; import { StyleSheet, View } from 'react-native'; import { useSharedValue, withTiming } from 'react-native-reanimated'; type NutritionScoreOverviewProps = { score: number; }; const RING_SIZE = 160; const STROKE_WIDTH = 10; const RADIUS = (RING_SIZE - STROKE_WIDTH) / 2; const CENTER = RING_SIZE / 2; const ANIMATION_DURATION = 800; const circlePath = Skia.Path.Make(); circlePath.addCircle(CENTER, CENTER, RADIUS); export function NutritionScoreOverview({ score }: NutritionScoreOverviewProps) { const c = useColors(); const scoreColor = getScoreColor(score, c); const displayScore = Math.ceil(Math.max(0, Math.min(100, score))); const progress = useSharedValue(0); useEffect(() => { progress.value = withTiming(displayScore / 100, { duration: ANIMATION_DURATION }); }, [displayScore]); return ( {displayScore} {getScoreLabel(score)} ); } const styles = StyleSheet.create({ container: { alignItems: 'center', paddingVertical: spacing.xl, }, ringContainer: { width: RING_SIZE, height: RING_SIZE, alignItems: 'center', justifyContent: 'center', }, scoreContainer: { position: 'absolute', alignItems: 'center', width: RING_SIZE, }, scoreText: { fontSize: fontSizes.display, fontWeight: '700', }, scoreLabel: { fontSize: fontSizes.xs, textTransform: 'uppercase', letterSpacing: 1, marginTop: 2, }, });