简体   繁体   中英

Smooth scrolling not so smooth

I have been trying to create a smooth scrolling with plain js. I tried it with typical animation timing using this:

function animate(x) {
    var start = new Date();
    var id = setInterval(function () {
        var timepassed = new Date() - start;
        var progress = timepassed / x.duration;
        if (progress > 1) {
            progress = 1;
        }
        var delta = x.delta(progress);
        x.step(delta);
        if (progress == 1) {
            clearInterval(id);
        }
    }, x.delay);
}

After that I'm measuring offsetTop elements and using scrollTo() to get there using window.scrollTo(0, delta * to.offsetTop); where delta is returned progress of time. But the problem is that it does not seem so smooth to my eyes. Am I missing some important information about animation?

Demo

(using else if to find out which way the anmiation should go - at least for now)

There are two aspects to your issue here:

  • Performance
  • Perceived smoothness

Performance

In your code you would gain performance by using requestAnimationFrame() instead of setInterval() . There is also a nice article for transitioning to the new method on mozilla or an in-depth article by Paul Irish . As a note: because you want to achieve 60fps, your code shouldn't take longer than 16ms calculation time.

Perceived animation smoothness & Easing

For the second issue: your animation is linear, thus it's boring. When (if you ever did) you use an animation-library or jQuery for some animation, you can always specify which timing-function the animation should use. These are for example 'ease-in', 'ease-out', and so on. You can implement these in your function through some math . There are many tools in the web which visualize these easing-equotations in different ways .

If you are now hungry for more input, check out Robert Penner's Easing Page .

Last, but not least, take a look at this gist , which also provides JavaScript-Implementation of the different easing functions - oh and also another possible solution in Vanilla JS ;)

ps just for demonstration, your code with a little ease

To branch on @Sebastian's answer here is a real quick demo of your code using window.requestAnimationFrame();

http://jsfiddle.net/xerxesnoble/e53qm15L/4/

More than just that, here is another simple way (using jQuery) to have a smooth scroll in your code:

https://css-tricks.com/snippets/jquery/smooth-scrolling/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM