Last active
November 9, 2016 22:22
-
-
Save benjamminf/6ccde05fd1153036c70312b7823648b6 to your computer and use it in GitHub Desktop.
parallax.js
This file contains hidden or 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
import $ from 'jquery' | |
// Request animation frame polyfills | |
const frame = window.requestAnimationFrame ? cb => requestAnimationFrame(cb) : cb => setTimeout(cb, 0) | |
const unframe = window.cancelAnimationFrame ? id => cancelAnimationFrame(id) : id => clearTimeout(id) | |
// Trigger layout redraws around some element | |
const redraw = el => (el instanceof $ ? el[0] : el).offsetWidth | |
// Memoize viewport height so using it is less expensive | |
const $window = $(window) | |
let viewportHeight = $window.height() | |
$window.on('resize', e => viewportHeight = $window.height()) | |
/** | |
* Applies parallax to an element | |
* | |
* @param element | |
* @param speed - A float in range [0-1] | |
* @param scale - Whether to scale the element so it covers it's original area (use with background images) | |
*/ | |
function parallax(element, speed, scale=false) | |
{ | |
const $element = $(element) | |
let height, offset, resetupId, repositionId | |
// Initialises parallax on the element | |
const setup = () => | |
{ | |
$element.css('transform', '') | |
$element.css('height', '') | |
redraw(element) | |
height = $element.outerHeight() | |
offset = $element.offset() | |
if(scale) | |
{ | |
const viewHeight = Math.min(viewportHeight, offset.top + height) | |
const newHeight = viewHeight - (viewHeight - height) * speed | |
$element.css('height', newHeight + 'px') | |
} | |
position() | |
} | |
// Updates the position of the parallaxed element | |
const position = () => | |
{ | |
let translate = $window.scrollTop() - offset.top | |
if(!scale) | |
{ | |
translate += (viewportHeight - height) / 2 | |
} | |
translate *= speed - 1 | |
$element.css('transform', `translate3d(0, ${-translate}px, 0)`) | |
} | |
// Setup parallax as soon as the page is ready | |
setup() | |
$(e => { unframe(resetupId), resetupId = frame(setup) }) | |
// Resetup the element when the environment changes | |
$window.on('load resize', e => { unframe(resetupId), resetupId = frame(setup) }) | |
// Reposition the element on scroll | |
$window.on('scroll', e => { unframe(repositionId), repositionId = frame(position) }) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Quick and dirty transpiler: http://es6console.com/