Trying to figure out somekind of logic that will let me distribute elements in a sequenced order. What size and position should be randomly generated within a given range (for example, element must be within viewport and the size of the element should be within a defined range such as minimum 10% of viewport, maximum 60%).
I'm not sure what would be the best way to approach something like this, any ideas?
I've attached a sketch below of what it could look like. The layout would be different at each load.
Markup
<div class="container">
<div class="post">Post 1</div>
<div class="post">Post 2</div>
<div class="post">Post 3</div>
<div class="post">Post 4</div>
<div class="post">Post 5</div>
<div class="post">Post 6</div>
<div class="post">Post 7</div>
<div class="post">Post 8</div>
<div class="post">Post 9</div>
<div class="post">Post 10</div>
<div class="post">Post 11</div>
<div class="post">Post 12</div>
<div class="post">Post 13</div>
<div class="post">Post 14</div>
<div class="post">Post 15</div>
</div>
Thanks, this was fun to code. I set some defaults in CSS and then did the logic in JS. Note that the buffer() function is nonlinear; we want most of the buffers to be close to zero and very few of them to be on the larger side, so we use powers of e (2.7⁰/12 = 0.08em to 2.7⁶/12 = 33.62em) for the scale and then multiply them out to get a bigger range of numbers (rather than powers of two divided by 12).
I assume the elements are already chronologically ordered. If not, that shouldn't be hard to do, just sort posts[] and insert them in order using appendChild()
on the container.
var defaultMax = Math.exp(6) / 12; // e⁶ / 12 = 33.5em
// random buffer to give for spacing.
// growth is inverse exponential, so larger is less likely
function buffer(min=0.1, max=defaultMax, mult=1) {
return Math.min(max, Math.max(min,
min / 2 + Math.exp(Math.random() * 6) * Math.random() * mult / 12
))+"em";
}
function randomize() {
var posts = document.getElementsByClassName("posts");
for (var p = 0; p < posts.length; p++) {
// random buffered margins, ordered: top right bottom left.
// top is at least 0.1em, right and bottom are at least 0.25em.
// top and bottom are cut in half to limit lost vertical space.
posts[p].style.margin = buffer(0.1, defaultMax, 0.5) + " "
+ buffer(0.25) + " "
+ buffer(0.25, defaultMax, 0.5) + " "
+ buffer();
// random width and height (with sane minimum size: 8em x 5em)
posts[p].style.width = buffer(8);
posts[p].style.height = buffer(5);
}
}
.posts { float:left; background:#000; color:#fff;
padding:0.2em; text-align:center; }
.container { width:50em; max-width:100%; }
<body onload="randomize()">
<div class="container">
<div class="posts">Post 1</div>
<div class="posts">Post 2</div>
<div class="posts">Post 3</div>
<div class="posts">Post 4</div>
<div class="posts">Post 5</div>
<div class="posts">Post 6</div>
<div class="posts">Post 7</div>
<div class="posts">Post 8</div>
<div class="posts">Post 9</div>
<div class="posts">Post 10</div>
<div class="posts">Post 11</div>
<div class="posts">Post 12</div>
<div class="posts">Post 13</div>
<div class="posts">Post 14</div>
<div class="posts">Post 15</div>
</div>
</body>