123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- /*!
- * Masonry v3.3.2
- * Cascading grid layout library
- * http://masonry.desandro.com
- * MIT License
- * by David DeSandro
- */
- ( function( window, factory ) {
- 'use strict';
- // universal module definition
- if ( typeof define === 'function' && define.amd ) {
- // AMD
- define( [
- 'outlayer/outlayer',
- 'get-size/get-size',
- 'fizzy-ui-utils/utils'
- ],
- factory );
- } else if ( typeof exports === 'object' ) {
- // CommonJS
- module.exports = factory(
- require('outlayer'),
- require('get-size'),
- require('fizzy-ui-utils')
- );
- } else {
- // browser global
- window.Masonry = factory(
- window.Outlayer,
- window.getSize,
- window.fizzyUIUtils
- );
- }
- }( window, function factory( Outlayer, getSize, utils ) {
- 'use strict';
- // -------------------------- masonryDefinition -------------------------- //
- // create an Outlayer layout class
- var Masonry = Outlayer.create('masonry');
- Masonry.prototype._resetLayout = function() {
- this.getSize();
- this._getMeasurement( 'columnWidth', 'outerWidth' );
- this._getMeasurement( 'gutter', 'outerWidth' );
- this.measureColumns();
- // reset column Y
- var i = this.cols;
- this.colYs = [];
- while (i--) {
- this.colYs.push( 0 );
- }
- this.maxY = 0;
- };
- Masonry.prototype.measureColumns = function() {
- this.getContainerWidth();
- // if columnWidth is 0, default to outerWidth of first item
- if ( !this.columnWidth ) {
- var firstItem = this.items[0];
- var firstItemElem = firstItem && firstItem.element;
- // columnWidth fall back to item of first element
- this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
- // if first elem has no width, default to size of container
- this.containerWidth;
- }
- var columnWidth = this.columnWidth += this.gutter;
- // calculate columns
- var containerWidth = this.containerWidth + this.gutter;
- var cols = containerWidth / columnWidth;
- // fix rounding errors, typically with gutters
- var excess = columnWidth - containerWidth % columnWidth;
- // if overshoot is less than a pixel, round up, otherwise floor it
- var mathMethod = excess && excess < 1 ? 'round' : 'floor';
- cols = Math[ mathMethod ]( cols );
- this.cols = Math.max( cols, 1 );
- };
- Masonry.prototype.getContainerWidth = function() {
- // container is parent if fit width
- var container = this.options.isFitWidth ? this.element.parentNode : this.element;
- // check that this.size and size are there
- // IE8 triggers resize on body size change, so they might not be
- var size = getSize( container );
- this.containerWidth = size && size.innerWidth;
- };
- Masonry.prototype._getItemLayoutPosition = function( item ) {
- item.getSize();
- // how many columns does this brick span
- var remainder = item.size.outerWidth % this.columnWidth;
- var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
- // round if off by 1 pixel, otherwise use ceil
- var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
- colSpan = Math.min( colSpan, this.cols );
- var colGroup = this._getColGroup( colSpan );
- // get the minimum Y value from the columns
- var minimumY = Math.min.apply( Math, colGroup );
- var shortColIndex = utils.indexOf( colGroup, minimumY );
- // position the brick
- var position = {
- x: this.columnWidth * shortColIndex,
- y: minimumY
- };
- // apply setHeight to necessary columns
- var setHeight = minimumY + item.size.outerHeight;
- var setSpan = this.cols + 1 - colGroup.length;
- for ( var i = 0; i < setSpan; i++ ) {
- this.colYs[ shortColIndex + i ] = setHeight;
- }
- return position;
- };
- /**
- * @param {Number} colSpan - number of columns the element spans
- * @returns {Array} colGroup
- */
- Masonry.prototype._getColGroup = function( colSpan ) {
- if ( colSpan < 2 ) {
- // if brick spans only one column, use all the column Ys
- return this.colYs;
- }
- var colGroup = [];
- // how many different places could this brick fit horizontally
- var groupCount = this.cols + 1 - colSpan;
- // for each group potential horizontal position
- for ( var i = 0; i < groupCount; i++ ) {
- // make an array of colY values for that one group
- var groupColYs = this.colYs.slice( i, i + colSpan );
- // and get the max value of the array
- colGroup[i] = Math.max.apply( Math, groupColYs );
- }
- return colGroup;
- };
- Masonry.prototype._manageStamp = function( stamp ) {
- var stampSize = getSize( stamp );
- var offset = this._getElementOffset( stamp );
- // get the columns that this stamp affects
- var firstX = this.options.isOriginLeft ? offset.left : offset.right;
- var lastX = firstX + stampSize.outerWidth;
- var firstCol = Math.floor( firstX / this.columnWidth );
- firstCol = Math.max( 0, firstCol );
- var lastCol = Math.floor( lastX / this.columnWidth );
- // lastCol should not go over if multiple of columnWidth #425
- lastCol -= lastX % this.columnWidth ? 0 : 1;
- lastCol = Math.min( this.cols - 1, lastCol );
- // set colYs to bottom of the stamp
- var stampMaxY = ( this.options.isOriginTop ? offset.top : offset.bottom ) +
- stampSize.outerHeight;
- for ( var i = firstCol; i <= lastCol; i++ ) {
- this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
- }
- };
- Masonry.prototype._getContainerSize = function() {
- this.maxY = Math.max.apply( Math, this.colYs );
- var size = {
- height: this.maxY
- };
- if ( this.options.isFitWidth ) {
- size.width = this._getContainerFitWidth();
- }
- return size;
- };
- Masonry.prototype._getContainerFitWidth = function() {
- var unusedCols = 0;
- // count unused columns
- var i = this.cols;
- while ( --i ) {
- if ( this.colYs[i] !== 0 ) {
- break;
- }
- unusedCols++;
- }
- // fit container to columns that have been used
- return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
- };
- Masonry.prototype.needsResizeLayout = function() {
- var previousWidth = this.containerWidth;
- this.getContainerWidth();
- return previousWidth !== this.containerWidth;
- };
- return Masonry;
- }));
|