使用javascript分配随机选取的颜色

时间:2014-03-17 23:58:47

标签: javascript jquery css performance math

我的页面中有一个网格,我希望通过带有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中为渐变等映射的每个元素分配一个随机类,等等。

如果上述脚本可以在性能方面进行优化,我会提出任何建议!

其他信息:

  • 我正在使用jQuery
  • 网格由每行20个元素组成,共10行
  • 颜色应为4,但如果可以提供帮助,可以将其增加到5-7添加一些中性灰色调

以下是试用 http://codepen.io/Gruber/pen/lDxBw/

的笔

奖金功能请求:如上所述,我希望避免重复的相邻颜色。是否有可能避免这种情况&#34;上面和下面&#34;?我觉得如果不是不可能完全避免这种情况很难,但如果有人能找到解决方案那就太棒了! 像这样的东西,其中&#34; nope&#34;标记的元素是被阻止的,而&#34; yep&#34;允许对角线标记:

enter image description here

3 个答案:

答案 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)

randomColours.png

我想介绍的第一件事是过滤索引功能。

给定一个数组:

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中,还有几位用于演示代码的工作。

randomColours.png