metafizzy / packery

:bento: Gapless, draggable grid layouts
https://packery.metafizzy.co
4.13k stars 315 forks source link

Centered Layout #8

Open davidmerrique opened 11 years ago

davidmerrique commented 11 years ago

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 commented 11 years ago

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.

jnns commented 11 years ago

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 commented 11 years ago

I'm happy to keep this discussion going :wind_chime:

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 commented 11 years ago

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 commented 11 years ago

Thanks for the JS solution for fixed elements.

macsupport commented 11 years ago

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 commented 11 years ago

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

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

squidis commented 11 years ago

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

desandro commented 11 years ago

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

squidis commented 11 years ago

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

markgarrigan commented 11 years ago

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 commented 11 years ago

Thinking of adding isFitWidth to Packery.

marcotisi commented 10 years ago

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 commented 10 years ago

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 commented 10 years ago

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 commented 9 years ago

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 commented 9 years ago

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

voltmn commented 9 years ago

@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 commented 9 years ago

@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 commented 9 years ago

Wow, so easy! Thanks!

Lucas-C commented 9 years ago

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-dev commented 6 years ago

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 commented 6 years ago

+1

sometimes things just need to be centered :)

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

xe4me commented 5 years ago

Unfortunately, none of these examples is working properly. As soon as you put a max-width in the container, it blows

tolgaulas commented 2 months ago

At present, web site(https://packery.metafizzy.co/extras)'s pointed solution (https://codepen.io/desandro/pen/chisC) works only fixed width.

This hack worked nice for me: