Last active
February 7, 2019 15:21
-
-
Save benfrain/f7a9591b9db3f81bd6f6f34975d9cf80 to your computer and use it in GitHub Desktop.
JS utility to animate numeric values from one value to another
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* [animateNumericValues interpolates from one number to another with a max of 60 integers per second] | |
* @param {Element} element [The DOM element that will get interpolated] | |
* @param {number} fromValue [the first value] | |
* @param {number} toValue [the final value] | |
* @param {number} speed [how long the animation should take in milliseconds] | |
* @param {delay} delay [any delay before it starts counting up] | |
* @param {string} appendString [optional string that gets appended to the value. E.g. "%"] | |
*/ | |
function animateNumericValues({ | |
element = document.body, | |
fromValue = 0, | |
toValue = 0, | |
speed = 1000, | |
delay = 0, | |
format = {}, | |
appendString = "", | |
} = {}) { | |
// Ensure the numbers compute | |
if (fromValue > toValue || toValue < 1) { | |
console.warn("The from value is greater than than the too value or the toValue is less than 1"); | |
return; | |
} | |
// Create an array of all values between and including from and to | |
var arrayOfValuesFromTo = []; | |
for (let i = fromValue; i++ <= toValue; ) { | |
arrayOfValuesFromTo.push(i); | |
} | |
// Timing adjuster | |
let adjuster = speed / 1000; | |
// Reduce the number of items to around 60 | |
let reduceToSixty = arrayOfValuesFromTo.reduce((arr, idx, elem, original) => { | |
if (original.length <= 30) { | |
arr.push(elem); | |
return arr; | |
} | |
// We always want the first and last value | |
// Get the difference of from and to and divide by 60 and then push every one of those values into the array | |
if (idx === 1 || idx % Math.round((fromValue - toValue) / (10 * adjuster)) === 0) { | |
arr.push(elem); | |
} | |
// We want the actual value of the final one | |
if (idx === original.length) { | |
arr.push(toValue); | |
} | |
return arr; | |
}, []); | |
// Handle any delay | |
setTimeout(e => { | |
writeToDom(); | |
}, delay); | |
function writeToDom() { | |
// Write the values into the DOM | |
reduceToSixty.forEach((num, count) => { | |
setTimeout(() => { | |
element.textContent = `${num.toLocaleString("en-US", format)}${appendString}`; | |
}, (speed / reduceToSixty.length) * count); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You might want to pass in another parameter for the
toLocaleString
to vary the lang format.