Masonry with fixed width and height?

iKamy picture iKamy · Dec 31, 2012 · Viewed 11.7k times · Source

I want something like this

enter image description here

the container box are fixed width and height

box sizes are different, like 1 * 1 or 2 * 1 or 3 * 3 and ... but not bigger that 4 in width and 3 in height

the numbers on boxes are the index of boxes when loading

I tried to write an algorithm width these conditions

first - put the item1 in the first position (0,0)

second - first box create 2 positions : (0,1) and (1,0)

third - the item2 should decide between 2 new positions and fit in the best position for less gap

and each item when placed produce 2 new position at the left top corner and right bottom corner of it

also I must check the area remained of container and boxes area for checking if container is full or not

and if the container is full creating new container and put the rest items on there

I found some examples that my algorithm failed but I should find the solution

maybe sorting these boxes by area and space is the easiest solution

but I dont like it becuz it beaks the design I mean bigger boxes at the top and and smaller boxes at the bottom :( it's not good plus I want load these boxes on infinte scroll then I dont know what's my next box size so I cant place them based on the area

after I gived up, I checked all the plugins about this kind of design

like isotope and masonry and vanilla masonry and gridster and ...

I tried to customize isotope

the JSfiddle link shows my attemp the link

<a href="#" id="good">Shuffle</a> |
<a href="#" id="bad">Original order (broken)</a>
<div id="container">
   <div class="item w1 h1">1</div>    
   <div class="item w2 h1">2</div>
   <div class="item w1 h2">3</div>
   <div class="item w1 h1">4</div>
   <div class="item w2 h2">5</div>
   <div class="item w2 h1">6</div>
   <div class="item w1 h1">7</div>
   <div class="item w1 h1">8</div>
   <div class="item w1 h2">9</div>
   <div class="item w2 h2">10</div>
   <div class="item w2 h1">11</div>
 </div>​

 #container {
   margin: 0 auto;
   border: 2px solid black;
   height: 430px;
   margin: 20px 0 0 0;}

 .item {
  float: right;
  background: #CCC;
  width: 100px;
  height: 100px;
  margin: 10px;}

 .item.w1 {
   width: 100px;}

 .item.w2 {
   width: 200px;}

 .item.h1 {
   height: 100px;}

 .item.h2 {
   height: 200px}

 .isotope,
   .isotope .isotope-item {
   -webkit-transition-duration: 0.8s;
    -moz-transition-duration: 0.8s;
      transition-duration: 0.8s;}

  .isotope {
    -webkit-transition-property: height, width;
     -moz-transition-property: height, width;
      transition-property: height, width;}


  .isotope .isotope-item {
    -webkit-transition-property: -webkit-transform, opacity;
    -moz-transition-property:    -moz-transform, opacity;
      transition-property:         transform, opacity;}​


$(function(){

$("#good").click(function() {
    $("#container").isotope('shuffle');
    return false;
});

$("#bad").click(function() {
    $("#container").isotope({'sortBy':'original-order'});
    return false;
});

$("#container").isotope({
  layoutMode: 'masonryHorizontal',
  masonryHorizontal: {
    rowHeight: 60
  }
});  });​

but it seems cant have fixed width and height at the same time

it's important for me becuz I want keep this equal margin between the boxes and not change

I also want detect browser height and change the height with just these 3 state and not the variable height

5 rows , 4 rows and 3 rows

my questions :

first - I will be so glad to write this algorithm my self so please help me to find the best solution for this algorithm in detail ??

I've tried many ways in last 2 days

second - can we customize one of these plugins as I expected and how ??

Answer

Gigamegs picture Gigamegs · Dec 31, 2012

Most simple is to use a kd-tree to subdivide the tree into a vertical and horizontal euklidian 2d space. Then you can pack the rectangle into one of the created space and recursively subdivide the tree. There is a Jquery treemap plugin example available online. The jquery plugin masonry can do the same but it's more like a 1d bin-packing solver. 2d bin-packing is much more complicated and can also mean to rotate the rectangle. Here is an example for packing lightmaps: http://www.blackpawn.com/texts/lightmaps/default.html. To achieve a better packing you can sort the sizes in some order, desc, asc, random etc. This also creates a different treemap.