Skip to content

Instantly share code, notes, and snippets.

@celsowhite
Created July 1, 2017 17:39
Show Gist options
  • Save celsowhite/1c8d0696a75aad45ca92bfb499f24ec2 to your computer and use it in GitHub Desktop.
Save celsowhite/1c8d0696a75aad45ca92bfb499f24ec2 to your computer and use it in GitHub Desktop.
Parallax function that can be applied to any element on a page. Control the elements speed and rotation.
/*=================================
General Parallax Elements
=================================*/
const parallaxItems = document.querySelectorAll('.parallax_item');
const windowHeight = window.innerHeight;
// Check each item to see if it is in view on page load so we can set a base position
Array.from(parallaxItems).forEach(item => {
if(item.getBoundingClientRect().bottom < window.innerHeight) {
item.base = (-item.getBoundingClientRect().top + window.innerHeight) / (item.clientHeight + window.innerHeight);
}
else {
item.base = 0;
}
});
// On scroll check the position of an item and if in view then parallax it based on the speed and rotate settings
function checkParallaxItems() {
Array.from(parallaxItems).forEach(item => {
// Window Measurements
let windowPosition = window.scrollY;
let windowBottomPosition = window.scrollY + windowHeight;
// Item distances from way top of page
let itemTop = item.getBoundingClientRect().top + window.scrollY;
let itemBottom = item.getBoundingClientRect().bottom + window.scrollY;
// Conditionals
// Bottom of item is greater than the scroll position
// Meaning we havn't scrolled past the item yet
let itemBelowTop = itemBottom >= window.scrollY;
// Top of item is less than the bottom scroll position of our window
// Meaning the item has scrolled into view
let itemAboveBottom = itemTop <= windowBottomPosition;
// If item is in view then parallax it at the given speed/rotation
// In view is top of the item has peaked into the bottom of the frame and bottom of the item is just about to leave top of frame
if(itemBelowTop && itemAboveBottom) {
// User configurations for speed and rotate
let speed = Number(item.dataset.speed);
let rotate = Number(item.dataset.rotate);
// Calculate the percentage the item has scrolled within the viewport
// If item was already in viewport then subtract its base so we have an origin for the scroll effects
let percentage = (windowHeight - item.getBoundingClientRect().top) / (windowHeight + item.clientHeight) - item.base;
let rawPosition = (speed * (percentage * 100));
let position = Math.round(rawPosition * 10) / 10;
// Rotate a specific amount of degrees while item is in viewport
let rawDegrees = (rotate/100) * (percentage * 100);
let degrees = Math.round(rawDegrees * 10) / 10;
// Check which data attributes the user has set
if(rotate && speed) {
item.style.transform = 'translate3d(0, -' + position + 'px, 0) rotate(' + degrees + 'deg)';
}
else if(rotate) {
item.style.transform = 'rotate(' + degrees + 'deg)';
}
else if(speed) {
item.style.transform = 'translate3d(0, -' + position + 'px, 0)';
}
}
});
}
// Only trigger parallax effect on certain screen sizes.
if(mq.matches) {
window.addEventListener('scroll', function(){
// Ensure the browser repaints before running each animation
window.requestAnimationFrame(checkParallaxItems);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment