I am currently try to develop a small lightweight vanilla-js parallax-library which gives the possibility to parallax elements (images, videos, sliders, ...) horizontally and vertically in both directions without any background-position things.
It works very well so far and does a great job expecting one important detail: Sometimes it's still laggy. I've tested it on Mac OS and iPhone, in Safari and Chromebrowser. For all the same.
I have tried to use the common practices like throttling, requestAnimationFrame and CSS's will-change but without success.
I am not sure, if it's possible to see the lags here in this video.
But I made an example where you could test it: https://codepen.io/flexplosion/pen/RwgQXxo?editors=1111
Someone has an idea, how I can improve the scrolling-performance for the parallax?
var parallaxes = document.getElementsByClassName('parallax');
const windowInnerHeight = window.innerHeight;
function throttle (callback, limit) {
var wait = false; // Initially, we're not waiting
return function () { // We return a throttled function
if (!wait) { // If we're not waiting
callback.call(); // Execute users function
wait = true; // Prevent future invocations
setTimeout(function () { // After a period of time
wait = false; // And allow future invocations
}, limit);
}
}
}
Array.from(parallaxes).forEach((parallax) => {
const movement = parseFloat(parallax.dataset.movement),
direction = parallax.dataset.direction,
element = parallax.children[0];
if( direction == 'horizontal' ) {
// Prepare for orzintal
element.style.height = '100%';
element.style.width = (100 + movement) + "%";
} else {
// Otherwise prepare for vertical
element.style.height = (100 + movement) + "%";
element.style.width = '100%';
}
});
const handleScroll = () => {
var parallaxes = document.getElementsByClassName('parallax');
Array.from(parallaxes).forEach((parallax) => {
const movement = parseFloat(parallax.dataset.movement),
direction = parallax.dataset.direction,
reverse = parallax.dataset.reverse === 'true',
element = parallax.children[0];
var containerReact = parallax.getBoundingClientRect();
var scrolledInContainer = 0 - (containerReact.top - windowInnerHeight);
var scrollArea = windowInnerHeight + containerReact.height;
var progress = scrolledInContainer / scrollArea;
var scrolledInContainer = window.pageYOffset - (containerReact.top - windowInnerHeight);
if(progress > 0 && progress < 1) {
requestAnimationFrame(() => {
var position = reverse
? movement * progress
: movement - movement * progress;
element.style[ direction == 'horizontal' ? 'left' : 'top'] = "-" + position + "%";
});
}
});
}
// Initialize
handleScroll();
// Hook into event
window.addEventListener('scroll', throttle(handleScroll, 10) );
UPDATE 1:
I tried to switch the script to use translate3d instead of top/left properties. The animation on Desktop (Chrome) is now ultra-smooth. Exactly how it should be. In Safari and all mobile Browsers it didn't really help...
https://codepen.io/flexplosion/pen/BaZrKYv
In Safari (same on mobile Chrome and Safari): https://jmp.sh/n4JG8J5 In Chrome: https://jmp.sh/EMM7y1Z
from Parallax-Animation with transform3d, throttle, requestAnimationFrame, will-change still laggy on Mobile and Desktop, Chrome and Safari
No comments:
Post a Comment