haltu / muuri

Infinite responsive, sortable, filterable and draggable layouts
https://muuri.dev
MIT License
10.8k stars 643 forks source link

Set item height on fluid layout via custom layout() function #473

Open thednp opened 3 years ago

thednp commented 3 years ago

Howzit goin everyone?

I've looking for a solution for something I'm working on, a grid with percentage based elements:

issue

Because of the ~0.016px difference, the last two images do not align left as expected. Now to solve this I found a partial solution for the issues, I want this to take into account the above mentioned dimensions for mobiles and desktop PCs and calculate a fixed rounded size for items to solve both misalignment and out of order items:

This is the custom layout I'm using

const defaultLayoutSettings = {
  fillGaps: true,
  horizontal: false,
  alignRight: false,
  alignBottom: false,
  rounding: false,
};

Grid.defaultOptions.layout = function updateLayout(grid, layoutId, items, width, height, callback) {
  Grid.defaultPacker.setOptions(defaultLayoutSettings);
  return Grid.defaultPacker.createLayout(
    grid,
    layoutId,
    items,
    width,
    height,
    (layout) => {
      // Here you can modify the layout data before it's passed on to Muuri.
      items.forEach((item) => {
        const el = item._element;
        el.style.height = '';
        item._refreshDimensions();
        const h = Math.max(0, Math.round(item._height));
        el.style.height = `${h}px`;
      });
      callback(layout);
    },
  );
};

This is what happens on resize:

image

However if I remove the item._refreshDimensions() line, the layout won't brake like shown above, but will no longer switch from 18vh to 18vw height, which is intended in the first place.

So the question is: what does my function need to make this work?

I am open to any suggestion.