Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ScrollTo with animation

how can i add an easing/animation/slowly moving to this function? At the moment it just jumps. Now it should move to the "anchor" with an animation.

<script type='text/javascript'>
        setTimeout("window.scrollBy(0,270);",3000);
</script>
like image 237
Max Avatar asked Aug 30 '12 14:08

Max


2 Answers

also possible with plain javascript using request animation frame..

// first add raf shim
// http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

// main function
function scrollToY(scrollTargetY, speed, easing) {
    // scrollTargetY: the target scrollY property of the window
    // speed: time in pixels per second
    // easing: easing equation to use

    var scrollY = window.scrollY,
        scrollTargetY = scrollTargetY || 0,
        speed = speed || 2000,
        easing = easing || 'easeOutSine',
        currentTime = 0;

    // min time .1, max time .8 seconds
    var time = Math.max(.1, Math.min(Math.abs(scrollY - scrollTargetY) / speed, .8));

    // easing equations from https://github.com/danro/easing-js/blob/master/easing.js
    var PI_D2 = Math.PI / 2,
        easingEquations = {
            easeOutSine: function (pos) {
                return Math.sin(pos * (Math.PI / 2));
            },
            easeInOutSine: function (pos) {
                return (-0.5 * (Math.cos(Math.PI * pos) - 1));
            },
            easeInOutQuint: function (pos) {
                if ((pos /= 0.5) < 1) {
                    return 0.5 * Math.pow(pos, 5);
                }
                return 0.5 * (Math.pow((pos - 2), 5) + 2);
            }
        };

    // add animation loop
    function tick() {
        currentTime += 1 / 60;

        var p = currentTime / time;
        var t = easingEquations[easing](p);

        if (p < 1) {
            requestAnimFrame(tick);

            window.scrollTo(0, scrollY + ((scrollTargetY - scrollY) * t));
        } else {
            console.log('scroll done');
            window.scrollTo(0, scrollTargetY);
        }
    }

    // call it once to get started
    tick();
}

// scroll it!
scrollToY(0, 1500, 'easeInOutQuint');
like image 159
shunryu111 Avatar answered Oct 01 '22 09:10

shunryu111


For anyone viewing this question in 2019: this can now be done natively by using

window.scrollBy({
    top: 0,
    left: 270,
    behavior: 'smooth'
});

This works in all major browsers except edge and safari. See https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy#Examples

like image 31
xnim Avatar answered Oct 01 '22 08:10

xnim