0

Fiddle

This is what I currently have. It's working, but I'd like to edit the random function so that the divs (this is just a mockup, there will be many, many more!) would be "evenly distributed" according to the browser's width, if that makes any sense. In a way that no horizontal scroll bar would ever be necessary!

I think this is a good example. Click the Designer's name (top left corner) and you'll see what I mean. Notice how those folders always use the whole window no matter how small or big it is? I want to mimic that behavior... I just don't know to go about it... edit the current script? a totally different approach?

Any input would be highly appreciated. Thanks.

html

<div id="box1" class="boxes">
<div id="text1">&nbsp;&nbsp;Lorem Ipsum Dolor Sit Amet&nbsp;&nbsp;</div>
</div>

<div id="box2" class="boxes">
<div id="text2">&nbsp;&nbsp;Lorem Ipsum Dolor Sit Amet&nbsp;&nbsp;</div>
</div>

<div id="box3" class="boxes">
<div id="text3">&nbsp;&nbsp;Lorem Ipsum Dolor Sit Amet&nbsp;&nbsp;</div>
</div>

<div id="box4" class="boxes">
<div id="text4">&nbsp;&nbsp;Lorem Ipsum Dolor Sit Amet&nbsp;&nbsp;</div>
</div>

css

.boxes {
    position: absolute;
}

#text1 {
    color: white;
    font-family: "Times", Times New Roman, serif;
    font-size: 16px;
    font-weight: bold;
    line-height: 24px;
    background-color: black;
}

    #text2 {
    color: white;
    font-family: "Times", Times New Roman, serif;
    font-size: 16px;
    font-weight: bold;
    line-height: 24px;
    background-color: blue;
}

#text3 {
    color: white;
    font-family: "Times", Times New Roman, serif;
    font-size: 16px;
    font-weight: bold;
    line-height: 24px;
    background-color: green;
}

#text4 {
    color: white;
    font-family: "Times", Times New Roman, serif;
    font-size: 16px;
    font-weight: bold;
    line-height: 24px;
    background-color: red;
}

javascript

var boxDims = new Array();

function setRandomPos(elements,x,dx){
  elements.each(function(){
    var conflict = true;
    while (conflict) {
        fixLeft=(Math.floor(Math.random()*x)*10) + dx;
        fixTop = (Math.floor(Math.random()*40)*10) + 180;
        $(this).offset({
            left: fixLeft,
            top: fixTop
        });
        var box = {
            top: parseInt(window.getComputedStyle($(this)[0]).top),
            left: parseInt(window.getComputedStyle($(this)[0]).left),
            width: parseInt(window.getComputedStyle($(this)[0]).width),
            height: parseInt(window.getComputedStyle($(this)[0]).height)
        }
        conflict = false;
        for (var i=0;i<boxDims.length;i++) {
            if (overlap(box,boxDims[i])) {
                conflict = true;
                break;
            } else {
                conflict = false;
            }                   
        }
    }
    boxDims.push(box)

  });
}

function overlap(box1,box2) {
  var x1 = box1.left
  var y1 = box2.top;
  var h1 = box1.height;
  var w1 = box1.width;
  var b1 = y1 + h1;
  var r1 = x1 + w1;
  var x2 = box1.left;
  var y2 = box1.top;
  var h2 = box1.height;
  var w2 = box1.width;
  var b2 = y2 + h2;
  var r2 = x2 + w2;

  var buf = 24;

  if (b1 + buf < y2 || y1 > b2 + buf || r1 + buf < x2 || x1 > r2 + buf) return false;
  return true;
}

setRandomPos($(".boxes"),40,40);
15
  • 1
    That site is using media queries to obtain that effect. Perhaps you could read up on those? The bootstrap library provides a lot of that functionality out of the box. I don't understand what randomization has to do with your question. Commented Jan 2, 2015 at 13:29
  • Is there any specific reason you want to do this with Javascript when you can do this with CSS media queries. And indeed what @JLRishe says: there are a lot of frameworks that will handle the work for you. I like to use PureCSS Commented Jan 2, 2015 at 13:36
  • They don't always use the whole window. If you keep clicking on Random, sometimes you'll see pretty large gaps. That's the nature of randomness. Commented Jan 2, 2015 at 13:48
  • @JLRishe I think it has to do with randomization because right now the script has no correlation with the window's width... and they need to be linked, right? It needs to know that the items need to be placed across at least, let's say, 80% of the window's width. That's what i want to do... Commented Jan 2, 2015 at 14:14
  • @Mikey No reason, I just think the issue lies with the function that sets the randomization... Commented Jan 2, 2015 at 14:16

1 Answer 1

1

I thought I'd share the tweaks and further solution I came up with. Making sure the parent container gets extended when there's not enough room inside the current window so no infinite loops will occur.

http://codepen.io/Shikkediel/pen/dPOVJp?editors=011

Made slightly less random by iterating over the screen's quadrants by a specified number first.

$(window).on('load', function() {

var spread, crest, boxes = [];

var margin = 40;
var itemwidth = 50;
var itemheight = 50;
var pad = 25;
var initial = 8;

setArea($(".boxes"));
placeRandom($(".boxes"));

function setArea(items) {

var range = 0, pitch = 0, total = 0;

items.each(function() {
range = $(this).width()+2*pad;
pitch = $(this).height()+2*pad;
total = total+range*pitch;
});

spread = $(window).width();
var term = $(window).height();
var edge = total/spread;

if (term < 4*edge) crest = 4*edge;
else crest = term;

$('#boxcontainer').css({'width': spread, 'height': crest});
spread = $(window).width();
$('#boxcontainer').width(spread);
}

function placeRandom(elements) {

var iter = 0;
var horizontal = spread/2;
var vertical = crest/2;

elements.each(function() {

var object = $(this), box;
iter++;
setPosition();

function setPosition() {

if (iter <= initial) {

var quadrant = iter%4;
if (quadrant == 0) quadrant = 4;
var spaceX = Math.round(Math.random()*(horizontal-itemwidth-margin));
var spaceY = Math.round(Math.random()*(vertical-itemheight-margin));
var bufferX, bufferY;

if (quadrant == 1) {
bufferX = margin;
bufferY = margin;
}
if (quadrant == 2) {
bufferX = horizontal;
bufferY = margin;
}
if (quadrant == 3) {
bufferX = horizontal;
bufferY = vertical;
}
if (quadrant == 4) {
bufferX = margin;
bufferY = vertical;
}
fixleft = spaceX+bufferX;
fixtop = spaceY+bufferY;
object.css({top: fixtop, left: fixleft});
}
else {
fixleft = Math.round(Math.random()*($(window).width()-itemwidth-2*margin))+margin;
fixtop = Math.round(Math.random()*($(window).height()-itemheight-2*margin))+margin;
object.css({top: fixtop, left: fixleft});
}

box = {
top: fixtop,
left: fixleft,
width: object.width(),
height: object.height()
}

if (iter == 1) boxes.push(box);
else {
for (var i=0; i < boxes.length; i++) {
if (encroachOn(box, boxes[i])) setPosition();
}
}
}
boxes.push(box);
object.show();
});
}

function encroachOn(box1, box2) {

var x1 = box1.left;
var y1 = box1.top;
var h1 = box1.height;
var w1 = box1.width;
var b1 = y1+h1;
var r1 = x1+w1;
var x2 = box2.left;
var y2 = box2.top;
var h2 = box2.height;
var w2 = box2.width;
var b2 = y2+h2;
var r2 = x2+w2;

return (x1 < r2+pad && r1+pad > x2 && y1 < b2+pad && b1+pad > y2);
}
});

An additional function for resizing is to be added as well.

Edit - a nice solution for the latter found here on Stackoverflow :

https://stackoverflow.com/a/5490021/3168107

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.