Created
September 24, 2012 17:16
-
-
Save bpander/3777101 to your computer and use it in GitHub Desktop.
parallax framework for creating Tweens and Switches based on the user's scroll position
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* parallax.js | |
* @author Brad Anderson | |
* @description Tween elements based on the users scroll position or flip a switch when the user gets to a certain point in the page | |
* @requires Nothing | |
* @example | |
* var tween = new parallax.Tween( | |
document.getElementById('pizza'), | |
'left', | |
'0px', | |
'300px', | |
20, | |
220 | |
); | |
parallax.init(); | |
*/ | |
var parallax = (function() { | |
var parallax = {}; | |
var _tweens = []; | |
var _switches = []; | |
var _scrollTop = 0; | |
var _lastScrollTop = 0; | |
var _getSupportedProperty = function(property) { | |
var div = document.createElement('div'); | |
var supportedProperty = null; | |
if (property in div.style) { | |
supportedProperty = property; | |
} else { | |
var capitalizedProperty = property.charAt(0).toUpperCase() + property.slice(1); | |
var prefixes = ['Moz', 'Webkit', 'O', 'ms']; | |
var l = prefixes.length; | |
for (var i = 0; i < l; i++) { | |
var vendorProperty = prefixes[i] + capitalizedProperty; | |
if (vendorProperty in div.style) { | |
supportedProperty = vendorProperty; | |
break; | |
} | |
} | |
} | |
div = null; | |
return supportedProperty; | |
}; | |
var _transitionProperty = _getSupportedProperty('transition'); | |
var _defaultEasingFunction = function(p) { | |
return 0.5 + 0.5 * Math.sin(Math.PI * ( p - 0.5 )); | |
}; | |
/** | |
* Start listening for the scroll event, also figure out where all the elements need to be | |
*/ | |
parallax.init = function() { | |
_onScroll(); | |
document.addEventListener('scroll', _onScroll, false); | |
}; | |
/** | |
* Stop listening for the scroll event, also empty the private tweens array | |
*/ | |
parallax.exit = function() { | |
document.removeEventListener('scroll', _onScroll); | |
_tweens = []; | |
}; | |
/** | |
* Tween an element based on how many pixels the user has scrolled | |
* @class parallax.Tween | |
* @param {DOM Element} element The element to animate | |
* @param {String} property The CSS property to animate | |
* @param {String} start The initial value when we start animating (with units e.g. '0px') | |
* @param {String} end The final value when we stop animating (with units e.g. '200px') | |
* @param {Number} delay How many pixels will the user have scrolled when the animation starts | |
* @param {Number} animationEnd How many pixels will the user have scrolled when the animation finishes | |
* @param {Function} easingFunction Optional. A function taking the percentComplete of pixels scrolled and outputting the percentComplete of the animation | |
*/ | |
parallax.Tween = function ParallaxTween( | |
element, | |
property, | |
start, | |
end, | |
delay, | |
animationEnd, | |
easingFunction | |
) { | |
this.element = element; | |
this.property = property; | |
this.start = parseFloat(start); | |
this.end = parseFloat(end); | |
this.delay = delay; | |
this.animationEnd = animationEnd; | |
this.easingFunction = easingFunction || _defaultEasingFunction; | |
this.isAnimating = false; | |
this.range = this.animationEnd - this.delay; | |
this.change = this.end - this.start; | |
this.units = start.split(this.start)[1]; | |
//this.element.style[_transitionProperty] = property + ' 0.1s'; | |
_tweens.push(this); | |
}; | |
/** | |
* Flip a switch when a user scrolls x pixels | |
* @class parallax.Switch | |
* @param {DOM Element} element The element to change | |
* @param {String} property The CSS property to change | |
* @param {String} start The value of the CSS property *before* we scroll x pixels | |
* @param {String} end The value of the CSS property *after* we scroll x pixels | |
* @param {Number} delay How many pixels will the user have scrolled when we make the switch | |
*/ | |
parallax.Switch = function ParallaxSwitch( | |
element, | |
property, | |
start, | |
end, | |
delay | |
) { | |
this.element = element; | |
this.property = property; | |
this.start = start; | |
this.end = end; | |
this.delay = delay; | |
_switches.push(this); | |
}; | |
var _onScroll = function(e) { | |
_scrollTop = window.pageYOffset || document.scrollTop || 0; | |
var l = _tweens.length; | |
for (var i = 0; i < l; i++) { | |
var tween = _tweens[i]; | |
if (_scrollTop > tween.animationEnd || _scrollTop < tween.delay) { | |
if (tween.isAnimating) { | |
if (_lastScrollTop > _scrollTop) { | |
tween.element.style[tween.property] = tween.start + tween.units; | |
} else { | |
tween.element.style[tween.property] = tween.end + tween.units; | |
} | |
tween.isAnimating = false; | |
} | |
continue; | |
} | |
tween.isAnimating = true; | |
var percentComplete = (_scrollTop - tween.delay) / tween.range; | |
var position = tween.start + tween.change * tween.easingFunction(percentComplete); | |
tween.element.style[tween.property] = position + tween.units; | |
} | |
l = _switches.length; | |
for (var i = 0; i < l; i++) { | |
var _switch = _switches[i]; | |
if (_lastScrollTop < _switch.delay && _scrollTop >= _switch.delay) { | |
_switch.element.style[_switch.property] = _switch.end; | |
} else if (_lastScrollTop > _switch.delay && _scrollTop < _switch.delay) { | |
_switch.element.style[_switch.property] = _switch.start; | |
} | |
} | |
_lastScrollTop = _scrollTop; | |
}; | |
return parallax; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment