From 24efcce500c7aed566f18f62c9bd90bcac1cfdb7 Mon Sep 17 00:00:00 2001 From: HerrHase Date: Fri, 26 May 2023 15:41:42 +0200 Subject: [PATCH] adding --- example/example.js | 70 ++++++++++++++++++++++++++++++++++++++-------- example/index.html | 12 ++++++++ package.json | 2 +- src/masonry.js | 52 +++++++++++++++++++++++++--------- 4 files changed, 110 insertions(+), 26 deletions(-) diff --git a/example/example.js b/example/example.js index 735d0f4..dfce206 100644 --- a/example/example.js +++ b/example/example.js @@ -35,35 +35,81 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } + +/** + * Tiny Masonry + * + * @author Björn Hase + * @license http://opensource.org/licenses/MIT The MIT License + * @link https://gitea.node001.net/tiny-components/masonry + * + */ var Masonry = /*#__PURE__*/function () { + /** + * + * + */ function Masonry() { var _this = this; _classCallCheck(this, Masonry); + // 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', (0,throttle_debounce__WEBPACK_IMPORTED_MODULE_0__.throttle)(300, function () { _this.calculate(); }), false); + window.addEventListener('scroll', (0,throttle_debounce__WEBPACK_IMPORTED_MODULE_0__.throttle)(300, function () { + _this.calculate(true); + }), false); } + + /** + * + * + */ _createClass(Masonry, [{ key: "calculate", value: function calculate() { - this.columns = Math.ceil(this.container.offsetWidth / this.elements[0].parentElement.offsetWidth) - 1; - for (var i = 0; i < this.elements.length; i++) { - this.elements[i].parentElement.style.marginTop = '0px'; + var onlyVisible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 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 (var _i = 0; _i < this.elements.length; _i++) { - if (this.elements[_i + this.columns]) { - var offset = 0; + for (var i = 0; i < this.elements.length; i++) { + var marginTop = 0; - // if style was already - if (this.elements[_i] && this.elements[_i].parentElement.style.marginTop) { - offset += parseInt(this.elements[_i].parentElement.style.marginTop); - } + // getting row + var row = Math.round(i / this.columns) + 1; - // setting - this.elements[_i + this.columns].parentElement.style.marginTop = this.elements[_i].offsetHeight + parseInt(offset) + 'px'; + // 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'; } } } diff --git a/example/index.html b/example/index.html index c75bf09..b8db91e 100644 --- a/example/index.html +++ b/example/index.html @@ -47,6 +47,18 @@
10
11
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
diff --git a/package.json b/package.json index 9104954..fd9a360 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tiny-components/masonry", - "version": "0.1.0", + "version": "0.2.0", "description": "Masonry for Desktop and Mobile", "repository": { "type": "git", diff --git a/src/masonry.js b/src/masonry.js index 9811944..bf4a1f0 100644 --- a/src/masonry.js +++ b/src/masonry.js @@ -21,41 +21,67 @@ class Masonry { 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() { + calculate(onlyVisible = false) { // getting number of columns - this.columns = Math.ceil(this.container.offsetWidth / this.elements[0].parentElement.offsetWidth) - 1 + if (!onlyVisible) { + this.columns = Math.ceil(this.container.offsetWidth / this.elements[0].parentElement.offsetWidth) - 1 - // reset margin-top - for (let i = 0; i < this.elements.length; i++) { - this.elements[i].parentElement.style.marginTop = '0px' + if (this.columns === 0) { + this.columns = 1 + } } for (let i = 0; i < this.elements.length; i++) { - // adding each parent element in column - if (this.elements[i + this.columns]) { + let marginTop = 0 - let offset = 0 + // getting row + let row = Math.round(i / this.columns) + 1 - // if style was already setup adding to offset - if (this.elements[i] && this.elements[i].parentElement.style.marginTop) { - offset += parseInt(this.elements[i].parentElement.style.marginTop) + // 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) } - // setting margin top - this.elements[i + this.columns].parentElement.style.marginTop = this.elements[i].offsetHeight + parseInt(offset) + 'px' + 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' } } }