This is the code that powers the parallax effect on codetunes.com.
I think it’s quite chaotic at the moment and waits for being released as open source when it’s cleaned up. Requires resizeend.
This is the code that powers the parallax effect on codetunes.com.
I think it’s quite chaotic at the moment and waits for being released as open source when it’s cleaned up. Requires resizeend.
| /** | |
| * Creates the parallax effect. | |
| */ | |
| function createParallaxEffect() { | |
| var parallaxElement = document.getElementsByClassName("parallax-outer")[0]; | |
| var parallaxClassName = "js-parallax"; | |
| var parallaxEnabled = ( | |
| parallaxElement.nodeType === 1 && | |
| getStyle(document.body, "content", ":after").indexOf("parallax") >= 0 && | |
| !hasClass(rootElement, parallaxClassName) | |
| ); | |
| if ( !parallaxEnabled ) { | |
| return; | |
| } | |
| addClass(rootElement, parallaxClassName); | |
| var parallaxSpeed = 0.5; | |
| var parallaxTopClassName = parallaxClassName + "-alt"; | |
| var parallaxLimitMax; | |
| var lastPositionY; | |
| var setTransform; | |
| var handleScrollY; | |
| var handleResize; | |
| if ( Modernizr.ios ) { | |
| setTransform = function(){}; | |
| } | |
| else if ( Modernizr.qgraphicsview && Modernizr.csstransforms3d ) { | |
| setTransform = function(offset, scale) { | |
| parallaxElement.style[transformProperty] = "translate3d(0," + offset + "px,0) scale(" + scale + ")"; | |
| }; | |
| } | |
| else if ( Modernizr.qgraphicsview && Modernizr.csstransforms ) { | |
| setTransform = function(offset, scale) { | |
| parallaxElement.style[transformProperty] = "translateY(" + offset + "px) scale(" + scale + ")"; | |
| }; | |
| } | |
| else { | |
| setTransform = function(offset) { | |
| parallaxElement.style.backgroundPosition = "50% " + offset + "px"; | |
| }; | |
| } | |
| handleScrollY = function() { | |
| var positionY = parseInt(window.pageYOffset, 10); | |
| positionY = Math.min(parallaxLimitMax, positionY); | |
| if ( positionY !== lastPositionY ) { | |
| lastPositionY = positionY; | |
| if ( positionY > 0 ) { | |
| setTransform(positionY * parallaxSpeed, 1); | |
| } | |
| else { | |
| setTransform(positionY / -6, -1 * positionY / parallaxLimitMax + 1); | |
| } | |
| if ( positionY >= (parallaxLimitMax - 35) ) { | |
| addClass(rootElement, parallaxTopClassName); | |
| } | |
| else { | |
| removeClass(rootElement, parallaxTopClassName); | |
| } | |
| } | |
| }; | |
| handleResize = function() { | |
| parallaxLimitMax = parallaxElement.offsetHeight || 440; | |
| lastPositionY += 999; | |
| handleScrollY(); | |
| }; | |
| handleResize(); | |
| window.addEventListener("resizeend", handleResize, false); | |
| window.addEventListener("scroll", handleScrollY, false); | |
| } |
| Modernizr.addTest("qgraphicsview", function() { | |
| var platform = !!navigator.userAgent.match(/Macintosh/i); | |
| var engine = !!navigator.userAgent.match(/AppleWebKit/i); | |
| return ( platform && engine ); | |
| }); | |
| var rootElement = document.documentElement; | |
| var classListSupport = "classList" in document.createElement("a"); | |
| var classNameDisabled = "js-disabled"; | |
| var classNameLoaded = "js-loaded"; | |
| var classNameVisible = "js-visible"; | |
| var transformProperty = Modernizr.prefixed("transform"); | |
| /** | |
| * Removes the given class from the element’s `className`. | |
| */ | |
| function removeClass(element, className) { | |
| if ( !hasClass(element, className) ) { | |
| return element; | |
| } | |
| if ( classListSupport ) { | |
| element.classList.remove(className); | |
| } | |
| else { | |
| var elClassName = " " + element.className + " "; | |
| className = " " + className + " "; | |
| element.className = elClassName.replace(className, " "); | |
| } | |
| return element; | |
| } | |
| /** | |
| * Add the given class to the element’s `className`. | |
| */ | |
| function addClass(element, className) { | |
| if ( hasClass(element, className) ) { | |
| return element; | |
| } | |
| if ( classListSupport ) { | |
| element.classList.add(className); | |
| } | |
| else { | |
| element.className += " " + className; | |
| } | |
| return element; | |
| } | |
| /** | |
| * Returns true when the element contains the given class. | |
| */ | |
| function hasClass(element, className) { | |
| if ( classListSupport ) { | |
| return element.classList.contains(className); | |
| } | |
| var elClassName = " " + element.className + " "; | |
| className = " " + className + " "; | |
| return elClassName.replace(/[\n\t]/g, " ").indexOf(className) >= 0; | |
| } | |
| /** | |
| * Wrapper for `getComputedStyle`. | |
| */ | |
| function getStyle(element, styleName, pseudoElement) { | |
| return window.getComputedStyle(element, pseudoElement || null).getPropertyValue(styleName); | |
| } |