Search code examples
layoutgeometrygrid

Algorithm to compute a grid-layout given container size and items fixed aspect ratio


I'm looking for an algorithm to compute a grid layout. I will write it in javascript in the end but I'm looking for an agnostic-language answer.

I have a container (with a fixed dimension) and a variable number of elements.

All the elements have the same fixed aspect-ratio, and all the elements will have the same width/height, but it will change in proportion of the number of elements to fit the container.

As a plus, I would like to know a margin between each elements to space them equally.

Ideally, I imagine a function with this signature:

function computeLayout(containerWidth, containerHeight, numElements) {
   // ...
   return { itemWidth, itemHeight, margin }
}

Solution

  • Let element width/height ratio is C. We need to put n rectangle elements on the rectangular container with given Width and Height.

    Let unknown element height is h, width w = C * h

    Every row of grid contains nr elements

    nr =  Floor(Width / (C * h))   // rounding down
    

    Every column contains nc rows

    nc = Floor(Height / h)
    

    So we can write inequality to provide place for n elements:

    n <= nc * nr
    n <=  Floor(Width / (C * h)) * Floor(Height / h)
    

    and solve it for h (so find maximum possible h value)

    Initial approximate value of h:

    h0 = Ceil(Sqrt(Width * Height / (n * C)))   //rounding up
    

    Then we can decrement h value until inequality becomes true like this:

    while (n > Floor(Width / (C * h)) * Floor(Height / h))
       h--; 
    

    Margins introduce additional variability. We can predefine margin value and use it in nc, nr formulas (using h + margin, C * h + margin)

    If you want to get minimal margin (perhaps zero) - just calculate it from difference of Height and nr*h