我的页面中有一个网格,我想通过javascript填充200个元素。填充.grid元素的实际代码如下:
$(function () {
var $gd = $(".grid");
var blocks="";
for(i=0; i < 200; i++){
blocks += '<div class="block"></div>';
}
$gd.append(blocks);
});我现在要做的是给每个元素分配一个从列表中随机选择的颜色。让我们说红,蓝,黄,绿(出乎意料的是吧?)我希望这些值是最随机的,同时也避免同样的颜色再次被选中两次(为了清楚起见,这是可以的,比如red-blue-red-green-blue等等,而不是 red-red-green-yellow)。
也许这可以在随机化过程中有所帮助,费舍-耶茨洗牌,但是我不知道如何实现上面提到的非两次相邻规则(如果可以的话)。
实现这一结果的最佳途径是什么?我也在想,我是否可以为每个.block应用一个梯度,而不是一个平坦的十六进制颜色;我想更好的方法是为每个映射在CSS中的渐变元素分配一个随机类,等等。
如果上面的脚本可以从性能上优化,我会接受任何建议!
更多信息:
这里是一支用 http://codepen.io/Gruber/pen/lDxBw/做实验的钢笔
额外功能要求:如上所述,我想避免重复相邻的颜色。是否有可能避免这也是“上面和下面”?我想这是很难,如果不是不可能完全避免这一点,但好吧,如果任何人都能找到解决办法,这将是太棒了!在这样的情况下,"nope“标记元素被阻止,而”是“对角线标记被允许:

发布于 2014-03-18 17:19:25

我要介绍的第一件事是一个过滤的索引函数。
给定数组:
var options = ['red', 'green', 'blue', 'purple', 'yellow']; // never less than 3!和一个过滤器:
function filterFunc(val) {
var taken = { 'red': 1, 'blue': 1 };
return taken[val] ? 0 : 1;
} 我们可以通过筛选器从允许的值(==1)中获取第n项(这不是一种快速的方法,但除非有性能约束.):
// filteredIndex returns nth (0-index) element satisfying filterFunc
// returns undefined if insufficient options
function filteredIndex(options, filterFunc, n) {
var i=-1, j=0;
for(;j<options.length && i<n; ++j) {
i += filterFunc(options[j]);
if(i==n)
break;
}
return options[j];
}所以现在我们可以在过滤列表中获取一个索引2的值。如果我们没有足够的选择来这样做,我们应该得到undefined。
如果你是从左上角填充颜色,你只能使用3种颜色,因为你只受上面和左边的细胞的限制。
要随机挑选,我们需要设置过滤器。因此,我们可以通过一个已知值列表来实现这一点:
function genFilterFunc(takenValues) {
var takenLookup = {};
for(var i=0; i < takenValues.length; ++i) {
takenLookup[takenValues[i]] = 1;
}
var filterFunc = function(val) {
return takenLookup[val] ? 0 : 1;
};
return filterFunc;
}那么,我们可以为grid[rows][cols]中的一个单元格选择一个随机颜色。
function randomColourNotUpOrLeft(grid, row, col, options, ignoreColour) {
var takenlist = [];
if(row > 0 && grid[row-1][col] != ignoreColour) {
takenlist.push(grid[row-1][col]);
}
if(col > 0 && grid[row][col-1] != ignoreColour) {
takenlist.push(grid[row][col-1]);
}
var filt = genFilterFunc(takenlist);
var randomIndex = Math.floor(Math.random()*(options.length-takenlist.length));
var randomColour = filteredIndex(options, filt, randomIndex);
return randomColour;
}请注意,所使用的随机指数取决于筛选出了多少种颜色;如果剩下4种颜色,我们可以有0-3,但如果只剩下2种,则必须是0-1,等等。当相邻的单元格是相同的颜色和/或我们接近边界时,对于选择哪种颜色的限制较小。最后填写一个网格:
function fillGridSpeckled(grid, options, nullColour) {
for(var row=0; row<grid.length; ++row) {
for(var col=0; col<grid[row].length; ++col) {
grid[row][col] = randomColourNotUpOrLeft(grid,row,col,options,nullColour);
}
}
}我已经将其全部放在这个jsbin中,以及演示代码工作的几个部分。

发布于 2014-03-18 00:09:17
$(function () {
var colors = ["red","blue","green","yellow"];
var $gd = $(".grid");
var previousColor;
var blocks="";
for(i=0; i < 200; i++){
var color = "";
while(color === previousColor) {
color= colors [Math.floor(Math.random()*colors .length)];
}
blocks += '<div class="block" style="color:' + color + '"></div>';
previousColor = color;
}
$gd.append(blocks);
});发布于 2014-03-18 14:54:09
首先,我会用类来表示颜色:
CSS:
.red { background-color: red; }
.blue { background-color: blue; }
.green { background-color: green; }
.yellow { background-color: yellow; }下面是javascript:
$(document).ready(function() {
var colors = ["red","blue","green","yellow"];
var $gd = $(".grid");
var previousColor;
var previousRow;
var rowSize = 10;
while(rowSize--) previousRow.push("none");
var blocks = "";
for(i=0; i < 200; i++){
var color = colors [Math.floor(Math.random()*colors .length)];
while((color == previousColor) || (color == previousRow[i%rowSize])) {
color = colors [Math.floor(Math.random()*colors .length)];
}
blocks += '<div class="block ' + color + '"></div>';
previousColor = color;
previousRow[i%rowSize] = color;
}
$gd.append(blocks);
});我从类似MikeB的代码开始,但添加了一个row元素,这样我们就知道当前块上的是什么了。
https://stackoverflow.com/questions/22467842
复制相似问题