title: How to implement a smooth scroll using requestAnimationFrame?
body: <p>I want to make a good smooth scroll effect in my webpage, and I see that one of the best way is using the requestAnimationFrame.</p>
  
  <p>I found this polyfill by Jed Schmidt: <a href="https://gist.github.com/997619" rel="nofollow">https://gist.github.com/997619</a></p>
  
  <p>And this one by Paul Irish: <a href="http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/" rel="nofollow">http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/</a></p>
  
  <p>But to be honest, I don't know how to use it to create the smooth effect. In the past I checked some plugins: nicescroll (I don't like it because it changes the scrollbar style), smoothscroll.js (this one only works on Chrome), and some others that only work on mousewheel, but not when you click the Re Pag, Av Pag, the spacebar, etc.</p>
  
  <p>I can provide an example on this page: <a href="http://cirkateater.no/" rel="nofollow">http://cirkateater.no/</a> The scroll effect is really nice and works efficiently. It's also cross browser! But taking a look in its JS code, I only see a huge function for parallax, and I'm not sure if what I want is into this function.</p>
  
  <p>Could you tell me where I start? I will update the progress here.</p>
  
  <p>PD: Actually, I've spent a day trying to implement it through non-sense actions about copy-paste into my scripts.js file. I'm not an expert on JS, but I deduce it's something difficult to do.</p>
  
  <p><strong>Edit 1:</strong> I already have something. First, the polyfill:</p>
  
  <pre><code>(function() {
  var lastTime = 0;
  var vendors = ['ms', 'moz', 'webkit', 'o'];
  for(var x = 0; x &lt; vendors.length &amp;&amp; !window.requestAnimationFrame; ++x) {
      window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
      window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
                                 || window[vendors[x]+'CancelRequestAnimationFrame'];
  }
  
  if (!window.requestAnimationFrame)
      window.requestAnimationFrame = function(callback, element) {
          var currTime = new Date().getTime();
          var timeToCall = Math.max(0, 16 - (currTime - lastTime));
          var id = window.setTimeout(function() { callback(currTime + timeToCall); },
            timeToCall);
          lastTime = currTime + timeToCall;
          return id;
      };
  
  if (!window.cancelAnimationFrame)
      window.cancelAnimationFrame = function(id) {
          clearTimeout(id);
      };
  }());
  </code></pre>
  
  <p>And the smooth mouse wheel:</p>
  
  <pre><code>var html = document.documentElement;
  var rAF, target = 0, scroll = 0;
  
  onmousewheel = function (e) {
  e.preventDefault();
  var scrollEnd = html.scrollHeight - html.clientHeight;
  target += (e.wheelDelta &gt; 0) ? -70 : 70;
  if (target &lt; 0)
      target = 0;
  if (target &gt; scrollEnd)
      target = scrollEnd;
  if (!rAF)
      rAF = requestAnimationFrame(animate);
  };
  
  onscroll = function () {
  if (rAF)
      return;
  target = pageYOffset || html.scrollTop;
  scroll = target;
  };
  
  function animate() {
  scroll += (target - scroll) * 0.1;
  if (Math.abs(scroll.toFixed(5) - target) &lt;= 0.47131) {
      cancelAnimationFrame(rAF);
      rAF = false;
  }
  scrollTo(0, scroll);
  if (rAF)
      rAF = requestAnimationFrame(animate);
  }
  </code></pre>
  
  <p>We can begin from here. Now I only need to make a better improvement to have this smooth effect when I press the arrow keys, Re Page, Av Page, etc.</p>