Distribuir igualmente e randomizar
by Luiz Silva
HTML
<ul>
<li>C</li>
<li>C++</li>
<li>Java</li>
<li>PHP</li>
<li>JavaScript</li>
<li>Lisp</li>
<li>Scheme</li>
<li>Haskell</li>
<li>Lua</li>
<li>Python</li>
<li>Ruby</li>
<li>Delphi</li>
<li>Cobol</li>
</ul>
CSS
body {
margin: 0;
padding: 0;
}
ul {
width: 500px;
height: 350px;
border: 1px solid red;
margin: 0;
padding: 0;
text-align: center;
}
li {
list-style: none;
margin: 0;
padding: 0;
display: inline-block;
font-size: 2em;
}
JavaScript
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function rand(n) {
return getRandomInt(-n, n);
}
//calcula tamanhos dos itens para distribuição
var itens = [];
var larguraTotal = 0;
$('li').each(function(i) {
var $this = $(this);
larguraTotal += $this.width();
itens.push({
item: $this,
width: $this.width(),
height: $this.height()
});
});
//define a quantidade de linhas
var linhas = Math.ceil(Math.sqrt(itens.length));
var larguraMedia = larguraTotal / linhas;
//console.log(linhas, larguraMedia, larguraTotal);
//faz a distribuição dos elementos nas linhas de uma grid imaginária
var grid = [ [] ];
grid[0].largura = 0;
for (var i = 0, larguraConsumida = 0, linha = 0, coluna = 0, proximaQuebra = larguraMedia; i < itens.length; i++) {
var item = itens[i];
//quebra a linha, caso mais da metade do elemento ultrapasse a média
if (larguraConsumida + item.width / 2 > proximaQuebra) {
linha++;
grid[linha] = [];
grid[linha].largura = 0;
coluna = 0;
larguraLinha = 0;
proximaQuebra = larguraMedia * (linha + 1);
} else {
coluna++;
}
//armazena a largura
grid[linha].largura += item.width;
larguraConsumida += item.width;
grid[linha].push(item);
//console.log(item);
}
//coloca os elementos na posição final (uma célula do container)
var container = $('ul');
//a largura da célula (local onde o item deve ser inserido)
var larguraCelula = container.height() / grid.length;
for (var i = 0; i < grid.length; i++) {
var linha = grid[i];
//altura da célula (local onde o item deve ser inserido)
var alturaCelula = container.width() / linha.length;
//calcula o espaço horizontal que tem para randomizar, isto é, o espaço em branco até onde não enconsta no próximo elemento
//deve dividir por 2 pela possibilidade do outro elemento também poder se aproximar, mas multiplicando por 0.4...