4

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?

Steve K
  • 6,610
  • 2
  • 14
  • 28

1 Answers1

3

What version of FF are you using ?

About Edge, there have been some issues with requestAnimation frame, instead of

Scroll event > requestAnimationFrame > Paint

you can get

Scroll event > Paint > requestAnimationFrame

As you can see in performance inspector:

enter image description here

May be this is the cause of your issue on Edge.

Mosè Raguzzini
  • 12,776
  • 26
  • 36
  • 1
    I am using the latest version 71.0 of firefox and at first glance it looks smooth but you can see when overlap begins there is a stutter. This becomes more pronounced as more elements begin overlaping. It is not an issue with the actual overlap I think it is an issue with the css easing effect. I have created my own easing with javascript using a delta value and the stutter seems to go away so I'm kind of assuming that there is a css easing issue in firefox. Also if you compare the easing to webkit it is a considerably different effect so idk how firefox calculates easing. – Steve K Dec 10 '19 at 16:42