import { createElement, useEffect, useState } from 'rax'; import View from 'rax-view'; import classnames from 'classnames'; import { isValidNumber } from '@/common/util'; interface NumberAnimationPropsType { from?: number; value: number; speed?: number; interval: number; className?: string; style?: CSSProperties; } export default function NumberAnimation(props: NumberAnimationPropsType) { const { style, className, value, triggerAnimation = true, from = 0, speed = 1000, interval = 100, format = v => v, } = props; const [ numberShow, setNumber ] = useState(from); function isValidNumber(num) { return isNaN(num) ? false : num !== null && num !== undefined && num !== ""; } useEffect(() => { if (!triggerAnimation) { return; } if (!isValidNumber(value)) { setNumber(value); return; } let loops = Math.ceil(speed / interval), increment = parseInt((value - from) / loops), loopCount = 0, number = from, timer = setInterval(updateTimer, interval); function updateTimer() { loopCount++; if (loopCount >= loops){ number = value; clearInterval(timer); } else { number += increment; } setNumber(number); }; return () => { if (timer) { clearInterval(timer); } }; }, [value, triggerAnimation]); return ( <View className={className} style={style}>{format(numberShow)}</View> ); }