---
title: Centered Masonry
layout: default
category: custom-layout-modes
---

<style>
  #container {
    margin: 0 auto 20px;
  }
</style>

<section id="copy">
  <p><a href="../docs/layout-modes.html#modified_layout_modes">Modified masonry layout mode</a> for centered container.</p>
</section>

<section id="options" class="clearfix">

  {% include filter-buttons.html %}

  {% include sort-buttons.html %}

  <h3>Etc</h3>

  <ul id="etc" class="clearfix">
    <li id="toggle-sizes"><a href="#toggle-sizes">Toggle variable sizes</a></li>
    <li id="insert"><a href="#insert">Insert new elements</a></li>
    <li id="append"><a href='#append'>Append new elements</a></li>
    <li id="shuffle"><a href='#shuffle'>Shuffle</a></li>
  </ul>

</section> <!-- #options -->

<div id="container" class="clickable clearfix">
  {% for elem_number in site.best_of_order %}
    {% assign element = site.elements[elem_number] %}
    {% include element-partial.html %}
  {% endfor %}
</div> <!-- #container -->


<script src="../{{ site.jquery_js }}"></script>
<script src="../{{ site.isotope_js }}"></script>
<script src="../js/fake-element.js"></script>
<script>

  $.Isotope.prototype._getCenteredMasonryColumns = function() {
    this.width = this.element.width();
    
    var parentWidth = this.element.parent().width();
    
                  // i.e. options.masonry && options.masonry.columnWidth
    var colW = this.options.masonry && this.options.masonry.columnWidth ||
                  // or use the size of the first item
                  this.$filteredAtoms.outerWidth(true) ||
                  // if there's no items, use size of container
                  parentWidth;
    
    var cols = Math.floor( parentWidth / colW );
    cols = Math.max( cols, 1 );

    // i.e. this.masonry.cols = ....
    this.masonry.cols = cols;
    // i.e. this.masonry.columnWidth = ...
    this.masonry.columnWidth = colW;
  };
  
  $.Isotope.prototype._masonryReset = function() {
    // layout-specific props
    this.masonry = {};
    // FIXME shouldn't have to call this again
    this._getCenteredMasonryColumns();
    var i = this.masonry.cols;
    this.masonry.colYs = [];
    while (i--) {
      this.masonry.colYs.push( 0 );
    }
  };

  $.Isotope.prototype._masonryResizeChanged = function() {
    var prevColCount = this.masonry.cols;
    // get updated colCount
    this._getCenteredMasonryColumns();
    return ( this.masonry.cols !== prevColCount );
  };
  
  $.Isotope.prototype._masonryGetContainerSize = function() {
    var unusedCols = 0,
        i = this.masonry.cols;
    // count unused columns
    while ( --i ) {
      if ( this.masonry.colYs[i] !== 0 ) {
        break;
      }
      unusedCols++;
    }
    
    return {
          height : Math.max.apply( Math, this.masonry.colYs ),
          // fit container to columns that have been used;
          width : (this.masonry.cols - unusedCols) * this.masonry.columnWidth
        };
  };


  $(function(){
    
    var $container = $('#container');
    
    {% include random-sizes.js %}
    
    $container.isotope({
      itemSelector : '.element',
      masonry : {
        columnWidth : 120
      },
      getSortData : {
        symbol : function( $elem ) {
          return $elem.attr('data-symbol');
        },
        category : function( $elem ) {
          return $elem.attr('data-category');
        },
        number : function( $elem ) {
          return parseInt( $elem.find('.number').text(), 10 );
        },
        weight : function( $elem ) {
          return parseFloat( $elem.find('.weight').text().replace( /[\(\)]/g, '') );
        },
        name : function ( $elem ) {
          return $elem.find('.name').text();
        }
      }
    });
      
    {% include option-set-buttons.js %}

    {% include add-buttons.js %}

    {% include change-sizes.js %}

    var $sortBy = $('#sort-by');
    $('#shuffle a').click(function(){
      $container.isotope('shuffle');
      $sortBy.find('.selected').removeClass('selected');
      $sortBy.find('[data-option-value="random"]').addClass('selected');
      return false;
    });
    
  });
</script>