import * as React from "react"; import { Animated, Easing, EasingFunction, StyleProp, ViewStyle, } from "react-native"; import CircularProgress, { Props as CircularProgressProps, } from "./CircularProgress"; const AnimatedProgress = Animated.createAnimatedComponent(CircularProgress); type Props = { duration?: number; easing?: EasingFunction; prefill?: number; useNativeDriver?: boolean; tintColorSecondary?: string; onAnimationComplete?: Animated.EndCallback | undefined; } & CircularProgressProps; const AnimatedCircularProgress: React.FC<Props> = ({ duration = 500, easing = Easing.out(Easing.ease), fill, prefill = 0, useNativeDriver = false, tintColorSecondary, onAnimationComplete, tintColor = "black", ...other }) => { const [fillAnimation] = React.useState<Animated.Value>( new Animated.Value(prefill) ); const animate = React.useCallback( ( toVal: number = -1, dur?: number, ease?: EasingFunction ): Animated.CompositeAnimation => { const toValue = toVal >= 0 ? toVal : fill; const dura = dur || duration; const eas = ease || easing; const useNative = useNativeDriver; const anim = Animated.timing(fillAnimation, { useNativeDriver: useNative, toValue, easing: eas, duration: dura, }); anim.start(onAnimationComplete); return anim; }, [ duration, easing, fill, useNativeDriver, fillAnimation, onAnimationComplete, ] ); const animateColor = () => { if (!tintColorSecondary) { return tintColor; } const tintAnimation = fillAnimation.interpolate({ inputRange: [0, 100], outputRange: [tintColor, tintColorSecondary], }); return tintAnimation; }; React.useEffect(() => { animate(); }, [fill, animate]); return ( <AnimatedProgress {...other} style={other.style as Animated.WithAnimatedValue<StyleProp<ViewStyle>>} childrenContainerStyle={ other.childrenContainerStyle as Animated.WithAnimatedValue< StyleProp<ViewStyle> > } fill={fillAnimation} tintColor={animateColor()} /> ); }; export default AnimatedCircularProgress;