mirror of https://github.com/metafizzy/isotope
Filter & sort magical layouts
http://isotope.metafizzy.co
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.0 KiB
145 lines
4.0 KiB
( 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.resize = function() { |
|
this.resizeVertical(); |
|
}; |
|
|
|
return MasonryHorizontal; |
|
|
|
} |
|
|
|
if ( typeof define === 'function' && define.amd ) { |
|
// AMD |
|
define( [ |
|
'get-size/get-size', |
|
'../js/layout-mode' |
|
], |
|
masonryHorizontalDefinition ); |
|
} else { |
|
// browser global |
|
masonryHorizontalDefinition( |
|
window.getSize, |
|
window.Isotope.LayoutMode |
|
); |
|
} |
|
|
|
})( window );
|
|
|