Skip to content

Instantly share code, notes, and snippets.

@benjamminf
Last active November 9, 2016 22:22
Show Gist options
  • Save benjamminf/6ccde05fd1153036c70312b7823648b6 to your computer and use it in GitHub Desktop.
Save benjamminf/6ccde05fd1153036c70312b7823648b6 to your computer and use it in GitHub Desktop.
parallax.js
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) })
}
@benjamminf
Copy link
Author

Quick and dirty transpiler: http://es6console.com/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment