[javascript] scroll delle pagine con ease

Non avendo trovato nessuno script degno di nota per fare lo scrolling animato con ease-in-out di una pagina web in vanilla javascript (maledizione, gira solo del gran jQuery lì fuori), me lo sono scritto da solo.
	function kScrollTo(to, callback) {
    if(typeof(to) == "object") to = kGetPosition(to).top;
    if(to > document.body.scrollHeight - document.body.offsetHeight) to = document.body.scrollHeight - document.body.offsetHeight;
    if(!callback) var callback = function() {};

    var duration = 1000,
        start = null,
        from = window.scrollY;

    var easeInOutCubic=function (t)
    {
        return Math.ceil((t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1)*1000)/1000;
    }

 function scroll(timestamp) {
        if(!start) start = timestamp;

        if(timestamp-start > duration)
        {
            callback();
            return;
        }
        
        var movement = (to - from) * easeInOutCubic(1/duration*(timestamp-start));
        window.scrollTo(0, from + movement);

        requestAnimationFrame(scroll);
 }

 requestAnimationFrame(scroll);
}

function kGetPosition(obj)
{
    var pos={left:0,top:0};
    if(obj)
    {
        while(obj.offsetParent)
        {
            pos.left+=obj.offsetLeft-obj.scrollLeft;
            pos.top+=obj.offsetTop-obj.scrollTop;
            var tmp=obj.parentNode;
            while(tmp!=obj.offsetParent)
            {
                pos.left-=tmp.scrollLeft;
                pos.top-=tmp.scrollTop;
                tmp=tmp.parentNode;
            }
            obj=obj.offsetParent;
        }
        pos.left+=obj.offsetLeft;
        pos.top+=obj.offsetTop;
    }
    return pos;
}

Accetta due parametri in ingresso:

  1. to: la destinazione dello scroll. Si può passare un integer, i pixel dal bordo superiore della pagina, o un object, un puntatore all'elemento da raggiungere.
  2. callback (opzionale) : una funzione da eseguire al completamento dello scroll

Si può modificare la variabile duration, inserendo i millisecondi della durata totale dell'animazione.

Esempi:

kScrollTo( 600 ); // scrolla fino a 600 px di distanza

kScrollTo( document.getElementById('header')); // scrolla fino a <div id="header">

kScrollTo( 600, function() { console.log('mi sono scrollato'); }) // scrive in console dopo aver finito lo scroll