From c868ff796fd8ebf9f0c5f4d69a4abbb0f9682df8 Mon Sep 17 00:00:00 2001 From: Andinus Date: Fri, 10 Jun 2022 09:51:20 +0530 Subject: Add bricks.js for masonry layout, fix password input multi-column didn't do what I wanted. bricks.js does the masonry layout, I think left-to-right would be even better but we'll go with this. --- resources/js/bricks.js | 285 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 resources/js/bricks.js (limited to 'resources/js/bricks.js') diff --git a/resources/js/bricks.js b/resources/js/bricks.js new file mode 100644 index 0000000..7758b05 --- /dev/null +++ b/resources/js/bricks.js @@ -0,0 +1,285 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.Bricks = factory()); +}(this, (function () { 'use strict'; + +var _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; +}; + +var knot = function knot() { + var extended = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + var events = Object.create(null); + + function on(name, handler) { + events[name] = events[name] || []; + events[name].push(handler); + return this; + } + + function once(name, handler) { + handler._once = true; + on(name, handler); + return this; + } + + function off(name) { + var handler = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + handler ? events[name].splice(events[name].indexOf(handler), 1) : delete events[name]; + + return this; + } + + function emit(name) { + var _this = this; + + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + // cache the events, to avoid consequences of mutation + var cache = events[name] && events[name].slice(); + + // only fire handlers if they exist + cache && cache.forEach(function (handler) { + // remove handlers added with 'once' + handler._once && off(name, handler); + + // set 'this' context, pass args to handlers + handler.apply(_this, args); + }); + + return this; + } + + return _extends({}, extended, { + + on: on, + once: once, + off: off, + emit: emit + }); +}; + +var bricks = function bricks() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + // privates + + var persist = void 0; // packing new elements, or all elements? + var ticking = void 0; // for debounced resize + + var sizeIndex = void 0; + var sizeDetail = void 0; + + var columnTarget = void 0; + var columnHeights = void 0; + + var nodeTop = void 0; + var nodeLeft = void 0; + var nodeWidth = void 0; + var nodeHeight = void 0; + + var nodes = void 0; + var nodesWidths = void 0; + var nodesHeights = void 0; + + // resolve options + + var packed = options.packed.indexOf('data-') === 0 ? options.packed : 'data-' + options.packed; + var sizes = options.sizes.slice().reverse(); + var position = options.position !== false; + + var container = options.container.nodeType ? options.container : document.querySelector(options.container); + + var selectors = { + all: function all() { + return toArray(container.children); + }, + new: function _new() { + return toArray(container.children).filter(function (node) { + return !node.hasAttribute('' + packed); + }); + } + }; + + // series + + var setup = [setSizeIndex, setSizeDetail, setColumns]; + + var run = [setNodes, setNodesDimensions, setNodesStyles, setContainerStyles]; + + // instance + + var instance = knot({ + pack: pack, + update: update, + resize: resize + }); + + return instance; + + // general helpers + + function runSeries(functions) { + functions.forEach(function (func) { + return func(); + }); + } + + // array helpers + + function toArray(input) { + var scope = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document; + + return Array.prototype.slice.call(input); + } + + function fillArray(length) { + return Array.apply(null, Array(length)).map(function () { + return 0; + }); + } + + // size helpers + + function getSizeIndex() { + // find index of widest matching media query + return sizes.map(function (size) { + return size.mq && window.matchMedia('(min-width: ' + size.mq + ')').matches; + }).indexOf(true); + } + + function setSizeIndex() { + sizeIndex = getSizeIndex(); + } + + function setSizeDetail() { + // if no media queries matched, use the base case + sizeDetail = sizeIndex === -1 ? sizes[sizes.length - 1] : sizes[sizeIndex]; + } + + // column helpers + + function setColumns() { + columnHeights = fillArray(sizeDetail.columns); + } + + // node helpers + + function setNodes() { + nodes = selectors[persist ? 'new' : 'all'](); + } + + function setNodesDimensions() { + // exit if empty container + if (nodes.length === 0) { + return; + } + + nodesWidths = nodes.map(function (element) { + return element.clientWidth; + }); + nodesHeights = nodes.map(function (element) { + return element.clientHeight; + }); + } + + function setNodesStyles() { + nodes.forEach(function (element, index) { + columnTarget = columnHeights.indexOf(Math.min.apply(Math, columnHeights)); + + element.style.position = 'absolute'; + + nodeTop = columnHeights[columnTarget] + 'px'; + nodeLeft = columnTarget * nodesWidths[index] + columnTarget * sizeDetail.gutter + 'px'; + + // support positioned elements (default) or transformed elements + if (position) { + element.style.top = nodeTop; + element.style.left = nodeLeft; + } else { + element.style.transform = 'translate3d(' + nodeLeft + ', ' + nodeTop + ', 0)'; + } + + element.setAttribute(packed, ''); + + // ignore nodes with no width and/or height + nodeWidth = nodesWidths[index]; + nodeHeight = nodesHeights[index]; + + if (nodeWidth && nodeHeight) { + columnHeights[columnTarget] += nodeHeight + sizeDetail.gutter; + } + }); + } + + // container helpers + + function setContainerStyles() { + container.style.position = 'relative'; + container.style.width = sizeDetail.columns * nodeWidth + (sizeDetail.columns - 1) * sizeDetail.gutter + 'px'; + container.style.height = Math.max.apply(Math, columnHeights) - sizeDetail.gutter + 'px'; + } + + // resize helpers + + function resizeFrame() { + if (!ticking) { + window.requestAnimationFrame(resizeHandler); + ticking = true; + } + } + + function resizeHandler() { + if (sizeIndex !== getSizeIndex()) { + pack(); + instance.emit('resize', sizeDetail); + } + + ticking = false; + } + + // API + + function pack() { + persist = false; + runSeries(setup.concat(run)); + + return instance.emit('pack'); + } + + function update() { + persist = true; + runSeries(run); + + return instance.emit('update'); + } + + function resize() { + var flag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + + var action = flag ? 'addEventListener' : 'removeEventListener'; + + window[action]('resize', resizeFrame); + + return instance; + } +}; + +return bricks; + +}))); -- cgit 1.4.1-2-gfad0