Search code examples
javascriptcssmathgeometryreact-grid-layout

How to find new height unit while switching the row height in react-grid-layout?


I'm using react-grid-layout and using rowHeight to set the height of a "grid item" explicitly.

Now i want to change the rowHeight to a smaller value (on click of a button).

Current Behaviour: when the change is happened, all the tile heights are changed immediately (grid items are squished because of small heights)

Expected Behaviour: the tile height should be maintained same as old row height, but the height unit (h) should be increased.

This seems easy without margin, but react-grid-layout uses a margin property. so that

actual pixel height is (rowHeight * h) + (marginH * (h - 1).

For example, with rowHeight=30, margin=[10,10] and a unit with height 4, the calculation is (30 * 4) + (10 * 3) enter image description here

https://github.com/react-grid-layout/react-grid-layout#grid-item-heights-and-widths

Now i can calculate the old tile height.

But how can i find how many h i need, when i switch the row height from rowHeight=30 to rowHeight=10 and vice versa?

I have tried:

          const newRowHeight = 10;
          const oldTileHeight = (rowHeight * item.h) + (gap * (item.h - 1));

          const newH = oldTileHeight / newRowHeight;

But this doesn't work! It gives me some extra height.

Grid item Old height: 320px; New Height: 816px;

Any ideas what could be the issue here?


Solution

  • Cool maths! Here's what I've worked out:

    /*
    NOTES:
    • For ease, I'll rename your "h" to "n"
    • "H" stands for "height"
    • "o" prefix means old, "n" prefix means new
    */
    
    tileH = (oRowH * oN) + marginH * (oN - 1)
    tileH = (nRowH * nN) + marginH * (nN - 1)
    
    // Let's talk maths. We can turn those 2 to:
    tileH = oN * (oRowH + marginH) - marginH
    tileH = nN * (nRowH + marginH) - marginH
    
    // Since tileH doesn't change:
    nN * (nRowH + marginH) = oN * (oRowH + marginH)
    nN = oN * (oRowH + marginH) / (nRowH + marginH)
    
    // Or, alternatively:
    nN * (nRowH + marginH) - marginH = tileH
    nN * (nRowH + marginH) = tileH + marginH
    nN = (tileH + marginH) / (nRowH + marginH)
    

    That's a handful, but it should be correct. So:

    const newRowHeight = 10;
    const oldTileHeight = (rowHeight * item.h) + (gap * (item.h - 1));
    const newH = item.h * (rowHeight + gap) / (newRowHeight + gap);
    // OR:
    const newH = (oldTileHeight + gap) / (newRowHeight + gap);
    

    So, your solution of oldTileHeight / newRowHeight is actually pretty close!

    Hope it works :)