I'm trying to migrate some jQuery code that performs a smooth scroll (back and forth) in an horizontal image gallery when clicking over its images (putting the clicked image in the center of the browser viewport):
jQuery:
$('.page-template-format-horizontal .exhibit-image').on('click', function (e) {
var slideWidth = $(this).width();
var windowWidth = $(window).width();
var scrollTo = $(this).position().left;
var offset = scrollTo - (windowWidth / 2) (slideWidth / 2);
$('html, body').animate({
scrollLeft: offset
}, 500);
e.preventDefault();
});
This is the vanilla JS code I've come up with. I know that I can use the behaviour: 'smooth'
option in the window.scrollBy()
function, but I'd like to use the window.requestAnimationFrame()
function instead because I need to support some older Safari versions that don't support the smooth behavior option.
JS:
document.querySelector('.page-template-format-horizontal .exhibit-image').addEventListener('click', function (e) {
var slideWidth = e.currentTarget.getBoundingClientRect().width;
var windowWidth = window.innerWidth;
var scrollTo = e.currentTarget.offsetLeft;
var offset = scrollTo - (windowWidth / 2) (slideWidth / 2);
var duration = 50;
var startLocation = window.pageXOffset;
var endLocation = offset;
var distance = endLocation - startLocation;
var increments = distance / (duration / 16);
function step() {
window.scrollBy(increments, 0);
if ( window.pageXOffset <= endLocation) {
window.requestAnimationFrame(step);
}
}
window.requestAnimationFrame(step);
e.preventDefault();
});
It quite works, but just when scrolling to the right, not to the left. Any help would be appreciated.
CodePudding user response:
I managed to solve this myself. This is the code I came up with:
document.querySelectorAll('.page-template-format-horizontal .exhibit-image').forEach(function(item) {
item.addEventListener('click', function (e) {
var slideWidth = e.currentTarget.getBoundingClientRect().width;
var windowWidth = window.innerWidth;
var scrollTo = e.currentTarget.offsetLeft;
var startLocation = window.pageXOffset;
var endLocation = scrollTo - (windowWidth / 2) (slideWidth / 2);
var distance = endLocation - startLocation;
var duration = 400;
var easing = function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2) 1 }
var start;
if (!distance) {
return;
}
function step(timestamp) {
start = start || timestamp;
var time = timestamp - start;
var percent = Math.min(time / duration, 1);
percent = easing(percent);
window.scrollTo(parseInt(startLocation distance * percent), window.scrollY);
if (time < duration) {
window.requestAnimationFrame(step);
}
}
window.requestAnimationFrame(step);
e.preventDefault();
});
});