/
masonry-horizontal.js
152 lines (126 loc) · 4.23 KB
/
masonry-horizontal.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*!
* masonryHorizontal layout mode for Isotope
* http://isotope.metafizzy.co
*/
/*jshint browser: true, strict: true, undef: true, unused: true */
( function( window ) {
'use strict';
// -------------------------- helpers -------------------------- //
var indexOf = Array.prototype.indexOf ?
function( items, value ) {
return items.indexOf( value );
} :
function ( items, value ) {
for ( var i=0, len = items.length; i < len; i++ ) {
var item = items[i];
if ( item === value ) {
return i;
}
}
return -1;
};
// -------------------------- definition -------------------------- //
function masonryHorizontalDefinition( getSize, LayoutMode ) {
// create an Outlayer layout class
var MasonryHorizontal = LayoutMode.create('masonryHorizontal');
MasonryHorizontal.prototype._resetLayout = function() {
this.getRowHeight();
this._getMeasurement( 'gutter', 'outerHeight' );
this.rowHeight += this.gutter;
// measure rows
this.rows = Math.floor( ( this.isotope.size.innerHeight + this.gutter ) / this.rowHeight );
this.rows = Math.max( this.rows, 1 );
// reset row Xs
var i = this.rows;
this.rowXs = [];
while (i--) {
this.rowXs.push( 0 );
}
this.maxX = 0;
};
MasonryHorizontal.prototype._getItemLayoutPosition = function( item ) {
item.getSize();
// how many rows does this brick span
var rowSpan = Math.ceil( item.size.outerHeight / this.rowHeight );
rowSpan = Math.min( rowSpan, this.rows );
var rowGroup = this._getRowGroup( rowSpan );
// get the minimum Y value from the rows
var minimumX = Math.min.apply( Math, rowGroup );
var shortRowIndex = indexOf( rowGroup, minimumX );
// position the brick
var position = {
x: minimumX,
y: this.rowHeight * shortRowIndex
};
// apply setHeight to necessary rows
var setWidth = minimumX + item.size.outerWidth;
var setSpan = this.rows + 1 - rowGroup.length;
for ( var i = 0; i < setSpan; i++ ) {
this.rowXs[ shortRowIndex + i ] = setWidth;
}
return position;
};
/**
* @param {Number} rowSpan - number of rows the element spans
* @returns {Array} rowGroup
*/
MasonryHorizontal.prototype._getRowGroup = function( rowSpan ) {
if ( rowSpan < 2 ) {
// if brick spans only one row, use all the row Xs
return this.rowXs;
}
var rowGroup = [];
// how many different places could this brick fit horizontally
var groupCount = this.rows + 1 - rowSpan;
// for each group potential horizontal position
for ( var i = 0; i < groupCount; i++ ) {
// make an array of rowX values for that one group
var groupRowXs = this.rowXs.slice( i, i + rowSpan );
// and get the max value of the array
rowGroup[i] = Math.max.apply( Math, groupRowXs );
}
return rowGroup;
};
MasonryHorizontal.prototype._manageStamp = function( stamp ) {
var stampSize = getSize( stamp );
var offset = this.isotope._getElementOffset( stamp );
// get the rows that this stamp affects
var firstY = this.isotope.options.isOriginTop ? offset.top : offset.bottom;
var lastY = firstY + stampSize.outerHeight;
var firstRow = Math.floor( firstY / this.rowHeight );
firstRow = Math.max( 0, firstRow );
var lastRow = Math.floor( lastY / this.rowHeight );
lastRow = Math.min( this.rows - 1, lastRow );
// set rowXs to outside edge of the stamp
var stampMaxX = ( this.isotope.options.isOriginLeft ? offset.left : offset.right ) +
stampSize.outerWidth;
for ( var i = firstRow; i <= lastRow; i++ ) {
this.rowXs[i] = Math.max( stampMaxX, this.rowXs[i] );
}
};
MasonryHorizontal.prototype._getContainerSize = function() {
this.maxX = Math.max.apply( Math, this.rowXs );
return {
width: this.maxX
};
};
MasonryHorizontal.prototype.needsResizeLayout = function() {
return this.needsVerticalResizeLayout();
};
return MasonryHorizontal;
}
if ( typeof define === 'function' && define.amd ) {
// AMD
define( [
'get-size/get-size',
'isotope/js/layout-mode'
],
masonryHorizontalDefinition );
} else {
// browser global
masonryHorizontalDefinition(
window.getSize,
window.Isotope.LayoutMode
);
}
})( window );