/* scrollorama - The jQuery plugin for doing cool scrolly stuff by John Polacek (@johnpolacek) Dual licensed under MIT and GPL. */ (function($) { $.scrollorama = function(options) { var scrollorama = this, blocks = [], browserPrefix = '', onBlockChange = function() {}, latestKnownScrollY = 0, ticking = false, requestAnimFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function( callback ){ window.setTimeout(callback, 1000 / 60); }, defaults = {offset:0, enablePin: true}; scrollorama.settings = $.extend({}, defaults, options); scrollorama.blockIndex = 0; if (options.blocks === undefined) { alert('ERROR: Must assign blocks class selector to scrollorama plugin'); } // PRIVATE FUNCTIONS function init() { var i, block, didScroll = false; if (typeof scrollorama.settings.blocks === 'string') { scrollorama.settings.blocks = $(scrollorama.settings.blocks); } // set browser prefix if ($.browser.mozilla) { browserPrefix = '-moz-'; } if ($.browser.webkit) { browserPrefix = '-webkit-'; } if ($.browser.opera) { browserPrefix = '-o-'; } if ($.browser.msie) { browserPrefix = '-ms-'; } // create blocks array to contain animation props $('body').css('position','relative'); for (i=0; i'); latestKnownScrollY = 0; ticking = false; $(window).scroll( onScroll ); } function onScroll() { latestKnownScrollY = window.scrollY; requestTick(); } function requestTick() { if(!ticking) { requestAnimFrame(function(){ onScrollorama(); update(); }); } ticking = true; } function update() { // reset the tick so we can // capture the next onScroll ticking = false; } function onScrollorama() { var scrollTop = $(window).scrollTop(), currBlockIndex = getCurrBlockIndex(scrollTop), i, j, anim, startAnimPos, endAnimPos, animPercent, animVal; // update all animations for (i=0; i currBlockIndex) { if (currBlockIndex !== i-1 && anim.baseline !== 'bottom') { setProperty(anim.element, anim.property, anim.startVal); } if (blocks[i].pin) { blocks[i].block .css('position', 'absolute') .css('top', blocks[i].top); } } // if below current block, settings should be at end value // unless on an element that gets animated when it hits the bottom of the viewport else if (i < currBlockIndex) { setProperty(anim.element, anim.property, anim.endVal); if (blocks[i].pin) { blocks[i].block .css('position', 'absolute') .css('top', (blocks[i].top + blocks[i].pin)); } } // otherwise, set values per scroll position if (i === currBlockIndex || (currBlockIndex === i-1 && anim.baseline === 'bottom')) { // if block gets pinned, set position fixed if (blocks[i].pin && currBlockIndex === i) { blocks[i].block .css('position', 'fixed') .css('top', 0); } // set start and end animation positions startAnimPos = blocks[i].top + anim.delay; if (anim.baseline === 'bottom') { startAnimPos -= $(window).height(); } endAnimPos = startAnimPos + anim.duration; // if scroll is before start of animation, set to start value if (scrollTop < startAnimPos) { setProperty(anim.element, anim.property, anim.startVal); } // if scroll is after end of animation, set to end value else if (scrollTop > endAnimPos) { setProperty(anim.element, anim.property, anim.endVal); if (blocks[i].pin) { blocks[i].block .css('position', 'absolute') .css('top', (blocks[i].top + blocks[i].pin)); } } // otherwise, set value based on scroll else { // calculate percent to animate animPercent = (scrollTop - startAnimPos) / anim.duration; // account for easing if there is any if ( anim.easing && $.isFunction( $.easing[anim.easing] ) ) { animPercent = $.easing[anim.easing]( animPercent, animPercent*1000, 0, 1, 1000 ); } // then multiply the percent by the value range and calculate the new value animVal = anim.startVal + (animPercent * (anim.endVal - anim.startVal)); setProperty(anim.element, anim.property, animVal); } } } } } // update blockIndex and trigger event if changed if (scrollorama.blockIndex !== currBlockIndex) { scrollorama.blockIndex = currBlockIndex; onBlockChange(); } } function getCurrBlockIndex(scrollTop) { var currBlockIndex = 0, i; for (i=0; i 0) { for (j=0; j