scroll / scale

by desandro

HTML

<div id="container"><div id="box"></div></div>

<ul id="nav">
    <li><a href="#0">Jump to 0</a></li>
    <li><a href="#1">Jump to 1</a></li>
    <li><a href="#2">Jump to 2</a></li>
    <li><a href="#3">Jump to 3</a></li>
    <li><a href="#4">Jump to 4</a></li>
</ul>

CSS

body {
  height: 2000px;
}

#container {
  width: 200px;
  height: 200px;
  border: 2px solid;
  position: fixed;
}

#box {
  width: 100%;
  height: 100%;
  background: red;
}

#box.transitions-enabled {
  -webkit-transition: -webkit-transform 1s;
     -moz-transition:    -moz-transform 1s;
       -o-transition:      -o-transform 1s;
          transition:         transform 1s;
}

#nav {
  position: fixed;
  left: 230px;
}

JavaScript

window.addEventListener( 'load', function() {
  var box = document.getElementById('box'),
      docHeight = document.documentElement.offsetHeight;
  
  window.addEventListener( 'scroll', function() {
        // normalize scroll position as percentage
    var scrolled = window.scrollY / ( docHeight - window.innerHeight ),
        transformValue = 'scale('+(1-scrolled)+')';

    box.style.WebkitTransform = transformValue;
    box.style.MozTransform = transformValue;
    box.style.OTransform = transformValue;
    box.style.transform = transformValue;
    
  }, false);
  
  document.getElementById('nav').addEventListener( 'click', function(event) {
    var level = parseInt( event.target.getAttribute('href').slice(1), 10 ),
        // normalize scroll position
        scrollY = ( level / 4 ) * ( docHeight - window.innerHeight );
    // enable transitions
    box.className = 'transitions-enabled';
    // change scroll position
    window.scrollTo( 0, scrollY );
  }, false);
  
  function transitionEnded(event) {
    // disable transition
    box.className = '';
  }
  
  box.addEventListener( 'webkitTransitionEnd', transitionEnded, false);
  box.addEventListener( 'transitionend', transitionEnded, false);
  box.addEventListener( 'oTransitionEnd', transitionEnded, false);
  
}, false);