PageSourceSearch

https://www.arktos.be/js/masonry/packery-mode.pkgd.js

js arktos.be collected 2026-09-24 10:37:59 UTC 32,588 bytes, 1,238 lines download raw bytes

1/*!
2 * Packery layout mode PACKAGED v2.0.1
3 * sub-classes Packery
4 */
5
6/**
7 * Rect
8 * low-level utility class for basic geometry
9 */
10
11(function (window, factory) {
12  // universal module definition
13  /* jshint strict: false */ /* globals define, module */
14  if (typeof define == 'function' && define.amd) {
15    // AMD
16    define('packery/js/rect', factory);
17  } else if (typeof module == 'object' && module.exports) {
18    // CommonJS
19    module.exports = factory();
20  } else {
21    // browser global
22    window.Packery = window.Packery || {};
23    window.Packery.Rect = factory();
24  }
25
26}(window, function factory() {
27
28
29  // -------------------------- Rect -------------------------- //
30
31  function Rect(props) {
32    // extend properties from defaults
33    for (var prop in Rect.defaults) {
34      this[prop] = Rect.defaults[prop];
35    }
36
37    for (prop in props) {
38      this[prop] = props[prop];
39    }
40
41  }
42
43  Rect.defaults = {
44    x: 0,
45    y: 0,
46    width: 0,
47    height: 0
48  };
49
50  var proto = Rect.prototype;
51
52  /**
53   * Determines whether or not this rectangle wholly encloses another rectangle or point.
54   * @param {Rect} rect
55   * @returns {Boolean}
56  **/
57  proto.contains = function (rect) {
58    // points don't have width or height
59    var otherWidth = rect.width || 0;
60    var otherHeight = rect.height || 0;
61    return this.x <= rect.x &&
62      this.y <= rect.y &&
63      this.x + this.width >= rect.x + otherWidth &&
64      this.y + this.height >= rect.y + otherHeight;
65  };
66
67  /**
68   * Determines whether or not the rectangle intersects with another.
69   * @param {Rect} rect
70   * @returns {Boolean}
71  **/
72  proto.overlaps = function (rect) {
73    var thisRight = this.x + this.width;
74    var thisBottom = this.y + this.height;
75    var rectRight = rect.x + rect.width;
76    var rectBottom = rect.y + rect.height;
77
78    // http://stackoverflow.com/a/306332
79    return this.x < rectRight &&
80      thisRight > rect.x &&
81      this.y < rectBottom &&
82      thisBottom > rect.y;
83  };
84
85  /**
86   * @param {Rect} rect - the overlapping rect
87   * @returns {Array} freeRects - rects representing the area around the rect
88  **/
89  proto.getMaximalFreeRects = function (rect) {
90
91    // if no intersection, return false
92    if (!this.overlaps(rect)) {
93      return false;
94    }
95
96    var freeRects = [];
97    var freeRect;
98
99    var thisRight = this.x + this.width;
100    var thisBottom = this.y + this.height;
101    var rectRight = rect.x + rect.width;
102    var rectBottom = rect.y + rect.height;
103
104    // top
105    if (this.y < rect.y) {
106      freeRect = new Rect({
107        x: this.x,
108        y: this.y,
109        width: this.width,
110        height: rect.y - this.y
111      });
112      freeRects.push(freeRect);
113    }
114
115    // right
116    if (thisRight > rectRight) {
117      freeRect = new Rect({
118        x: rectRight,
119        y: this.y,
120        width: thisRight - rectRight,
121        height: this.height
122      });
123      freeRects.push(freeRect);
124    }
125
126    // bottom
127    if (thisBottom > rectBottom) {
128      freeRect = new Rect({
129        x: this.x,
130        y: rectBottom,
131        width: this.width,
132        height: thisBottom - rectBottom
133      });
134      freeRects.push(freeRect);
135    }
136
137    // left
138    if (this.x < rect.x) {
139      freeRect = new Rect({
140        x: this.x,
141        y: this.y,
142        width: rect.x - this.x,
143        height: this.height
144      });
145      freeRects.push(freeRect);
146    }
147
148    return freeRects;
149  };
150
151  proto.canFit = function (rect) {
152    return this.width >= rect.width && this.height >= rect.height;
153  };
154
155  return Rect;
156
157}));
158
159/**
160 * Packer
161 * bin-packing algorithm
162 */
163
164(function (window, factory) {
165  // universal module definition
166  /* jshint strict: false */ /* globals define, module, require */
167  if (typeof define == 'function' && define.amd) {
168    // AMD
169    define('packery/js/packer', ['./rect'], factory);
170  } else if (typeof module == 'object' && module.exports) {
171    // CommonJS
172    module.exports = factory(
173      require('./rect')
174    );
175  } else {
176    // browser global
177    var Packery = window.Packery = window.Packery || {};
178    Packery.Packer = factory(Packery.Rect);
179  }
180
181}(window, function factory(Rect) {
182
183
184  // -------------------------- Packer -------------------------- //
185
186  /**
187   * @param {Number} width
188   * @param {Number} height
189   * @param {String} sortDirection
190   *   topLeft for vertical, leftTop for horizontal
191   */
192  function Packer(width, height, sortDirection) {
193    this.width = width || 0;
194    this.height = height || 0;
195    this.sortDirection = sortDirection || 'downwardLeftToRight';
196
197    this.reset();
198  }
199
200  var proto = Packer.prototype;
201
202  proto.reset = function () {
203    this.spaces = [];
204
205    var initialSpace = new Rect({
206      x: 0,
207      y: 0,
208      width: this.width,
209      height: this.height
210    });
211
212    this.spaces.push(initialSpace);
213    // set sorter
214    this.sorter = sorters[this.sortDirection] || sorters.downwardLeftToRight;
215  };
216
217  // change x and y of rect to fit with in Packer's available space
217s
218  proto.pack = function (rect) {
219    for (var i = 0; i < this.spaces.length; i++) {
220      var space = this.spaces[i];
221      if (space.canFit(rect)) {
222        this.placeInSpace(rect, space);
223        break;
224      }
225    }
226  };
227
228  proto.columnPack = function (rect) {
229    for (var i = 0; i < this.spaces.length; i++) {
230      var space = this.spaces[i];
231      var canFitInSpaceColumn = space.x <= rect.x &&
232        space.x + space.width >= rect.x + rect.width &&
233        space.height >= rect.height - 0.01; // fudge number for rounding error
234      if (canFitInSpaceColumn) {
235        rect.y = space.y;
236        this.placed(rect);
237        break;
238      }
239    }
240  };
241
242  proto.rowPack = function (rect) {
243    for (var i = 0; i < this.spaces.length; i++) {
244      var space = this.spaces[i];
245      var canFitInSpaceRow = space.y <= rect.y &&
246        space.y + space.height >= rect.y + rect.height &&
247        space.width >= rect.width - 0.01; // fudge number for rounding error
248      if (canFitInSpaceRow) {
249        rect.x = space.x;
250        this.placed(rect);
251        break;
252      }
253    }
254  };
255
256  proto.placeInSpace = function (rect, space) {
257    // place rect in space
258    rect.x = space.x;
259    rect.y = space.y;
260
261    this.placed(rect);
262  };
263
264  // update spaces with placed rect
265  proto.placed = function (rect) {
266    // update spaces
267    var revisedSpaces = [];
268    for (var i = 0; i < this.spaces.length; i++) {
269      var space = this.spaces[i];
270      var newSpaces = space.getMaximalFreeRects(rect);
271      // add either the original space or the new spaces to the revised spaces
272      if (newSpaces) {
273        revisedSpaces.push.apply(revisedSpaces, newSpaces);
274      } else {
275        revisedSpaces.push(space);
276      }
277    }
278
279    this.spaces = revisedSpaces;
280
281    this.mergeSortSpaces();
282  };
283
284  proto.mergeSortSpaces = function () {
285    // remove redundant spaces
286    Packer.mergeRects(this.spaces);
287    this.spaces.sort(this.sorter);
288  };
289
290  // add a space back
291  proto.addSpace = function (rect) {
292    this.spaces.push(rect);
293    this.mergeSortSpaces();
294  };
295
296  // -------------------------- utility functions -------------------------- //
297
298  /**
299   * Remove redundant rectangle from array of rectangles
300   * @param {Array} rects: an array of Rects
301   * @returns {Array} rects: an array of Rects
302  **/
303  Packer.mergeRects = function (rects) {
304    var i = 0;
305    var rect = rects[i];
306
307    rectLoop:
308    while (rect) {
309      var j = 0;
310      var compareRect = rects[i + j];
311
312      while (compareRect) {
313        if (compareRect == rect) {
314          j++; // next
315        } else if (compareRect.contains(rect)) {
316          // remove rect
317          rects.splice(i, 1);
318          rect = rects[i]; // set next rect
319          continue rectLoop; // bail on compareLoop
320        } else if (rect.contains(compareRect)) {
321          // remove compareRect
322          rects.splice(i + j, 1);
323        } else {
324          j++;
325        }
326        compareRect = rects[i + j]; // set next compareRect
327      }
328      i++;
329      rect = rects[i];
330    }
331
332    return rects;
333  };
334
335
336  // -------------------------- sorters -------------------------- //
337
338  // functions for sorting rects in order
339  var sorters = {
340    // top down, then left to right
341    downwardLeftToRight: function (a, b) {
342      return a.y - b.y || a.x - b.x;
343    },
344    // left to right, then top down
345    rightwardTopToBottom: function (a, b) {
346      return a.x - b.x || a.y - b.y;
347    }
348  };
349
350
351  // --------------------------  -------------------------- //
352
353  return Packer;
354
355}));
356
357/**
358 * Packery Item Element
359**/
360
361(function (window, factory) {
362  // universal module definition
363  /* jshint strict: false */ /* globals define, module, require */
364  if (typeof define == 'function' && define.amd) {
365    // AMD
366    define('packery/js/item', [
367      'outlayer/outlayer',
368      './rect'
369    ],
370      factory);
371  } else if (typeof module == 'object' && module.exports) {
372    // CommonJS
373    module.exports = factory(
374      require('outlayer'),
375      require('./rect')
376    );
377  } else {
378    // browser global
379    window.Packery.Item = factory(
380      window.Outlayer,
381      window.Packery.Rect
382    );
383  }
384
385}(window, function factory(Outlayer, Rect) {
386
387
388  // -------------------------- Item -------------------------- //
389
390  var docElemStyle = document.documentElement.style;
391
392  var transformProperty = typeof docElemStyle.transform == 'string' ?
393    'transform' : 'WebkitTransform';
394
395  // sub-class Item
396  var Item = function PackeryItem() {
397    Outlayer.Item.apply(this, arguments);
398  };
399
400  var proto = Item.prototype = Object.create(Outlayer.Item.prototype);
401
402  var __create = proto._create;
403  proto._create = function () {
404    // call default _create logic
405    __create.call(this);
406    this.rect = new Rect();
407  };
408
409  var _moveTo = proto.moveTo;
410  proto.moveTo = function (x, y) {
411    // don't shift 1px while dragging
412    var dx = Math.abs(this.position.x - x);
413    var dy = Math.abs(this.position.y - y);
414
415    var canHackGoTo = this.layout.dragItemCount && !this.isPlacing &&
416      !this.isTransitioning && dx < 1 && dy < 1;
417    if (canHackGoTo) {
418      this.goTo(x, y);
419      return;
420    }
421    _moveTo.apply(this, arguments);
422  };
423
424  // -------------------------- placing -------------------------- //
425
426  proto.enablePlacing = function () {
427    this.removeTransitionStyles();
428    // remove transform property from transition
429    if (this.isTransitioning && transformProperty) {
430      this.element.style[transformProperty] = 'none';
431    }
432    this.isTransitioning = false;
433    this.getSize();
434    this.layout._setRectSize(this.element, this.rect);
435    this.isPlacing = true;
436  };
437
438  proto.disablePlacing = function () {
439    this.isPlacing = false;
440  };
441
442  // -----  ----- //
443
444  // remove element from DOM
445  proto.removeElem = function () {
446    this.element.parentNode.removeChild(this.element);
447    // add space back to packer
448    this.layout.packer.addSpace(this.rect);
449    this.emitEvent('remove', [this]);
450  };
451
452  // ----- dropPlaceholder ----- //
453
454  proto.showDropPlaceholder = function () {
455    var dropPlaceholder = this.dropPlaceholder;
456    if (!dropPlaceholder) {
457      // create dropPlaceholder
458      dropPlaceholder = this.dropPlaceholder = document.createElement('div');
459      dropPlaceholder.className = 'packery-drop-placeholder';
460      dropPlaceholder.style.position = 'absolute';
461    }
462
463    dropPlaceholder.style.width = this.size.width + 'px';
464    dropPlaceholder.style.height = this.size.height + 'px';
465    this.positionDropPlaceholder();
466    this.layout.element.appendChild(dropPlaceholder);
467  };
468
469  proto.positionDropPlaceholder = function () {
470    this.dropPlaceholder.style[transformProperty] = 'translate(' +
471      this.rect.x + 'px, ' + this.rect.y + 'px)';
472  };
473
474  proto.hideDropPlaceholder = function () {
475    this.layout.element.removeChild(this.dropPlaceholder);
476  };
477
478  // -----  ----- //
479
480  return Item;
481
482}));
483
484/*!
485 * Packery v2.0.0
486 * Gapless, draggable grid layouts
487 *
488 * Licensed GPLv3 for open source use
489 * or Packery Commercial License for commercial use
490 *
491 * http://packery.metafizzy.co
492 * Copyright 2016 Metafizzy
493 */
494
495(function (window, factory) {
496  // universal module definition
497  /* jshint strict: false */ /* globals define, module, require */
498  if (typeof define == 'function' && define.amd) {
499    // AMD
500    define('packery/js/packery', [
501      'get-size/get-size',
502      'outlayer/outlayer',
503      './rect',
504      './packer',
505      './item'
506    ],
507      factory);
508  } else if (typeof module == 'object' && module.exports) {
509    // CommonJS
510    module.exports = factory(
511      require('get-size'),
512      require('outlayer'),
513      require('./rect'),
514      require('./packer'),
515      require('./item')
516    );
517  } else {
518    // browser global
519    window.Packery = factory(
520      window.getSize,
521      window.Outlayer,
522      window.Packery.Rect,
523      window.Packery.Packer,
524      window.Packery.Item
525    );
526  }
527
528}(window, function factory(getSize, Outlayer, Rect, Packer, Item) {
529
530
531  // ----- Rect ----- //
532
533  // allow for pixel rounding errors IE8-IE11 & Firefox; #227
534  Rect.prototype.canFit = function (rect) {
535    return this.width >= rect.width - 1 && this.height >= rect.height - 1;
536  };
537
538  // -------------------------- Packery -------------------------- //
539
540  // create an Outlayer layout class
541  var Packery = Outlayer.create('packery');
542  Packery.Item = Item;
543
544  var proto = Packery.prototype;
545
546  proto._create = function () {
547    // call super
548    Outlayer.prototype._create.call(this);
549
550    // initial properties
551    this.packer = new Packer();
552    // packer for drop targets
553    this.shiftPacker = new Packer();
554    this.isEnabled = true;
555
556    this.dragItemCount = 0;
557
558    // create drag handlers
559    var _this = this;
560    this.handleDraggabilly = {
561      dragStart: function () {
562        _this.itemDragStart(this.element);
563      },
564      dragMove: function () {
565        _this.itemDragMove(this.element, this.position.x, this.position.y);
566      },
567      dragEnd: function () {
568        _this.itemDragEnd(this.element);
569      }
570    };
571
572    this.handleUIDraggable = {
573      start: function handleUIDraggableStart(event, ui) {
574        // HTML5 may trigger dragstart, dismiss HTML5 dragging
575        if (!ui) {
576          return;
577        }
578        _this.itemDragStart(event.currentTarget);
579      },
580      drag: function handleUIDraggableDrag(event, ui) {
581        if (!ui) {
582          return;
583        }
584        _this.itemDragMove(event.currentTarget, ui.position.left, ui.position.top);
585      },
586      stop: function handleUIDraggableStop(event, ui) {
587        if (!ui) {
588          return;
589        }
590        _this.itemDragEnd(event.currentTarget);
591      }
592    };
593
594  };
595
596
597  // ----- init & layout ----- //
598
599  /**
600   * logic before any new layout
601   */
602  proto._resetLayout = function () {
603    this.getSize();
604
605    this._getMeasurements();
606
607    // reset packer
608    var width, height, sortDirection;
609    // packer settings, if horizontal or vertical
610    if (this._getOption('horizontal')) {
611      width = Infinity;
612      height = this.size.innerHeight + this.gutter;
613      sortDirection = 'rightwardTopToBottom';
614    } else {
615      width = this.size.innerWidth + this.gutter;
616      height = Infinity;
617      sortDirection = 'downwardLeftToRight';
618    }
619
620    this.packer.width = this.shiftPacker.width = width;
621    this.packer.height = this.shiftPacker.height = height;
622    this.packer.sortDirection = this.shiftPacker.sortDirection = sortDirection;
623
624    this.packer.reset();
625
626    // layout
627    this.maxY = 0;
628    this.maxX = 0;
629  };
630
631  /**
632   * update columnWidth, rowHeight, & gutter
633   * @private
634   */
635  proto._getMeasurements = function () {
636    this._getMeasurement('columnWidth', 'width');
637    this._getMeasurement('rowHeight', 'height');
638    this._getMeasurement('gutter', 'width');
639  };
640
641  proto._getItemLayoutPosition = function (item) {
642    this._setRectSize(item.element, item.rect);
643    if (this.isShifting || this.dragItemCount > 0) {
644      var packMethod = this._getPackMethod();
645      this.packer[packMethod](item.rect);
646    } else {
647      this.packer.pack(item.rect);
648    }
649
650    this._setMaxXY(item.rect);
651    return item.rect;
652  };
653
654  proto.shiftLayout = function () {
655    this.isShifting = true;
656    this.layout();
657    delete this.isShifting;
658  };
659
660  proto._getPackMethod = function () {
661    return this._getOption('horizontal') ? 'rowPack' : 'columnPack';
662  };
663
664
665  /**
666   * set max X and Y value, for size of container
667   * @param {Packery.Rect} rect
668   * @private
669   */
670  proto._setMaxXY = function (rect) {
671    this.maxX = Math.max(rect.x + rect.width, this.maxX);
672    this.maxY = Math.max(rect.y + rect.height, this.maxY);
673  };
674
675  /**
676   * set the width and height of a rect, applying columnWidth and rowHeight
677   * @param {Element} elem
678   * @param {Packery.Rect} rect
679   */
680  proto._setRectSize = function (elem, rect) {
681    var size = getSize(elem);
682    var w = size.outerWidth;
683    var h = size.outerHeight;
684    // size for columnWidth and rowHeight, if available
685    // only check if size is non-zero, #177
686    if (w || h) {
687      w = this._applyGridGutter(w, this.columnWidth);
688      h = this._applyGridGutter(h, this.rowHeight);
689    }
690    // rect must fit in packer
691    rect.width = Math.min(w, this.packer.width);
692    rect.height = Math.min(h, this.packer.height);
693  };
694
695  /**
696   * fits item to columnWidth/rowHeight and adds gutter
697   * @param {Number} measurement - item width or height
698   * @param {Number} gridSize - columnWidth or rowHeight
699   * @returns measurement
700   */
701  proto._applyGridGutter = function (measurement, gridSize) {
702    // just add gutter if no gridSize
703    if (!gridSize) {
704      return measurement + this.gutter;
705    }
706    gridSize += this.gutter;
707    // fit item to columnWidth/rowHeight
708    var remainder = measurement % gridSize;
709    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
710    measurement = Math[mathMethod](measurement / gridSize) * gridSize;
711    return measurement;
712  };
713
714  proto._getContainerSize = function () {
715    if (this._getOption('horizontal')) {
716      return {
717        width: this.maxX - this.gutter
718      };
719    } else {
720      return {
721        height: this.maxY - this.gutter
722      };
723    }
724  };
725
726
727  // -------------------------- stamp -------------------------- //
728
729  /**
730   * makes space for element
731   * @param {Element} elem
732   */
733  proto._manageStamp = function (elem) {
734
735    var item = this.getItem(elem);
736    var rect;
737    if (item && item.isPlacing) {
738      rect = item.rect;
739    } else {
740      var offset = this._getElementOffset(elem);
741      rect = new Rect({
742        x: this._getOption('originLeft') ? offset.left : offset.right,
743        y: this._getOption('originTop') ? offset.top : offset.bottom
744      });
745    }
746
747    this._setRectSize(elem, rect);
748    // save its space in the packer
749    this.packer.placed(rect);
750    this._setMaxXY(rect);
751  };
752
753  // -------------------------- methods -------------------------- //
754
755  function verticalSorter(a, b) {
756    return a.position.y - b.position.y || a.position.x - b.position.x;
757  }
758
759  function horizontalSorter(a, b) {
760    return a.position.x - b.position.x || a.position.y - b.position.y;
761  }
762
763  proto.sortItemsByPosition = function () {
764    var sorter = this._getOption('horizontal') ? horizontalSorter : verticalSorter;
765    this.items.sort(sorter);
766  };
767
768  /**
769   * Fit item element in its current position
770   * Packery will position elements around it
771   * useful for expanding elements
772   *
773   * @param {Element} elem
774   * @param {Number} x - horizontal destination position, optional
775   * @param {Number} y - vertical destination position, optional
776   */
777  proto.fit = function (elem, x, y) {
778    var item = this.getItem(elem);
779    if (!item) {
780      return;
781    }
782
783    // stamp item to get it out of layout
784    this.stamp(item.element);
785    // set placing flag
786    item.enablePlacing();
787    this.updateShiftTargets(item);
788    // fall back to current position for fitting
789    x = x === undefined ? item.rect.x : x;
790    y = y === undefined ? item.rect.y : y;
791    // position it best at its destination
792    this.shift(item, x, y);
793    this._bindFitEvents(item);
794    item.moveTo(item.rect.x, item.rect.y);
795    // layout everything else
796    this.shiftLayout();
797    // return back to regularly scheduled programming
798    this.unstamp(item.element);
799    this.sortItemsByPosition();
800    item.disablePlacing();
801  };
802
803  /**
804   * emit event when item is fit and other items are laid out
805   * @param {Packery.Item} item
806   * @private
807   */
808  proto._bindFitEvents = function (item) {
809    var _this = this;
810    var ticks = 0;
811    function onLayout() {
812      ticks++;
813      if (ticks != 2) {
814        return;
815      }
816      _this.dispatchEvent('fitComplete', null, [item]);
817    }
818    // when item is laid out
819    item.once('layout', onLayout);
820    // when all items are laid out
821    this.once('layoutComplete', onLayout);
822  };
823
824  // -------------------------- resize -------------------------- //
825
826  // debounced, layout on resize
827  proto.resize = function () {
828    // don't trigger if size did not change
829    // or if resize was unbound. See #285, outlayer#9
830    if (!this.isResizeBound || !this.needsResizeLayout()) {
831      return;
832    }
833
834    if (this.options.shiftPercentResize) {
835      this.resizeShiftPercentLayout();
836    } else {
837      this.layout();
838    }
839  };
840
841  /**
842   * check if layout is needed post layout
843   * @returns Boolean
844   */
845  proto.needsResizeLayout = function () {
846    var size = getSize(this.element);
847    var innerSize = this._getOption('horizontal') ? 'innerHeight' : 'innerWidth';
848    return size[innerSize] != this.size[innerSize];
849  };
850
851  proto.resizeShiftPercentLayout = function () {
852    var items = this._getItemsForLayout(this.items);
853
854    var isHorizontal = this._getOption('horizontal');
855    var coord = isHorizontal ? 'y' : 'x';
856    var measure = isHorizontal ? 'height' : 'width';
857    var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth';
858    var innerSize = isHorizontal ? 'innerHeight' : 'innerWidth';
859
860    // proportional re-align items
861    var previousSegment = this[segmentName];
862    previousSegment = previousSegment && previousSegment + this.gutter;
863
864    if (previousSegment) {
865      this._getMeasurements();
866      var currentSegment = this[segmentName] + this.gutter;
867      items.forEach(function (item) {
868        var seg = Math.round(item.rect[coord] / previousSegment);
869        item.rect[coord] = seg * currentSegment;
870      });
871    } else {
872      var currentSize = getSize(this.element)[innerSize] + this.gutter;
873      var previousSize = this.packer[measure];
874      items.forEach(function (item) {
875        item.rect[coord] = (item.rect[coord] / previousSize) * currentSize;
876      });
877    }
878
879    this.shiftLayout();
880  };
881
882  // -------------------------- drag -------------------------- //
883
884  /**
885   * handle an item drag start event
886   * @param {Element} elem
887   */
888  proto.itemDragStart = function (elem) {
889    if (!this.isEnabled) {
890      return;
891    }
892    this.stamp(elem);
893    // this.ignore( elem );
894    var item = this.getItem(elem);
895    if (!item) {
896      return;
897    }
898
899    item.enablePlacing();
900    item.showDropPlaceholder();
901    this.dragItemCount++;
902    this.updateShiftTargets(item);
903  };
904
905  proto.updateShiftTargets = function (dropItem) {
906    this.shiftPacker.reset();
907
908    // pack stamps
909    this._getBoundingRect();
910    var isOriginLeft = this._getOption('originLeft');
911    var isOriginTop = this._getOption('originTop');
912    this.stamps.forEach(function (stamp) {
913      // ignore dragged item
914      var item = this.getItem(stamp);
915      if (item && item.isPlacing) {
916        return;
917      }
918      var offset = this._getElementOffset(stamp);
919      var rect = new Rect({
920        x: isOriginLeft ? offset.left : offset.right,
921        y: isOriginTop ? offset.top : offset.bottom
922      });
923      this._setRectSize(stamp, rect);
924      // save its space in the packer
925      this.shiftPacker.placed(rect);
926    }, this);
927
928    // reset shiftTargets
929    var isHorizontal = this._getOption('horizontal');
930    var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth';
931    var measure = isHorizontal ? 'height' : 'width';
932
933    this.shiftTargetKeys = [];
934    this.shiftTargets = [];
935    var boundsSize;
936    var segment = this[segmentName];
937    segment = segment && segment + this.gutter;
938
939    if (segment) {
940      var segmentSpan = Math.ceil(dropItem.rect[measure] / segment);
941      var segs = Math.floor((this.shiftPacker[measure] + this.gutter) / segment);
942      boundsSize = (segs - segmentSpan) * segment;
943      // add targets on top
944      for (var i = 0; i < segs; i++) {
945        this._addShiftTarget(i * segment, 0, boundsSize);
946      }
947    } else {
948      boundsSize = (this.shiftPacker[measure] + this.gutter) - dropItem.rect[measure];
949      this._addShiftTarget(0, 0, boundsSize);
950    }
951
952    // pack each item to measure where shiftTargets are
953    var items = this._getItemsForLayout(this.items);
954    var packMethod = this._getPackMethod();
955    items.forEach(function (item) {
956      var rect = item.rect;
957      this._setRectSize(item.element, rect);
958      this.shiftPacker[packMethod](rect);
959
960      // add top left corner
961      this._addShiftTarget(rect.x, rect.y, boundsSize);
962      // add bottom left / top right corner
963      var cornerX = isHorizontal ? rect.x + rect.width : rect.x;
964      var cornerY = isHorizontal ? rect.y : rect.y + rect.height;
965      this._addShiftTarget(cornerX, cornerY, boundsSize);
966
967      if (segment) {
968        // add targets for each column on bottom / row on right
969        var segSpan = Math.round(rect[measure] / segment);
970        for (var i = 1; i < segSpan; i++) {
971          var segX = isHorizontal ? cornerX : rect.x + segment * i;
972          var segY = isHorizontal ? rect.y + segment * i : cornerY;
973          this._addShiftTarget(segX, segY, boundsSize);
974        }
975      }
976    }, this);
977
978  };
979
980  proto._addShiftTarget = function (x, y, boundsSize) {
981    var checkCoord = this._getOption('horizontal') ? y : x;
982    if (checkCoord !== 0 && checkCoord > boundsSize) {
983      return;
984    }
985    // create string for a key, easier to keep track of what targets
986    var key = x + ',' + y;
987    var hasKey = this.shiftTargetKeys.indexOf(key) != -1;
988    if (hasKey) {
989      return;
990    }
991    this.shiftTargetKeys.push(key);
992    this.shiftTargets.push({ x: x, y: y });
993  };
994
995  // -------------------------- drop -------------------------- //
996
997  proto.shift = function (item, x, y) {
998    var shiftPosition;
999    var minDistance = Infinity;
1000    var position = { x: x, y: y };
1001    this.shiftTargets.forEach(function (target) {
1002      var distance = getDistance(target, position);
1003      if (distance < minDistance) {
1004        shiftPosition = target;
1005        minDistance = distance;
1006      }
1007    });
1008    item.rect.x = shiftPosition.x;
1009    item.rect.y = shiftPosition.y;
1010  };
1011
1012  function getDistance(a, b) {
1013    var dx = b.x - a.x;
1014    var dy = b.y - a.y;
1015    return Math.sqrt(dx * dx + dy * dy);
1016  }
1017
1018  // -------------------------- drag move -------------------------- //
1019
1020  var DRAG_THROTTLE_TIME = 120;
1021
1022  /**
1023   * handle an item drag move event
1024   * @param {Element} elem
1025   * @param {Number} x - horizontal change in position
1026   * @param {Number} y - vertical change in position
1027   */
1028  proto.itemDragMove = function (elem, x, y) {
1029    var item = this.isEnabled && this.getItem(elem);
1030    if (!item) {
1031      return;
1032    }
1033
1034    x -= this.size.paddingLeft;
1035    y -= this.size.paddingTop;
1036
1037    var _this = this;
1038    function onDrag() {
1039      _this.shift(item, x, y);
1040      item.positionDropPlaceholder();
1041      _this.layout();
1042    }
1043
1044    // throttle
1045    var now = new Date();
1046    if (this._itemDragTime && now - this._itemDragTime < DRAG_THROTTLE_TIME) {
1047      clearTimeout(this.dragTimeout);
1048      this.dragTimeout = setTimeout(onDrag, DRAG_THROTTLE_TIME);
1049    } else {
1050      onDrag();
1051      this._itemDragTime = now;
1052    }
1053  };
1054
1055  // -------------------------- drag end -------------------------- //
1056
1057  /**
1058   * handle an item drag end event
1059   * @param {Element} elem
1060   */
1061  proto.itemDragEnd = function (elem) {
1062    var item = this.isEnabled && this.getItem(elem);
1063    if (!item) {
1064      return;
1065    }
1066
1067    clearTimeout(this.dragTimeout);
1068    item.element.classList.add('is-positioning-post-drag');
1069
1070    var completeCount = 0;
1071    var _this = this;
1072    function onDragEndLayoutComplete() {
1073      completeCount++;
1074      if (completeCount != 2) {
1075        return;
1076      }
1077      // reset drag item
1078      item.element.classList.remove('is-positioning-post-drag');
1079      item.hideDropPlaceholder();
1080      _this.dispatchEvent('dragItemPositioned', null, [item]);
1081    }
1082
1083    item.once('layout', onDragEndLayoutComplete);
1084    this.once('layoutComplete', onDragEndLayoutComplete);
1085    item.moveTo(item.rect.x, item.rect.y);
1086    this.layout();
1087    this.dragItemCount = Math.max(0, this.dragItemCount - 1);
1088    this.sortItemsByPosition();
1089    item.disablePlacing();
1090    this.unstamp(item.element);
1091  };
1092
1093  /**
1094   * binds Draggabilly events
1095   * @param {Draggabilly} draggie
1096   */
1097  proto.bindDraggabillyEvents = function (draggie) {
1098    this._bindDraggabillyEvents(draggie, 'on');
1099  };
1100
1101  proto.unbindDraggabillyEvents = function (draggie) {
1102    this._bindDraggabillyEvents(draggie, 'off');
1103  };
1104
1105  proto._bindDraggabillyEvents = function (draggie, method) {
1106    var handlers = this.handleDraggabilly;
1107    draggie[method]('dragStart', handlers.dragStart);
1108    draggie[method]('dragMove', handlers.dragMove);
1109    draggie[method]('dragEnd', handlers.dragEnd);
1110  };
1111
1112  /**
1113   * binds jQuery UI Draggable events
1114   * @param {jQuery} $elems
1115   */
1116  proto.bindUIDraggableEvents = function ($elems) {
1117    this._bindUIDraggableEvents($elems, 'on');
1118  };
1119
1120  proto.unbindUIDraggableEvents = function ($elems) {
1121    this._bindUIDraggableEvents($elems, 'off');
1122  };
1123
1124  proto._bindUIDraggableEvents = function ($elems, method) {
1125    var handlers = this.handleUIDraggable;
1126    $elems
1127    [method]('dragstart', handlers.start)
1128    [method]('drag', handlers.drag)
1129    [method]('dragstop', handlers.stop);
1130  };
1131
1132  // ----- destroy ----- //
1133
1134  var _destroy = proto.destroy;
1135  proto.destroy = function () {
1136    _destroy.apply(this, arguments);
1137    // disable flag; prevent drag events from triggering. #72
1138    this.isEnabled = false;
1139  };
1140
1141  // -----  ----- //
1142
1143  Packery.Rect = Rect;
1144  Packery.Packer = Packer;
1145
1146  return Packery;
1147
1148}));
1149
1150/*!
1151 * Packery layout mode v2.0.1
1152 * sub-classes Packery
1153 */
1154
1155/*jshint browser: true, strict: true, undef: true, unused: true */
1156
1157(function (window, factory) {
1158
1159  // universal module definition
1160  if (typeof define == 'function' && define.amd) {
1161    // AMD
1162    define([
1163      'isotope-layout/js/layout-mode',
1164      'packery/js/packery'
1165    ],
1166      factory);
1167  } else if (typeof module == 'object' && module.exports) {
1168    // CommonJS
1169    module.exports = factory(
1170      require('isotope-layout/js/layout-mode'),
1171      require('packery')
1172    );
1173  } else {
1174    // browser global
1175    factory(
1176      window.Isotope.LayoutMode,
1177      window.Packery
1178    );
1179  }
1180
1181}(window, function factor(LayoutMode, Packery) {
1182
1183
1184  // create an Outlayer layout class
1185  var PackeryMode = LayoutMode.create('packery');
1186  var proto = PackeryMode.prototype;
1187
1188  var keepModeMethods = {
1189    _getElementOffset: true,
1190    _getMeasurement: true
1191  };
1192
1193  // inherit Packery prototype
1194  for (var method in Packery.prototype) {
1195    // do not inherit mode methods
1196    if (!keepModeMethods[method]) {
1197      proto[method] = Packery.prototype[method];
1198    }
1199  }
1200
1201  // set packer in _resetLayout
1202  var _resetLayout = proto._resetLayout;
1203  proto._resetLayout = function () {
1204    this.packer = this.packer || new Packery.Packer();
1205    this.shiftPacker = this.shiftPacker || new Packery.Packer();
1206    _resetLayout.apply(this, arguments);
1207  };
1208
1209  var _getItemLayoutPosition = proto._getItemLayoutPosition;
1210  proto._getItemLayoutPosition = function (item) {
1211    // set packery rect
1212    item.rect = item.rect || new Packery.Rect();
1213    return _getItemLayoutPosition.call(this, item);
1214  };
1215
1216  // needsResizeLayout for vertical or horizontal
1217  var _needsResizeLayout = proto.needsResizeLayout;
1218  proto.needsResizeLayout = function () {
1219    if (this._getOption('horizontal')) {
1220      return this.needsVerticalResizeLayout();
1221    } else {
1222      return _needsResizeLayout.call(this);
1223    }
1224  };
1225
1226  // point to mode options for horizontal
1227  var _getOption = proto._getOption;
1228  proto._getOption = function (option) {
1229    if (option == 'horizontal') {
1230      return this.options.isHorizontal !== undefined ?
1231        this.options.isHorizontal : this.options.horizontal;
1232    }
1233    return _getOption.apply(this.isotope, arguments);
1234  };
1235
1236  return PackeryMode;
1237
1238}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.