/*! * masonryHorizontal layout mode for Isotope * v2.0.1 * https://isotope.metafizzy.co/layout-modes/masonryhorizontal.html */ /*jshint browser: true, strict: true, undef: true, unused: true */ ( function( window, factory ) { 'use strict'; // universal module definition if ( typeof define === 'function' && define.amd ) { // AMD define( [ 'get-size/get-size', 'isotope-layout/js/layout-mode' ], factory ); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( require('get-size'), require('isotope-layout/js/layout-mode') ); } else { // browser global factory( window.getSize, window.Isotope.LayoutMode ); } }( window, function factory( getSize, LayoutMode ) { 'use strict'; // -------------------------- definition -------------------------- // // create an Outlayer layout class var MasonryHorizontal = LayoutMode.create('masonryHorizontal'); var proto = MasonryHorizontal.prototype; proto._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; }; proto._getItemLayoutPosition = function( item ) { item.getSize(); // how many rows does this brick span var remainder = item.size.outerHeight % this.rowHeight; var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; // round if off by 1 pixel, otherwise use ceil var rowSpan = Math[ mathMethod ]( item.size.outerHeight / this.rowHeight ); rowSpan = Math.min( rowSpan, this.rows ); var rowGroup = this._getRowGroup( rowSpan ); // get the minimum X value from the rows var minimumX = Math.min.apply( Math, rowGroup ); var shortRowIndex = rowGroup.indexOf( 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 */ proto._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; }; proto._manageStamp = function( stamp ) { var stampSize = getSize( stamp ); var offset = this.isotope._getElementOffset( stamp ); // get the rows that this stamp affects var firstY = this._getOption('originTop') ? 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._getOption('originLeft') ? offset.left : offset.right ) + stampSize.outerWidth; for ( var i = firstRow; i <= lastRow; i++ ) { this.rowXs[i] = Math.max( stampMaxX, this.rowXs[i] ); } }; proto._getContainerSize = function() { this.maxX = Math.max.apply( Math, this.rowXs ); return { width: this.maxX }; }; proto.needsResizeLayout = function() { return this.needsVerticalResizeLayout(); }; return MasonryHorizontal; }));