Skip to content

Instantly share code, notes, and snippets.

@felipemarcos
Created June 2, 2016 20:53
Show Gist options
  • Save felipemarcos/192f14d1632bf42dca8f88f28ba89509 to your computer and use it in GitHub Desktop.
Save felipemarcos/192f14d1632bf42dca8f88f28ba89509 to your computer and use it in GitHub Desktop.
Reveal on scroll
import Packery from 'packery';
import imagesLoaded from 'imagesloaded';
export default class Mosaic {
constructor() {
this.options = {
pckry: {
percentPosition: true,
itemSelector: '.mosaic-item',
},
minDuration: 1,
stepDuration: 0.05,
viewportFactor: 0
};
const mosaicEl = document.querySelector('.mosaic');
if (!mosaicEl) {
return;
}
this.docElem = window.document.documentElement;
this.didScroll = false;
this.items = [].slice.call(document.querySelectorAll('.mosaic-item'), 0);
this.itemsRenderedCount = 0;
this.pckry = new Packery(mosaicEl, this.options.pckry);
this.animation();
this.imagesLoaded();
}
handleImageLoaded() {
this.pckry.layout();
}
imagesLoaded() {
const imagesLoad = imagesLoaded('.mosaic',
{background: '.mosaic-item'},
this.handleImageLoaded.bind(this)
);
imagesLoad.on( 'progress', (instance, image) => {
image.element.classList.add('mosaic-item--' + (image.isLoaded ? 'loaded' : 'error'));
// if ( this.inViewport(image.element) ) {
// this._checkTotalRendered();
// image.element.classList.add( 'shown' );
// }
});
}
animation() {
window.addEventListener( 'scroll', () => {
this.handleScroll();
}, false );
}
handleScroll() {
if ( !this.didScroll ) {
this.didScroll = true;
setTimeout( () => {
this.scrollPage();
}, 60 );
}
}
scrollPage() {
this.items.forEach( ( el, i ) => {
if(
!el.classList.contains( 'mosaic-item--shown' ) &&
!el.classList.contains( 'mosaic-item--animate' ) &&
this.inViewport( el, this.options.viewportFactor)
) {
setTimeout( () => {
const perspY = this.scrollY() + this.getViewportH() / 2;
el.style.perspectiveOrigin = '50% ' + perspY + 'px';
this._checkTotalRendered();
const delay = (i * this.options.stepDuration) + 's';
el.style.animationDelay = delay;
el.classList.add( el, 'mosaic-item--animate' );
}, 25 );
}
});
this.didScroll = false;
}
inViewport( el, h ) {
const elH = el.offsetHeight;
const scrolled = this.scrollY();
const viewed = scrolled + this.getViewportH();
const elTop = this.getOffset(el).top;
const elBottom = elTop + elH;
h = h || 0;
return (elTop + elH * h) <= viewed && (elBottom - elH * h) >= scrolled;
}
scrollY() {
return window.pageYOffset || this.docElem.scrollTop;
}
getOffset( el ) {
let offsetTop = 0;
let offsetLeft = 0;
do {
if ( !isNaN( el.offsetTop ) ) {
offsetTop += el.offsetTop;
}
if ( !isNaN( el.offsetLeft ) ) {
offsetLeft += el.offsetLeft;
}
} while( el = el.offsetParent )
return {
top : offsetTop,
left : offsetLeft
}
}
getViewportH() {
const client = this.docElem['clientHeight'];
const inner = window['innerHeight'];
if ( client < inner ) {
return inner;
} else {
return client;
}
}
_checkTotalRendered() {
++this.itemsRenderedCount;
if ( this.itemsRenderedCount === this.itemsCount ) {
window.removeEventListener( 'scroll', this.handleScroll );
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment