我的页面中有一个网格,我希望通过带有200个元素的javascript填充。填充.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
)。
也许这可以帮助进行随机化过程Fisher–Yates Shuffle,但我不知道如何实施上述非两次相邻规则(如果可以应用的话)。
实现这一结果的最佳方法是什么?我还想知道是否可以对每个.block
应用渐变而不是扁平的十六进制颜色;我想更好的方法是为CSS中为渐变等映射的每个元素分配一个随机类,等等。
如果上述脚本可以在性能方面进行优化,我会提出任何建议!
其他信息:
以下是试用 http://codepen.io/Gruber/pen/lDxBw/
的笔奖金功能请求:如上所述,我希望避免重复的相邻颜色。是否有可能避免这种情况&#34;上面和下面&#34;?我觉得如果不是不可能完全避免这种情况很难,但如果有人能找到解决方案那就太棒了! 像这样的东西,其中&#34; nope&#34;标记的元素是被阻止的,而&#34; yep&#34;允许对角线标记:
答案 0 :(得分:3)
$(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);
});
答案 1 :(得分:3)
首先,我会使用颜色类:
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的代码开始,但添加了一个行元素,因此我们知道当前块之上的内容。
答案 2 :(得分:1)
我想介绍的第一件事是过滤索引功能。
给定一个数组:
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);
}
}
}
我已将其全部放在this jsbin中,还有几位用于演示代码的工作。