How to create a countup between two numbers with Jquery with intervals 15 and slowdown similar to the GIF image below?
I can't reproduce this effect.
$('.count').each(function () {
var $this = $(this);
jQuery({ Counter: 1243234 }).animate({ Counter: $this.attr('data-stop') }, {
useGrouping: true,
separator: ".",
decimal: ",",
speed: 99999,
duration: 9999999,
refreshInterval: 300,
easing: 'swing',
step: function (now) {
$this.text(Math.ceil(now));
}
});
});
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<span data-stop="3256986">3256986</span> Total downloads <br>
</body>
</html>
CodePudding user response:
Here's a jquery solution using .data
to store the current value and setTimeout to loop. Change the timeout (150 here) to adjust the speed. Same concepts can be used for a non-jquery solution.
Storing the current value in the element's data means:
- stored as an int, so no need to parse the text
- function can be used for multiple elements without them interfering (if you used global variables, this would be an issue)
$("[data-stop]").each(function() {
countCounter(this);
})
function countCounter(element) {
var $this = $(element);
var counter = $this.data("current") || ($this.text()*1);
var stop = $this.data("stop");
//console.log(counter, stop)
counter = 15;
if (counter > stop) counter = stop;
$this.text(counter.toLocaleString())
$this.data("current", counter)
if (counter < stop)
setTimeout(() => countCounter(element), 150);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span data-stop="3256986">3256700</span> Total downloads
<br>
CodePudding user response:
To replicate what you have in the GIF, you could create a simple 1-second interval that changes the value of an element's textContent property. Below is a simple approach. You should update it to make sure the start value and end value are valid, etc.
// Specify a selector, start/end numbers, and increment size
graduallyIncrement(".number", 1234, 1498, 15);
function graduallyIncrement ( selector, start, end, incrementBy ) {
// Start with an initial value, and an element reference
let currentValue = start;
let element = document.querySelector(selector);
// Update our element to show our initial value
element.textContent = currentValue.toLocaleString();
// Create an interval to run every 1 second
let interval = setInterval(() => {
// Determine next number. This may be our current
// number 15, or it may be the end number.
let nextNumber = Math.min(end, currentValue = incrementBy);
// Update our element to show the new number
element.textContent = nextNumber.toLocaleString();
// Determine whether or not to stop updating
if ( nextNumber === end ) {
clearInterval(interval);
}
}, 1000);
}
<div >1,243,234</div>
Other ways to improve would be to make this a Promise, which resolves when the final number is met. Or pass it a callback function which can be called once the process is complete. Here's how you could use Promises to determine when the counting has completed:
graduallyIncrement(".number", 1234, 1498, 15).then(() => {
alert("Done counting!");
});
async function graduallyIncrement(selector, current, end, incrementBy) {
// Start with an initial value, and an element reference
let element = document.querySelector(selector);
// Update our element to show our initial value
element.textContent = current.toLocaleString();
return new Promise(resolve => {
// Create an interval to run every 1 second
let interval = setInterval(() => {
// Determine next number. This may be our current
// number 15, or it may be the end number.
current = Math.min(end, current = incrementBy);
// Update our element to show the new number
element.textContent = current.toLocaleString();
// Using a setTimeout lets the textContent update
// complete before we show our ALERT
setTimeout(() => {
// Determine whether or not to stop updating
if (current === end) {
clearInterval(interval);
resolve();
}
}, 0);
}, 1000);
});
}