/* c8 ignore start */ import { formatJackpotNumber } from '#lib/utils' import { onMounted, ref, watch, type Ref } from 'vue' /** * Provides a reactive animated number counter. * The counter animates from 0 to the specified number over a set duration. * @param {number} number - The target number to animate to. * @param {string} [character=','] - The character used for formatting the number. * @returns {Object} An object containing the reactive `numberCounter` property. * @namespace */ export function useAnimatedNumber(number: Ref, character: string = ',') { const numberCounter = ref('0') const animationDuration = 1000 let animationStartTime: number | null = null let previousNumber = 0 /** * The animation function that updates the numberCounter value based on the current timestamp. * @param {number} timestamp - The current time provided by the `requestAnimationFrame` callback. */ const animateNumber = (timestamp: number): void => { if (!animationStartTime) { animationStartTime = timestamp } const progress = Math.min( 1, (timestamp - animationStartTime) / animationDuration, ) const newCounterValue = Math.round(previousNumber + (number.value - previousNumber) * progress) numberCounter.value = formatJackpotNumber(newCounterValue, character) if (progress < 1) { requestAnimationFrame(animateNumber) } else { numberCounter.value = formatJackpotNumber(Math.round(number.value), character) } } onMounted(() => { requestAnimationFrame(animateNumber) }) watch( () => number.value, () => { previousNumber = parseInt(numberCounter.value.replace(/,/g, ''), 10) || 0 animationStartTime = null requestAnimationFrame(animateNumber) }, ) return { numberCounter, } } /* c8 ignore start */