Created
May 20, 2021 14:21
-
-
Save elpuas/f33b3007fd0b49c64dc14615b41937bd to your computer and use it in GitHub Desktop.
counter with intersection observer
This file contains hidden or 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
// How long you want the animation to take, in ms | |
const animationDuration = 2000; | |
// Calculate how long each ‘frame’ should last if we want to update the animation 60 times per second | |
const frameDuration = 1000 / 60; | |
// Use that to calculate how many frames we need to complete the animation | |
const totalFrames = Math.round( animationDuration / frameDuration ); | |
// An ease-out function that slows the count as it progresses | |
const easeOutQuad = t => t * ( 2 - t ); | |
// Variables | |
const isEditor = document.querySelector( '.wp-editor-element-class' ); | |
const target = document.querySelector('.wp-block-container-class'); | |
const adgrBlocksCalloutCard = { | |
init: () => { | |
/** | |
* Animate Numbers | |
* | |
* @param {object} el Element to animate. | |
*/ | |
const animateCountUp = el => { | |
let frame = 0; | |
const countTo = parseInt( el.innerHTML, 10 ); | |
// Start the animation running 60 times per second. | |
const counter = setInterval( () => { | |
frame++; | |
// Calculate our progress as a value between 0 and 1 | |
// Pass that value to our easing function to get our | |
// progress on a curve | |
const progress = easeOutQuad( frame / totalFrames ); | |
// Use the progress value to calculate the current count | |
const currentCount = Math.round( countTo * progress ); | |
// If the current count has changed, update the element | |
if ( parseInt( el.innerHTML, 10 ) !== currentCount ) { | |
el.innerHTML = currentCount; | |
} | |
// If we’ve reached our last frame, stop the animation | |
if ( frame === totalFrames ) { | |
clearInterval( counter ); | |
} | |
}, frameDuration ); | |
}; | |
/** | |
* Run the animation on all elements with a class of ‘countup'. | |
* | |
*/ | |
const runAnimations = () => { | |
const countupEls = document.querySelectorAll( '.countup' ); | |
countupEls.forEach( animateCountUp ); | |
}; | |
/** | |
* The callback will return an array of entries, even if you are only observing a single item. | |
* | |
* @param {array} entries array of entries. | |
*/ | |
const handleIntersection = ( entries ) => { | |
entries.map( ( entry ) => { | |
if ( entry.isIntersecting ) { | |
runAnimations(); | |
} | |
}); | |
} | |
// Next we instantiate the observer with the function we created above. | |
// This takes an optional configuration object that we will use in the other examples. | |
const observer = new IntersectionObserver( handleIntersection ); | |
// Finally start observing the target element. | |
if ( null === isEditor && target ) { | |
observer.observe(target); | |
} | |
} | |
} | |
export default adgrBlocksCalloutCard; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment