New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Centered Layout #8

Open
davidmerrique opened this Issue Apr 16, 2013 · 23 comments

Comments

@davidmerrique

davidmerrique commented Apr 16, 2013

Are there any plans to add a "centered" option? Like the "Centered Masonry" in Isotope?

http://isotope.metafizzy.co/custom-layout-modes/centered-masonry.html

That's the only thing that's missing for me right now.

@desandro

This comment has been minimized.

Member

desandro commented Apr 16, 2013

Nope. If you want to center your layout, you can just do that with your own CSS.

http://codepen.io/desandro/pen/xEzKo

This feature made sense if you use explicit widths for columns. But with Packery, columns can be fluid. Most likely, this feature will be removed from Isotope and from Masonry.

@desandro desandro closed this Apr 16, 2013

@jnns

This comment has been minimized.

jnns commented Apr 22, 2013

Sorry for responding to a closed issue, but I wonder what the rationale behind abandoning the isFitWidth feature in Masonry is.

You're right that CSS can be used with fluid columns, but what about fixed size columns? At the moment, the only solution that comes to mind in order to remove surplus space is to use a lot of css media queries to resize the container in correspondence to the number or columns. This seems a bit cumbersome.

@desandro

This comment has been minimized.

Member

desandro commented Apr 22, 2013

I'm happy to keep this discussion going 🎐

what the rationale behind abandoning the isFitWidth feature in Masonry is

  1. isFitWidth will not work with element sizing because of circular logic with percentage width columns.
  2. I could add isFitWidth feature and then add a disclaimer that it only works with fixed-sized columns. But I see this as more problematic than just removing the feature all together.

If you do need isFitWidth, you can implement it with some JS. See http://codepen.io/desandro/pen/chisC

@jnns

This comment has been minimized.

jnns commented Apr 22, 2013

Thank you very much for the quick response, David.

I see your point. Your JS solution is really nice; maybe you can link to your codepen snippet in the docs once you remove the feature.

@ScotterC

This comment has been minimized.

ScotterC commented May 15, 2013

Thanks for the JS solution for fixed elements.

@macsupport

This comment has been minimized.

macsupport commented Jun 4, 2013

I note on first loading the page in your example, http://codepen.io/desandro/pen/chisC , the items are not centered initially but do center when the window size is changed slightly. I see this in Firefox 22 on Mac and Windows.

@desandro

This comment has been minimized.

Member

desandro commented Jun 4, 2013

Good catch. I've updated it with a missing onResize()

http://codepen.io/desandro/pen/chisC

@squidis

This comment has been minimized.

squidis commented Jun 27, 2013

Hi, does this centered fix work with jquery packery objects?

@desandro

This comment has been minimized.

Member

desandro commented Jun 27, 2013

Here's the example using jQuery http://codepen.io/desandro/pen/nfkth

@squidis

This comment has been minimized.

squidis commented Jun 28, 2013

Thanks for the fix, took me a while but I have it working.

@markgarrigan

This comment has been minimized.

markgarrigan commented Jul 31, 2013

In case anyone stumbles on this looking for centered layout issues. Here's a codepen using a 960px container with 4 columns and 4 different box sizes.

http://codepen.io/anon/pen/bBAiw

@desandro

This comment has been minimized.

Member

desandro commented Sep 4, 2013

Thinking of adding isFitWidth to Packery.

@marcotisi

This comment has been minimized.

marcotisi commented Apr 1, 2014

Hi desandro, thanks for your excellent work with your packery script. I've found a bug in the function _getContainerSize in case you want to center the container under certain conditions.
Consider this codepen

http://codepen.io/anon/pen/GFsEy

As you can see, if there is an empty space at y = 0 that can't be filled with any element, the function fails and the container is shrinked,
I suggest to modify the function _getContainerSize like this:

Packery.prototype._getContainerSize = function() {
  // remove empty space from fit width
  var emptyWidth = 0;
  var maxFill = 0;
  for ( var i=0, len = this.items.length; i < len; i++ ) {
    var item = this.items[i];
    if((item.position.x + item.rect.width) > maxFill) {
        maxFill = item.position.x + item.rect.width;
    }
  }
  for ( var i=0, len = this.packer.spaces.length; i < len; i++ ) {
    var space = this.packer.spaces[i];
    if ( space.y === 0 && space.x > maxFill) {
      emptyWidth += space.width;
    }
  }

  return {
    width: this.fitWidth - emptyWidth - this.gutter,
    height: this.maxY - this.gutter
  };
};
@desandro

This comment has been minimized.

Member

desandro commented Apr 1, 2014

Hi @mtisi! Thanks for catching this a bug. I believe this was a problem with not factoring in gutter. I've refactored the code.

Here's your example http://codepen.io/desandro/pen/kbchD

The previous examples have been updated.

@gpetrioli

This comment has been minimized.

gpetrioli commented Jul 1, 2014

May i suggest this slight alteration/addition so that it will stay centered even when there are not enough items to fill a full width row
At the end of the Packery.prototype._getContainerSize method

var itemsWidth = 0;
$.each(this.items, function(idx,item){itemsWidth += item.rect.width}); 
return {
  width: Math.min(itemsWidth, this.fitWidth - this.gutter),
  height: this.maxY - this.gutter
};

Demo at http://codepen.io/gpetrioli/pen/oaqbI

@jkrehm

This comment has been minimized.

jkrehm commented Oct 30, 2014

I think the CodePen has a regression in the _getContainerSize function. The emptyWidth variable is calculated but never used. I think it should be:

Packery.prototype._getContainerSize = function() {
  // remove empty space from fit width
  var emptyWidth = 0;
  for ( var i=0, len = this.packer.spaces.length; i < len; i++ ) {
    var space = this.packer.spaces[i];
    if ( space.y === 0 && space.height === Number.POSITIVE_INFINITY ) {
      emptyWidth += space.width;
    }
  }

  return {
    width: this.fitWidth - this.gutter - emptyWidth,
    height: this.maxY - this.gutter
  };
};

At least that's what makes it work correctly for the project I'm working on.

@desandro

This comment has been minimized.

Member

desandro commented Oct 31, 2014

@jkrehm Thanks! I've updated the CodePen http://codepen.io/desandro/pen/chisC

@voltmn

This comment has been minimized.

voltmn commented Mar 2, 2015

@desandro Thanks a lot for this brilliant work with packery script, it's magic :) I have a question about isotope+packery centering. Is it possible to merge this js http://codepen.io/desandro/pen/chisC
and packery-mode.pkgd.min.js (not packery.pkgd.js) right? Because it's not working together.

@desandro

This comment has been minimized.

Member

desandro commented Mar 2, 2015

@voltmn Sure thing. Use this CodePen: http://codepen.io/desandro/pen/wBxvKe

// overwrite Packery methods
var PackeryMode = Isotope.LayoutMode.modes.packery;
var __resetLayout = PackeryMode.prototype._resetLayout;
PackeryMode.prototype._resetLayout = function() {
  __resetLayout.call( this );
  // reset packer
  var parentSize = getSize( this.element.parentNode );
  var colW = this.columnWidth + this.gutter;
  this.fitWidth = Math.floor( ( parentSize.innerWidth + this.gutter ) / colW ) * colW;
  this.packer.width = this.fitWidth;
  this.packer.height = Number.POSITIVE_INFINITY;
  this.packer.reset();
};

PackeryMode.prototype._getContainerSize = function() {
  // remove empty space from fit width
  var emptyWidth = 0;
  for ( var i=0, len = this.packer.spaces.length; i < len; i++ ) {
    var space = this.packer.spaces[i];
    if ( space.y === 0 && space.height === Number.POSITIVE_INFINITY ) {
      emptyWidth += space.width;
    }
  }

  return {
    width: this.fitWidth - this.gutter,
    height: this.maxY - this.gutter
  };
};

// always resize
PackeryMode.prototype.needsResizeLayout = function() {
  return true;
};
@voltmn

This comment has been minimized.

voltmn commented Mar 2, 2015

Wow, so easy! Thanks!

@Lucas-C

This comment has been minimized.

Lucas-C commented Apr 21, 2015

I tried to use that hack, but it looks like Packery.prototype.resize does not call the .needsResizeLayout() method defined in Outlayer. Hence, overriding Packery.prototype.needsResizeLayout as done is the CodePen does not work : the function simply does not get called.

As a result, the layout resize does not always happen because the return in Packery.prototype.resize acts as a shortcircuit.
I hope my explanations are clear enough. Do you see a way to solve this issue ?

Also, are you still considering to implement that behaviour as a functionality of Packery ? Because else such a hack will be difficult to maintain as Packery's code evolve.

@n8-sd

This comment has been minimized.

n8-sd commented Sep 8, 2017

I could add isFitWidth feature and then add a disclaimer that it only works with fixed-sized columns. But I see this as more problematic than just removing the feature all together.

I disagree with this, a functioning integrated option that doesn't work in a situation thats in the documentation, thats fine.

Currently am using isotope via a vue wrapper and can't get you js solutions working via that.

@NBurke1

This comment has been minimized.

NBurke1 commented Feb 9, 2018

+1

sometimes things just need to be centered :)

Struggling to get the codepen examples working, but I'm sure i'll get there eventually...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment