I see this style of momentum style scrolling on desktop a lot using transform: translate
and I really like the smoothness of the effect. I have attempted this using requestAnimationFrame and css transitions for the easing effect. In webkit browsers the effect is silky smooth and works well. The issue is with Firefox and edge. It is kind of jumpy and not as buttery smooth.
My question is there a better way to go about this or am I missing something that I should be doing. I can't pinpoint the issue with Firefox. I don't know if css transitions are the issue or not. Here is crude sample of what I am trying to acheive:
Here is a codepen Codepen
and here is a snippet:
//Momentum Scrolling
const requestAnimationFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame;
const wrapper = document.querySelector(".wrapper"),
target = document.getElementsByTagName("body")[0];
let easing = "cubic-bezier(0.23, 1, 0.32, 1)",
duration = "1s",
lastScrollY = window.scrollY,
pos = 0;
const init = () => {
target.style.height = wrapper.offsetHeight + "px";
target.style.overflow = "auto";
wrapper.style.transition = "transform " + duration + " " + easing;
wrapper.style.position = "fixed";
wrapper.style.top = "0";
wrapper.style.left = "0";
wrapper.style.width = "100%";
wrapper.style.padding = "0";
wrapper.style.zIndex = "2";
wrapper.style.display = "block";
wrapper.style.backfaceVisibility = "hidden";
loop();
window.addEventListener("resize", () => {
target.style.height = wrapper.offsetHeight + "px";
});
};
const onScroll = scrollY => {
pos = -(scrollY || document.documentElement.scrollTop);
wrapper.style.transform = "translateY(" + pos + "px)";
};
const loop = () => {
let scrollY = window.scrollY;
if (lastScrollY === scrollY) {
requestAnimationFrame(loop);
return;
} else {
lastScrollY = scrollY;
onScroll(scrollY);
requestAnimationFrame(loop);
}
};
init();
//Simple Parallax
const parallaxVert = document.querySelector('.parallax-vert');
const parallaxHor = document.querySelector('.parallax-hor');
window.addEventListener('scroll', function() {
parallaxVert.style.transform = `translateY(-${window.scrollY / 8}px)`;
parallaxHor.style.transform = `translateX(-${window.scrollY / 12}px)`;
});
body{
font-family: 'Anton', san-serif;
font-size: 40px;
}
.fixed{
position:fixed;
top:30px;
right: 40px;
width: 100px;
height: 60px;
background: white;
box-shadow: 0 10px 15px rgba(0,0,0,0.1);
z-index: 4;
}
.box{
height: 100vh;
margin: 2rem;
background: blue;
color:white;
display:flex;
align-items:center;
justify-content:center;
padding: 1rem;
text-align:center;
}
.parallax{
margin-left: 30%;
background: green;
transition: transform 1s cubic-bezier(0.23, 1, 0.32, 1);
}
<div class="fixed"></div>
<div class="wrapper">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="box">
Here is some content.
</div>
<div class="box parallax parallax-vert">
Here is some content.
</div>
<div class="box">
Here is some content.
</div>
<div class="box parallax parallax-hor">
Here is some content.
</div>
<div class="box">
Here is some content.
</div>
</div>
</div>
</div>
</div>
Any guidance would be much appreciated. I could really use someone to steer me in the right direction or show me an example so I don't waste any more time on this. Does anyone have any experience with this type of scrolling effect?