194 lines
5.3 KiB
JavaScript
194 lines
5.3 KiB
JavaScript
CNVS.ScrollDetect = function() {
|
|
var __core = SEMICOLON.Core;
|
|
|
|
var _detects = [];
|
|
|
|
var _percent = function(params) {
|
|
var percent = 0,
|
|
ratio = 0,
|
|
start = 0,
|
|
end = 0;
|
|
|
|
var onScroll = function(params) {
|
|
fastdom.measure( function(){
|
|
var position = window.scrollY;
|
|
|
|
if( position >= params.start && position <= params.end ) {
|
|
var startViewScroll = position - params.start;
|
|
var offsetScroll = position - params.offset;
|
|
percent = (startViewScroll / params.range.full) * 100;
|
|
start = (startViewScroll / params.range.start);
|
|
|
|
if( position > (params.start + params.height) && position < (params.offset) ) {
|
|
start = 1;
|
|
end = 0;
|
|
} else if( position >= (params.offset) ) {
|
|
start = 1;
|
|
end = (offsetScroll / params.range.end);
|
|
} else {
|
|
end = 0;
|
|
}
|
|
|
|
ratio = start - end;
|
|
} else if( position > params.end ) {
|
|
percent = 100;
|
|
ratio = 0;
|
|
start = end = 1;
|
|
} else {
|
|
percent = ratio = start = end = 0;
|
|
}
|
|
|
|
if( ratio > 0 ) {
|
|
params.elem.classList.add('scroll-detect-inview');
|
|
} else {
|
|
params.elem.classList.remove('scroll-detect-inview');
|
|
}
|
|
|
|
if( start > 0 && start < 1 ) {
|
|
params.elem.classList.add('scroll-detect-inview-start');
|
|
} else {
|
|
params.elem.classList.remove('scroll-detect-inview-start');
|
|
}
|
|
|
|
if( end > 0 && end < 1 ) {
|
|
params.elem.classList.add('scroll-detect-inview-end');
|
|
} else {
|
|
params.elem.classList.remove('scroll-detect-inview-end');
|
|
}
|
|
|
|
params.elem.style.setProperty('--cnvs-scroll-percent', percent);
|
|
params.elem.style.setProperty('--cnvs-scroll-ratio', ratio);
|
|
params.elem.style.setProperty('--cnvs-scroll-start', start);
|
|
params.elem.style.setProperty('--cnvs-scroll-end', end);
|
|
});
|
|
};
|
|
|
|
onScroll(params);
|
|
};
|
|
|
|
var _handle = function() {
|
|
_detects.forEach( function(settings) {
|
|
_percent(settings);
|
|
});
|
|
}
|
|
|
|
return {
|
|
init: function(selector) {
|
|
if( __core.getSelector(selector, false, false).length < 1 ){
|
|
return true;
|
|
}
|
|
|
|
__core.loadJS({ file: 'plugins.fastdom.js', id: 'canvas-fastdom-js', jsFolder: true });
|
|
|
|
__core.isFuncTrue( function() {
|
|
return typeof fastdom !== 'undefined';
|
|
}).then( function(cond) {
|
|
if( !cond ) {
|
|
return false;
|
|
}
|
|
|
|
__core.initFunction({ class: 'has-plugin-scrolldetect', event: 'pluginScrollDetectReady' });
|
|
|
|
selector = __core.getSelector( selector, false );
|
|
if( selector.length < 1 ){
|
|
return true;
|
|
}
|
|
|
|
var resizeObserver = new ResizeObserver( function(entries) {
|
|
entries.forEach( function(entry) {
|
|
if( !doing ) {
|
|
var doing = setTimeout( function() {
|
|
initParams(selector);
|
|
doing = false;
|
|
}, 333);
|
|
}
|
|
});
|
|
});
|
|
|
|
var initParams = function(selector) {
|
|
_detects = [];
|
|
|
|
selector.forEach( function(elem) {
|
|
var elemWidth = elem.offsetWidth,
|
|
elemHeight = elem.offsetHeight,
|
|
elemOffset = __core.offset(elem).top,
|
|
viewportHeight = __core.getVars.viewport.height,
|
|
includeWidth = elem.getAttribute('data-include-width'),
|
|
includeHeight = elem.getAttribute('data-include-height'),
|
|
includeOffset = elem.getAttribute('data-include-offset'),
|
|
scrollOffset = elem.getAttribute('data-scroll-offset'),
|
|
parallaxRatio = elem.getAttribute('data-parallax-ratio'),
|
|
params = {};
|
|
|
|
if( scrollOffset ) {
|
|
scrollOffset = scrollOffset.split('%');
|
|
|
|
if( scrollOffset.length > 1 ) {
|
|
elemOffset = elemOffset + (viewportHeight * Number(scrollOffset[0]) * 0.01);
|
|
} else if( scrollOffset.length == 1 && scrollOffset[0] ) {
|
|
elemOffset = elemOffset + Number(scrollOffset[0]);
|
|
}
|
|
}
|
|
|
|
var scrollStart = elemOffset - viewportHeight,
|
|
scrollEnd = elemOffset + elemHeight,
|
|
scrollRange = scrollEnd - scrollStart;
|
|
|
|
params.elem = elem;
|
|
params.start = scrollStart;
|
|
params.end = scrollEnd;
|
|
params.range = {
|
|
start: elemHeight,
|
|
end: elemHeight,
|
|
full: scrollRange,
|
|
};
|
|
params.width = elemWidth;
|
|
params.height = elemHeight;
|
|
params.offset = elemOffset;
|
|
|
|
if( includeWidth == 'true' || (elem.classList.contains('parallax') && elem.getAttribute('data-parallax-direction') == 'horizontal') ) {
|
|
elem.style.setProperty('--cnvs-scroll-width', params.width);
|
|
}
|
|
|
|
if( includeHeight == 'true' || (elem.classList.contains('parallax') && elem.getAttribute('data-parallax-direction') != 'horizontal') ) {
|
|
elem.style.setProperty('--cnvs-scroll-height', params.height);
|
|
}
|
|
|
|
if( includeOffset == 'true' ) {
|
|
elem.style.setProperty('--cnvs-scroll-offset', params.offset);
|
|
}
|
|
|
|
if( !isNaN(parallaxRatio) ) {
|
|
elem.style.setProperty('--cnvs-parallax-ratio', parallaxRatio);
|
|
}
|
|
|
|
_percent(params);
|
|
_detects.push(params);
|
|
|
|
resizeObserver.observe(elem);
|
|
});
|
|
};
|
|
|
|
initParams(selector);
|
|
_handle();
|
|
|
|
// var ticking = false;
|
|
window.addEventListener("scroll", function(){
|
|
fastdom.mutate( function(){
|
|
_handle();
|
|
});
|
|
// if (!ticking) {
|
|
// window.requestAnimationFrame( function(){
|
|
// _handle();
|
|
// ticking = false;
|
|
// });
|
|
// ticking = true;
|
|
// }
|
|
}, {passive: true});
|
|
|
|
resizeObserver.observe(document.documentElement);
|
|
});
|
|
}
|
|
};
|
|
}();
|