You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
masonry/src/masonry.js

91 lines
2.7 KiB

import { throttle, debounce } from 'throttle-debounce'
/**
* Tiny Masonry
*
* @author Björn Hase
* @license http://opensource.org/licenses/MIT The MIT License
* @link https://gitea.node001.net/tiny-components/masonry
*
*/
class Masonry {
/**
*
*
*/
constructor() {
// getting elements
this.elements = document.querySelectorAll('.tiny-masonry__item-inner')
this.container = document.querySelector('.tiny-masonry')
// getting gap for calculate from grid
this.gap = parseInt(getComputedStyle(this.container, 'gap').getPropertyValue('grid-gap').split(' ')[0])
this.calculate()
window.addEventListener('resize', throttle(300, () => {
this.calculate()
}), false)
window.addEventListener('scroll', throttle(300, () => {
this.calculate(true)
}), false)
}
/**
*
*
*/
calculate(onlyVisible = false) {
// getting number of columns
if (!onlyVisible) {
this.columns = Math.ceil(this.container.offsetWidth / this.elements[0].parentElement.offsetWidth) - 1
if (this.columns === 0) {
this.columns = 1
}
}
for (let i = 0; i < this.elements.length; i++) {
let marginTop = 0
// getting row
let row = Math.round(i / this.columns) + 1
// reset margin-top for the first columns
if (i < this.columns) {
this.elements[i].parentElement.dataset.offsetMarginTop = 0
}
// check for parent element and getting marginTop
if (this.elements[i - this.columns] && !onlyVisible) {
if (this.elements[i - this.columns].parentElement.dataset.offsetMarginTop) {
marginTop += parseInt(this.elements[i - this.columns].parentElement.dataset.offsetMarginTop)
}
marginTop += this.elements[i - this.columns].offsetHeight
} else {
marginTop = this.elements[i].parentElement.dataset.offsetMarginTop
}
if (!onlyVisible) {
this.elements[i].parentElement.dataset.offsetMarginTop = marginTop
}
if (window.pageYOffset <= (marginTop + this.elements[i].offsetHeight + (this.gap * row)) && (window.pageYOffset + window.innerHeight + (this.gap * row)) >= marginTop) {
this.elements[i].parentElement.style.marginTop = marginTop + 'px'
this.elements[i].parentElement.style.visibility = 'visible'
} else {
this.elements[i].parentElement.style.visibility = 'hidden'
}
}
}
}
export default Masonry