UNPKG

react-native-animated-number

Version:

React Native component that animates a number by smoothly changing it between renders

50 lines (47 loc) 2.05 kB
import * as React from 'react'; import { TextInput } from 'react-native'; function formatFn(value) { return value.toString(); } function AnimatedNumber({ formatter = formatFn, steps = 15, time = 17, value, ...restProps }) { const viewValue = React.useRef(value); const textInputRef = React.useRef(null); const timerRef = React.useRef(); const maybeClearInterval = () => { if (undefined !== timerRef.current) { clearInterval(timerRef.current); timerRef.current = undefined; } }; React.useEffect(() => { return () => maybeClearInterval(); }, []); // Start updating current value whenever `value` changes React.useEffect(() => { if (viewValue.current === value) return; const minimumStep = value - viewValue.current > 0 ? 1 : -1; const stepSize = Math.floor((value - viewValue.current) / steps); const valuePerStep = minimumStep > 0 ? Math.max(stepSize, minimumStep) : Math.min(stepSize, minimumStep); // Clamping is required to correct for rounding errors const clampValue = 1 === minimumStep ? Math.min.bind(undefined, value) : Math.max.bind(undefined, value); timerRef.current = setInterval(() => { viewValue.current = Math.floor(clampValue(viewValue.current + valuePerStep)); textInputRef.current?.setNativeProps({ text: formatter(viewValue.current), }); if ((minimumStep === 1 && viewValue.current >= value) || (minimumStep === -1 && viewValue.current <= value)) { maybeClearInterval(); } }, time); return () => maybeClearInterval(); }, [value]); return (React.createElement(TextInput, Object.assign({}, restProps, { ref: textInputRef, editable: false, value: formatter(viewValue.current) }))); } export default AnimatedNumber; //# sourceMappingURL=index.es.js.map