PageSourceSearch

https://www.topcamping.at/typo3conf/ext/mw_theme/Resources/Public/Isotope/packery.js?1761991622

js topcamping.at collected 2026-10-09 04:09:22 UTC 31,440 bytes, 1,239 lines download raw bytes

vendor: 31,440 bytes, lines 1-1239
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
31function 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
43Rect.defaults = {
44  x: 0,
45  y: 0,
46  width: 0,
47  height: 0
48};
49
50var 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**/
57proto.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**/
72proto.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**/
89proto.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
151proto.canFit = function( rect ) {
152  return this.width >= rect.width && this.height >= rect.height;
153};
154
155return 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 */
192function 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
200var proto = Packer.prototype;
201
202proto.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 spaces
218proto.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
228proto.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
242proto.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
256proto.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
265proto.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
284proto.mergeSortSpaces = function() {
285  // remove redundant spaces
286  Packer.mergeRects( this.spaces );
287  this.spaces.sort( this.sorter );
288};
289
290// add a space back
291proto.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**/
303Packer.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
339var 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
353return 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
390var docElemStyle = document.documentElement.style;
391
392var transformProperty = typeof docElemStyle.transform == 'string' ?
393  'transform' : 'WebkitTransform';
394
395// sub-class Item
396var Item = function PackeryItem() {
397  Outlayer.Item.apply( this, arguments );
398};
399
400var proto = Item.prototype = Object.create( Outlayer.Item.prototype );
401
402var __create = proto._create;
403proto._create = function() {
404  // call default _create logic
405  __create.call( this );
406  this.rect = new Rect();
407};
408
409var _moveTo = proto.moveTo;
410proto.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
426proto.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
438proto.disablePlacing = function() {
439  this.isPlacing = false;
440};
441
442// -----  ----- //
443
444// remove element from DOM
445proto.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
454proto.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
469proto.positionDropPlaceholder = function() {
470  this.dropPlaceholder.style[ transformProperty ] = 'translate(' +
471    this.rect.x + 'px, ' + this.rect.y + 'px)';
472};
473
474proto.hideDropPlaceholder = function() {
475  this.layout.element.removeChild( this.dropPlaceholder );
476};
477
478// -----  ----- //
479
480return 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
534Rect.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
541var Packery = Outlayer.create('packery');
542Packery.Item = Item;
543
544var proto = Packery.prototype;
545
546proto._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 */
602proto._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 */
635proto._getMeasurements = function() {
636  this._getMeasurement( 'columnWidth', 'width' );
637  this._getMeasurement( 'rowHeight', 'height' );
638  this._getMeasurement( 'gutter', 'width' );
639};
640
641proto._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
654proto.shiftLayout = function() {
655  this.isShifting = true;
656  this.layout();
657  delete this.isShifting;
658};
659
660proto._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 */
670proto._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 */
680proto._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 */
701proto._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
714proto._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 */
733proto._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
755function verticalSorter( a, b ) {
756  return a.position.y - b.position.y || a.position.x - b.position.x;
757}
758
759function horizontalSorter( a, b ) {
760  return a.position.x - b.position.x || a.position.y - b.position.y;
761}
762
763proto.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 */
777proto.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 */
808proto._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
827proto.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 */
845proto.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
851proto.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 */
888proto.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
905proto.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
980proto._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
997proto.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
1012function 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
1020var 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 */
1028proto.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 */
1061proto.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 */
1097proto.bindDraggabillyEvents = function( draggie ) {
1098  this._bindDraggabillyEvents( draggie, 'on' );
1099};
1100
1101proto.unbindDraggabillyEvents = function( draggie ) {
1102  this._bindDraggabillyEvents( draggie, 'off' );
1103};
1104
1105proto._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 */
1116proto.bindUIDraggableEvents = function( $elems ) {
1117  this._bindUIDraggableEvents( $elems, 'on' );
1118};
1119
1120proto.unbindUIDraggableEvents = function( $elems ) {
1121  this._bindUIDraggableEvents( $elems, 'off' );
1122};
1123
1124proto._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
1134var _destroy = proto.destroy;
1135proto.destroy = function() {
1136  _destroy.apply( this, arguments );
1137  // disable flag; prevent drag events from triggering. #72
1138  this.isEnabled = false;
1139};
1140
1141// -----  ----- //
1142
1143Packery.Rect = Rect;
1144Packery.Packer = Packer;
1145
1146return 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}));
1239

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.