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
JavaScript
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