Tuesday, 29 September 2020

How to get the exact smooth scrolling functionality of Chrome?

When the user clicks a button on my page it creates a new element below it and then scrolls downwards towards it. I'd like this to be done smoothly, and that can be accomplished like so:

window.scroll({ top: document.body.scrollHeight, behavior: "smooth" });

However, this does not work on Safari, so it appears that I need to use a custom function instead to get this functionality.

I searched around and found this (current answer, but suboptimal):

doScrolling = (elementY, duration) => { 
  let startingY = window.pageYOffset;
  let diff = elementY - startingY;
  var start;

  // Bootstrap our animation - it will get called right before next frame shall be rendered.
  window.requestAnimationFrame(function step(timestamp) {
    if (!start) { start = timestamp; }
    // Elapsed milliseconds since start of scrolling.
    let time = timestamp - start;
    // Get percent of completion in range [0, 1].
    let percent = Math.min(time / duration, 1);

    window.scrollTo(0, startingY + diff * percent);

    let isScrollAtBottom = (window.innerHeight + window.pageYOffset) >= document.body.scrollHeight - 3;

    if (isScrollAtBottom) { return; }

    // Proceed with animation as long as we wanted it to.
    if (time < duration) {
      window.requestAnimationFrame(step);
    }
  })
}

Called like: this.doScrolling(document.body.scrollHeight, 750);

Which seems to work, but it doesn't seem to have the same semantics as window.scroll.

For one, you need to specify a duration, whereas with window.scroll it's implied.

Secondly, it seems as if window.scroll uses a different transition type? It's hard to tell, but it feels more like an ease as opposed to a linear transition, where it starts off slow, then goes fast, and then slows to a stop.

Is it possible to modify the above function to mimic the exact semantics of window.scroll such that you can't tell the difference between calling the two?

To clarify, I don't need to clone all the functionalities of window.scroll. The only thing I require is the ability to scroll to a given position (in my case it's always the end of the page) in a smooth manner. The function I provided above in my question is almost perfect, except that it's slightly janky and doesn't feel as smooth as window.scroll. I think it may be the animation style? It's kind of hard to tell why it looks "worse" since it's so fast.



from How to get the exact smooth scrolling functionality of Chrome?

No comments:

Post a Comment