// Generated by CoffeeScript 2.5.1 (function() { /* jQuery Gridly Copyright 2020 Kevin Sylvestre 1.3.0 */ "use strict"; var $, Animation, Draggable, Gridly; $ = jQuery; Animation = (function() { class Animation { static transition($el) { var el, ref, result, type; el = $el[0]; ref = this.transitions; for (type in ref) { result = ref[type]; if (el.style[type] != null) { return result; } } } static execute($el, callback) { var transition; transition = this.transition($el); if (transition != null) { return $el.one(transition, callback); } else { return callback(); } } }; Animation.transitions = { "webkitTransition": "webkitTransitionEnd", "mozTransition": "mozTransitionEnd", "oTransition": "oTransitionEnd", "transition": "transitionend" }; return Animation; }).call(this); Draggable = class Draggable { constructor($container, selector, callbacks) { this.bind = this.bind.bind(this); this.toggle = this.toggle.bind(this); this.on = this.on.bind(this); this.off = this.off.bind(this); this.coordinate = this.coordinate.bind(this); this.began = this.began.bind(this); this.ended = this.ended.bind(this); this.moved = this.moved.bind(this); this.click = this.click.bind(this); this.touchend = this.touchend.bind(this); this.$container = $container; this.selector = selector; this.callbacks = callbacks; this.toggle(); } bind(method = 'on') { $(document)[method]('mousemove touchmove', this.moved); return $(document)[method]('mouseup touchcancel', this.ended); } toggle(method = 'on') { this.$container[method]('mousedown touchstart', this.selector, this.began); this.$container[method]('touchend', this.selector, this.touchend); return this.$container[method]('click', this.selector, this.click); } on() { return this.toggle('on'); } off() { return this.toggle('off'); } coordinate(event) { switch (event.type) { case 'touchstart': case 'touchmove': case 'touchend': case 'touchcancel': return event.originalEvent.touches[0]; default: return event; } } began(event) { var ref; if (this.$target) { return; } event.preventDefault(); event.stopPropagation(); this.bind('on'); this.$target = $(event.target).closest(this.$container.find(this.selector)); this.$target.addClass('dragging'); this.origin = { x: this.coordinate(event).pageX - this.$target.position().left, y: this.coordinate(event).pageY - this.$target.position().top }; return (ref = this.callbacks) != null ? typeof ref.began === "function" ? ref.began(event) : void 0 : void 0; } ended(event) { var ref; if (this.$target == null) { return; } if (event.type !== 'touchend') { event.preventDefault(); event.stopPropagation(); } this.bind('off'); this.$target.removeClass('dragging'); delete this.$target; delete this.origin; return (ref = this.callbacks) != null ? typeof ref.ended === "function" ? ref.ended(event) : void 0 : void 0; } moved(event) { var ref; if (this.$target == null) { return; } event.preventDefault(); event.stopPropagation(); this.$target.css({ left: this.coordinate(event).pageX - this.origin.x, top: this.coordinate(event).pageY - this.origin.y }); this.dragged = this.$target; return (ref = this.callbacks) != null ? typeof ref.moved === "function" ? ref.moved(event) : void 0 : void 0; } click(event) { if (!this.dragged) { return; } event.preventDefault(); event.stopPropagation(); return delete this.dragged; } touchend(event) { this.ended(event); return this.click(event); } }; Gridly = (function() { class Gridly { static gridly($el, options = {}) { var data; data = $el.data('_gridly'); if (data) { $.extend(data.settings, options); } else { data = new Gridly($el, options); $el.data('_gridly', data); } return data; } constructor($el, settings = {}) { this.ordinalize = this.ordinalize.bind(this); this.reordinalize = this.reordinalize.bind(this); this.$ = this.$.bind(this); this.compare = this.compare.bind(this); this.draggable = this.draggable.bind(this); this.$sorted = this.$sorted.bind(this); this.draggingBegan = this.draggingBegan.bind(this); this.draggingEnded = this.draggingEnded.bind(this); this.draggingMoved = this.draggingMoved.bind(this); this.size = this.size.bind(this); this.position = this.position.bind(this); this.structure = this.structure.bind(this); this.layout = this.layout.bind(this); this.optimize = this.optimize.bind(this); this.$el = $el; this.settings = $.extend({}, Gridly.settings, settings); this.ordinalize(this.$('> *')); if (this.settings.draggable !== false) { this.draggable(); } return this; } ordinalize($elements) { var $element, i, j, ref, results1; results1 = []; for (i = j = 0, ref = $elements.length; (0 <= ref ? j <= ref : j >= ref); i = 0 <= ref ? ++j : --j) { $element = $($elements[i]); results1.push($element.data('position', i)); } return results1; } reordinalize($element, position) { return $element.data('position', position); } $(selector) { return this.$el.find(selector); } compare(d, s) { if (d.y > s.y + s.h) { return +1; } if (s.y > d.y + d.h) { return -1; } if ((d.x + (d.w / 2)) > (s.x + (s.w / 2))) { return +1; } if ((s.x + (s.w / 2)) > (d.x + (d.w / 2))) { return -1; } return 0; } draggable(method) { if (this._draggable == null) { this._draggable = new Draggable(this.$el, this.settings.draggable.selector, { began: this.draggingBegan, ended: this.draggingEnded, moved: this.draggingMoved }); } if (method != null) { return this._draggable[method](); } } $sorted($elements) { return ($elements || this.$('> *')).sort(function(a, b) { var $a, $b, aPosition, aPositionInt, bPosition, bPositionInt; $a = $(a); $b = $(b); aPosition = $a.data('position'); bPosition = $b.data('position'); aPositionInt = parseInt(aPosition); bPositionInt = parseInt(bPosition); if ((aPosition != null) && (bPosition == null)) { return -1; } if ((bPosition != null) && (aPosition == null)) { return +1; } if (!aPosition && !bPosition && $a.index() < $b.index()) { return -1; } if (!bPosition && !aPosition && $b.index() < $a.index()) { return +1; } if (aPositionInt < bPositionInt) { return -1; } if (bPositionInt < aPositionInt) { return +1; } return 0; }); } draggingBegan(event) { var $elements, ref, ref1; $elements = this.$sorted(); this.ordinalize($elements); setTimeout(this.layout, 0); return (ref = this.settings) != null ? (ref1 = ref.callbacks) != null ? typeof ref1.reordering === "function" ? ref1.reordering($elements) : void 0 : void 0 : void 0; } draggingEnded(event) { var $elements, ref, ref1; $elements = this.$sorted(); this.ordinalize($elements); setTimeout(this.layout, 0); return (ref = this.settings) != null ? (ref1 = ref.callbacks) != null ? typeof ref1.reordered === "function" ? ref1.reordered($elements, this._draggable.dragged) : void 0 : void 0 : void 0; } draggingMoved(event) { var $dragging, $elements, element, i, index, j, k, len, original, positions, ref, ref1, ref2; $dragging = $(event.target).closest(this.$(this.settings.draggable.selector)); $elements = this.$sorted(this.$(this.settings.draggable.selector)); positions = this.structure($elements).positions; original = index = $dragging.data('position'); ref = positions.filter(function(position) { return position.$element.is($dragging); }); for (j = 0, len = ref.length; j < len; j++) { element = ref[j]; element.x = $dragging.position().left; element.y = $dragging.position().top; element.w = $dragging.data('width') || $dragging.outerWidth(); element.h = $dragging.data('height') || $dragging.outerHeight(); } positions.sort(this.compare); $elements = positions.map(function(position) { return position.$element; }); $elements = (((ref1 = this.settings.callbacks) != null ? ref1.optimize : void 0) || this.optimize)($elements); for (i = k = 0, ref2 = $elements.length; (0 <= ref2 ? k < ref2 : k > ref2); i = 0 <= ref2 ? ++k : --k) { this.reordinalize($($elements[i]), i); } return this.layout(); } size($element) { return (($element.data('width') || $element.outerWidth()) + this.settings.gutter) / (this.settings.base + this.settings.gutter); } position($element, columns) { var column, height, i, j, k, max, ref, ref1, ref2, size; size = this.size($element); height = 2e308; column = 0; for (i = j = 0, ref = columns.length - size; (0 <= ref ? j < ref : j > ref); i = 0 <= ref ? ++j : --j) { max = Math.max(...columns.slice(i, (i + size))); if (max < height) { height = max; column = i; } } for (i = k = ref1 = column, ref2 = column + size; (ref1 <= ref2 ? k < ref2 : k > ref2); i = ref1 <= ref2 ? ++k : --k) { columns[i] = height + ($element.data('height') || $element.outerHeight()) + this.settings.gutter; } return { x: column * (this.settings.base + this.settings.gutter), y: height }; } structure($elements = this.$sorted()) { var $element, columns, i, index, j, position, positions, ref; positions = []; columns = (function() { var j, ref, results1; results1 = []; for (i = j = 0, ref = this.settings.columns; (0 <= ref ? j <= ref : j >= ref); i = 0 <= ref ? ++j : --j) { results1.push(0); } return results1; }).call(this); for (index = j = 0, ref = $elements.length; (0 <= ref ? j < ref : j > ref); index = 0 <= ref ? ++j : --j) { $element = $($elements[index]); position = this.position($element, columns); positions.push({ x: position.x, y: position.y, w: $element.data('width') || $element.outerWidth(), h: $element.data('height') || $element.outerHeight(), $element: $element }); } return { height: Math.max(...columns), positions: positions }; } layout() { var $element, $elements, index, j, position, ref, ref1, structure; $elements = (((ref = this.settings.callbacks) != null ? ref.optimize : void 0) || this.optimize)(this.$sorted()); structure = this.structure($elements); for (index = j = 0, ref1 = $elements.length; (0 <= ref1 ? j < ref1 : j > ref1); index = 0 <= ref1 ? ++j : --j) { $element = $($elements[index]); position = structure.positions[index]; if ($element.is('.dragging')) { continue; } $element.css({ position: 'absolute', left: position.x, top: position.y }); } return this.$el.css({ height: structure.height }); } optimize(originals) { var columns, index, j, ref, results; results = []; columns = 0; while (originals.length > 0) { if (columns === this.settings.columns) { columns = 0; } index = 0; for (index = j = 0, ref = originals.length; (0 <= ref ? j < ref : j > ref); index = 0 <= ref ? ++j : --j) { if (!(columns + this.size($(originals[index])) > this.settings.columns)) { break; } } if (index === originals.length) { index = 0; columns = 0; } columns += this.size($(originals[index])); // Move from originals into results results.push(originals.splice(index, 1)[0]); } return results; } }; Gridly.settings = { base: 60, gutter: 20, columns: 12, draggable: { zIndex: 800, selector: '> *' } }; return Gridly; }).call(this); $.fn.extend({ gridly: function(option = {}, ...parameters) { return this.each(function() { var $this, action, options; $this = $(this); options = $.extend({}, $.fn.gridly.defaults, typeof option === "object" && option); action = typeof option === "string" ? option : option.action; if (action == null) { action = "layout"; } return Gridly.gridly($this, options)[action](parameters); }); } }); }).call(this);