2022-05-13 04:21:08 +00:00
|
|
|
/**
|
2024-05-26 03:18:18 +00:00
|
|
|
* Initialize a direction observer based on scroll behavior.
|
2022-11-10 01:02:21 +00:00
|
|
|
*
|
2024-05-26 03:18:18 +00:00
|
|
|
* @param {Function} onScrollDown - Function to be called when scrolling down.
|
|
|
|
* @param {Function} onScrollUp - Function to be called when scrolling up.
|
|
|
|
* @param {number} threshold - The threshold for significant scroll position change.
|
2024-11-07 00:31:49 +00:00
|
|
|
* @return {Object}
|
2022-11-10 01:02:21 +00:00
|
|
|
*/
|
2024-11-07 00:31:49 +00:00
|
|
|
function initDirectionObserver( onScrollDown, onScrollUp, threshold = 0 ) {
|
2024-11-02 05:59:17 +00:00
|
|
|
let lastScrollTop = 0;
|
2024-11-02 06:24:54 +00:00
|
|
|
let lastScrollDirection = '';
|
2024-11-02 05:59:17 +00:00
|
|
|
let isScrolling = false;
|
2024-11-02 06:24:54 +00:00
|
|
|
|
2024-11-07 00:31:49 +00:00
|
|
|
const handleScroll = () => {
|
|
|
|
const currentScrollTop = window.scrollY;
|
|
|
|
|
|
|
|
if ( Math.abs( currentScrollTop - lastScrollTop ) < threshold ) {
|
|
|
|
isScrolling = false;
|
|
|
|
return;
|
|
|
|
}
|
2022-11-10 01:02:21 +00:00
|
|
|
|
2024-11-07 00:31:49 +00:00
|
|
|
if ( currentScrollTop > lastScrollTop && lastScrollDirection !== 'down' ) {
|
|
|
|
lastScrollDirection = 'down';
|
|
|
|
onScrollDown();
|
|
|
|
} else if ( currentScrollTop < lastScrollTop && lastScrollDirection !== 'up' ) {
|
|
|
|
lastScrollDirection = 'up';
|
|
|
|
onScrollUp();
|
|
|
|
}
|
|
|
|
lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop;
|
|
|
|
isScrolling = false;
|
|
|
|
};
|
2022-11-10 01:02:21 +00:00
|
|
|
|
2024-11-07 00:31:49 +00:00
|
|
|
const onScroll = () => {
|
|
|
|
if ( !isScrolling ) {
|
|
|
|
window.requestAnimationFrame( handleScroll );
|
2024-11-02 05:59:17 +00:00
|
|
|
isScrolling = true;
|
2022-11-10 01:02:21 +00:00
|
|
|
}
|
2024-11-07 00:31:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
|
|
|
resume: () => {
|
|
|
|
window.addEventListener( 'scroll', onScroll );
|
|
|
|
},
|
|
|
|
pause: () => {
|
|
|
|
window.removeEventListener( 'scroll', onScroll );
|
|
|
|
}
|
|
|
|
};
|
2022-11-10 01:02:21 +00:00
|
|
|
}
|
|
|
|
|
2024-09-10 22:28:12 +00:00
|
|
|
/**
|
|
|
|
* Create an observer for showing/hiding feature and for firing scroll event hooks.
|
|
|
|
*
|
|
|
|
* @param {Function} show functionality for when feature is visible
|
|
|
|
* @param {Function} hide functionality for when feature is hidden
|
|
|
|
* @return {IntersectionObserver}
|
|
|
|
*/
|
|
|
|
function initScrollObserver( show, hide ) {
|
|
|
|
/* eslint-disable-next-line compat/compat */
|
|
|
|
return new IntersectionObserver( ( entries ) => {
|
|
|
|
if ( !entries[ 0 ].isIntersecting && entries[ 0 ].boundingClientRect.top < 0 ) {
|
|
|
|
// Viewport has crossed the bottom edge of the target element.
|
|
|
|
show();
|
|
|
|
} else {
|
|
|
|
// Viewport is above the bottom edge of the target element.
|
|
|
|
hide();
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
2022-05-13 04:21:08 +00:00
|
|
|
module.exports = {
|
2022-11-10 01:02:21 +00:00
|
|
|
initDirectionObserver,
|
2024-09-10 22:28:12 +00:00
|
|
|
initScrollObserver
|
2022-05-13 04:21:08 +00:00
|
|
|
};
|