muuri: Rounding problem

The scenario

I have two grids in which to exchange items. The items take on different sizes based on the grid that contains them. In both cases the dimensions are relative (e.g. width: 80% in the first grid, width: 30% in the second grid).

When an item is dragged, it is inserted into the dragContainer and I have to fix its size (e.g. width: 100px). If an item is dragged into the other grid, I have to calculate what dimensions it would have and apply them.

<div align="center"> </div>

The problem

Since rounding up the dimensions could break the layout I have to use

layout: {
  rounding: false
}

The problem is that I can’t accurately calculate the size of the item. The dimension values ​​given to me by the DOM are already rounded. Even if the error in the calculation is of some fraction of a pixel it is enough to break the layout.

Possible solution

The best solution would be to set Muuri to round the dimensions down instead of up, It should be enough to replace Math.round with Math.floor here.

This will also remove any possible layout breakage due to the use of relative dimensions (using rounding), do you think it’s a feasible change?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 20

Most upvoted comments

I am creating muuri-react utilities to generate the style of the components. I was hoping to find a simpler solution that did not require access to the DOM, but in any case I will try to make them as simple as possible.

Thanks a lot for the help and for the fast fix!

Since I am doing many tests and working with different use cases, if you wanted to open an issue in which to collect feedback on version 0.9.0 before its release, I would gladly contribute.

I will do other tests, but I think you can already highlight this issue as ready 😃

I think I fixed it.

I don’t think the problem is related to layoutOnResize, rather I think there are dimensions that can break the layout, and increasing the refresh rate increases the chances that the layout is calculated with these dimensions.

Yes, you’re right, there are edge case dimensions that do break the layout currently.

Another clue that prompts me to think about this is that the problem always appears with the first item on the third row, regardless of the number of items per row.

I actually got this issue reproduced in a variety of ways with even only four items in the grid.

Taking a quick look at the packer code and at the first decimal places of the width .06245 that I got, I would say that the eps value .001 is one of the causes of the problem.

The epsilon value is fine as is actually (at least according to my tests), but the problem is that it isn’t used in all places where needed at the moment.

I just updated the dev branch with a potential fix to this whole mess, did a deep look into the logic of Packer and refactored it to be more resilient with decimal values. Here’s your original test case with the latest dev version: https://codepen.io/niklasramo/pen/BaNebmN. Let me know if you can break it 😉

@Paol-imi I’m still not understanding why you can’t use the layout.rounding = false. I’m actually thinking the whole rounding feature should probably be deprecated as it usually leads to more confusion than necessary and all dimensions (relative or absolute) should work when layout.rounding is set to false.

That being said I actually noticed a little issue in your demo when I set layout.rounding = false. When I tried to resize the window very quickly sometimes the last item was positioned to the bottom right instead of bottom left. Not sure if it’s an issue with Muuri itself or your muuri-react lib, but I’ll try to take a look at that.

If you really really need to manipulate the item sizes just for the layout algorithm you can feed the packer manipulated values: https://codepen.io/niklasramo/pen/xPoVPe