The goal is to produce a fluid layout as show below.
So far I have a working function moveBox(lastBox, "east")
that keeps track of the row and column indexes.
function moveBox(box, where) {
switch (where) {
case "north":
lastTopOffset -= BOX_HEIGHT + BOX_MARGIN;
box.style.top = lastTopOffset + 'px';
box.style.left = lastLeftOffset + 'px';
rowIndex -= 1;
break;
// ...
}
My current code,
(function () {
var i, lastBox,
MAX_DIVS = 72,
BOX_HEIGHT = 50,
BOX_WIDTH = 100,
BOX_MARGIN = 5,
field = document.getElementById('fieldPerimeter'),
fieldHeight = field.offsetHeight,
maxRows = Math.floor(fieldHeight / (BOX_HEIGHT + BOX_MARGIN)),
rowIndex = 0,
colIndex = 0,
lastLeftOffset = 0,
lastTopOffset = 0;
function moveBox(box, where) {
switch (where) {
case "north":
lastTopOffset -= BOX_HEIGHT + BOX_MARGIN;
box.style.top = lastTopOffset + 'px';
box.style.left = lastLeftOffset + 'px';
rowIndex -= 1;
break;
case "east":
lastLeftOffset += BOX_WIDTH + BOX_MARGIN;
box.style.top = lastTopOffset + 'px';
box.style.left = lastLeftOffset + 'px';
colIndex += 1;
break;
case "south":
lastTopOffset += BOX_HEIGHT + BOX_MARGIN;
box.style.top = lastTopOffset + 'px';
box.style.left = lastLeftOffset + 'px';
rowIndex += 1;
break;
default:
break;
}
}
for (i = 0; i < MAX_DIVS; i += 1) {
lastBox = document.createElement('div');
lastBox.className = 'box';
lastBox.innerHTML = i;
field.appendChild(lastBox);
//delete me
if( (i + 1) % 2 === 0 || (i + 1)% 3 === 0){
moveBox(lastBox, "east");
} else {
moveBox(lastBox, "south");
}
//delete me
// if(rowIndex < maxRows && rowIndex > 0){
// if (colIndex % 4 === 0){
// moveBox(lastBox, "south");
// } else if (colIndex % 2 === 0){
// moveBox(lastBox, "north");
// } else {
// moveBox(lastBox, "east");
// }
// }
}
})();
appends divs to a container and then moves it. The code below shows part of my attempts for specifing when to move North or South. But I'm struggling with achiving the desired layout.
if (colIndex % 4 === 0) { moveBox(lastBox, "south"); }
else if (colIndex % 2 === 0) { moveBox(lastBox, "north"); }
else { moveBox(lastBox, "east"); }
Here is the working fiddle, http://jsfiddle.net/efortis/zuY74/
Note I hardcoded the offsetHeight
in order to work on the fiddle and also added a lastMove
variable at the top.
for (i = 0; i < MAX_DIVS; i += 1) {
lastBox = document.createElement('div');
lastBox.className = 'box';
lastBox.innerHTML = i;
field.appendChild(lastBox);
if (i === 0) {
rowIndex += 1;
} else {
if (colIndex % 4 === 0 && rowIndex < maxRows) {
moveBox(lastBox, "south");
lastMove = "south";
} else if (colIndex % 2 === 0 && rowIndex !== 1 && lastMove !== "south") {
moveBox(lastBox, "north");
lastMove = "north";
} else {
moveBox(lastBox, "east");
lastMove = "east";
}
}
}
The following works with grid positions rather than pixels, the idea being that you can convert a grid position to pixels without trouble.
My grid is pretty simple. The upper left is (0, 0)
. So your box 0 is at (0, 0)
, box 7 is at (1, 6)
, etc.
If you have maxrows
rows, then the first maxrows-1
items go in (0, 0)
, (0, 1)
, etc. And item maxrows
goes in (1, maxrows-1)
. The next maxrows-1
items go in (maxrows-1,2)
, (maxrows-2, 2)
, etc., and the item at 2*maxrows
goes in (0, 3)
.
You should be able to compute an item's position in the grid from its number. Assume integer math here.
// xblock treats each two columns as a single entity.
xblock = itemNo / (maxrows + 1);
xpos = 2 * xblock;
ypos = itemNo % (maxrows + 1);
if (ypos == maxrows)
{
// this is the last item, so we need to shift it.
xpos += 1;
ypos = maxrows - 1;
}
// Now, turn things upside down if xblock is odd
if ((xblock % 2) == 1 && ypos != maxrows)
{
ypos = maxrows - ypos - 1;
}
At this point you have the grid position where the box should go. It should be a simple matter now to turn that grid position into pixels by multiplying the xpos
by BOX_WIDTH
, and adding the offset. Do the same thing for ypos
and BOX_HEIGHT
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With