I want to display an animated number from 0 to max value y during x seconds. I have tried this following code but it take too much to complete and clear the interval.
jQuery('.numbers').each(function(item, index) {
const $obj = jQuery(this);
let objValue = parseInt($obj.text()),
currentValue = 0,
speed = 1,
time = 4000,
step = Math.floor(objValue / time);
$obj.text(currentValue);
let interVal = setInterval(() => {
if (currentValue >= objValue) {
clearInterval(interVal);
$obj.text(objValue);
}
$obj.text(currentValue);
currentValue = step
}, speed);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class='numbers'>7586</span>
<span class='numbers'>147520</span>
How do I play this animation during exactly time
seconds?
CodePudding user response:
It is better not to depend on the timing of setInterval()
, but the real problem in your script is that you use the floored value to decide the new value to print out.
It is better to use Window.requestAnimationFrame() and create a update()
function that prints the current number based on the real time elapsed.
let start, previousTimeStamp;
let numbers = document.querySelectorAll('.numbers');
requestAnimationFrame(update);
function update(timestamp) {
if (start === undefined) {
start = timestamp;
}
const elapsed = timestamp - start;
[...numbers].forEach(elm => {
if(!elm.dataset.start){
elm.dataset.start = elm.textContent;
}
let start = parseInt(elm.dataset.start);
elm.textContent = Math.floor(start / 4000 * elapsed);
});
if (elapsed < 4000) {
previousTimeStamp = timestamp;
requestAnimationFrame(update);
}else {
start = undefined;
[...numbers].forEach(elm => {
elm.textContent = elm.dataset.start;
});
}
}
<span class='numbers'>7586</span>
<span class='numbers'>147520</span>