2

如何创建一个确定性的Javascript HTML 颜色选择器,它给出需要多少颜色的参数返回一组 HTML 十六进制颜色代码,即:

    function createColours(numColours) {
        return [/* colours array of size numColours */]     
    }

颜色本身可以随机选择/生成,但该方法必须保证在调用之间选择的颜色始终相同,并且始终以相同的顺序排列。

例如,如果函数决定的颜色系列以以下 8 开头:

    "#47092E", "#CC2A43", "#00C66B", "#BC1300", "#667E00", "#795800", "#FFD245", "#6EFFAD", etc, etc

该函数将在客户端上的单独方法调用中以以下一致的响应运行

    ["#47092E", "#CC2A43"] == createColours(2);
    ["#47092E", "#CC2A43", "#00C66B", "#BC1300", "#667E00"] == createColours(5);
    ["#47092E"] == createColours(1);        
    ["#47092E", "#CC2A43", "#00C66B", "#BC1300", "#667E00", "#795800", "#FFD245", "#6EFFAD", #and 49 others#] == createColours(57);     

注意:颜色没有预先定义为变量;可能会要求该方法提供 345 种颜色,所有这些都需要通过任何合适的方式生成。

要解决的问题是 -首先也是最重要的 - 你将如何在方法中创建一种能力来生成 n 个 HEX 颜色值,每次都一致地相同,同时保留序列

4

6 回答 6

3

您需要使用具有固定起始种子的伪随机数生成器 (PRNG)。javascript 中的 Math.random 方法是 PRNG,但您不能像在其他语言中那样设置种子。

PRNG 的创建相当简单——互联网上有很多代码。给定一个固定的起始种子,它总是会生成相同的随机数序列,这就是您所要求的。

这些颜色看起来是否令人愉悦,完全是另一个问题......

一种具有播种功能的 javascript 实现:
http ://www.erikoest.dk/rng2.htm

您还可以在此处找到 C 实现(易于转换为 javascript)和构建您自己的 Lehmer 类型 PRNG 的其他详细信息:
http ://www.google.com/search?q=Lehmer%20random%20number%20generator

另一个有代码的(Mersenne twister): http:
//www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/JAVASCRIPT/java-script.html

这个问题涵盖了 javascript 中几种类型的 PRNG:
Seedable JavaScript random number generator

如果你在函数的开头给 PRNG 相同的起始种子,它总是会在每次连续调用时返回相同的数字序列。

将该数字转换为颜色,一切就绪。

-亚当

于 2009-02-04T18:34:43.543 回答
1

每对十六进制颜色代表一个 RGB 值。给定#AABBCC,可以推断出AA代表红色,BB代表绿色,CC代表蓝色。要获得 Red 的“值”,您首先需要将 A 从十六进制格式转换为十进制格式。

A 代表十进制的 10。当您将十六进制颜色的值对相乘时,您将获得 RBG 的每个值。因此,当您将前面所述的十六进制颜色转换为 RGB 时,您将得到 Red = A A、Green = B B 和 Blue = C*C 或 Red = 10*10 = 100、Green = 11*11 = 121 和 Blue = 12*12 = 144。

所以#AABBCC 是 (100,121,144) 的 RGB。我认为这应该是足够的信息来扭转这个过程......因为你不需要每种颜色长度超过 2 个十六进制字符的十六进制值,你不需要一个花哨的算法来将十进制转换为十六进制然后回来。RGB 仅从 0 到 255,因此您可以使用内置函数在基数之间进行转换,也可以通过页面上的资源制作表格:

十六进制的维基百科页面

于 2009-02-04T18:32:09.727 回答
1

使用上面提供的答案以及此处的 RNG 代码,我最终得到了(假设使用Prototype库进行类创建):

    var ColourPicker = Class.create({
        initialize: function() {
            this.hash = '#';
            this.rngRed = new RNG(5872323); // using same seed always guarantees number order response same
            this.rngGreen = new RNG(332233);
            this.rngBlue = new RNG(3442178);
        },
        numberToHex: function(number, padding) {
            var hex = number.toString(16);
            return hex;
        },
        createColours: function(numColours) {
            var colours = [];
            for (var i = numColours - colours.length; i-- > 0;) {
                var r = this.rngRed.nextRange(5,240);
                var g = this.rngGreen.nextRange(10,250);
                var b = this.rngBlue.nextRange(0,230);
                colours.push(this.hash + this.numberToHex(r) + this.numberToHex(g) + this.numberToHex(b));
            }
            return colours;
        }
    });

    var colourPicker = new ColourPicker();
    var colours = colourPicker.createColours(10);

    for (var i = 0 ; i < colours.length ; i++) {
        alert(colours[i]);
    }
于 2009-02-05T18:14:46.967 回答
0

我就是这样做的。

(function(){
var colours = [];
var x = "0123456789ABCDEF".split('');
var addColour = function() {
  var s='#';
  for(var i=6; i-->0;)
    s+=x[Math.round(Math.random()*15)];
  colours.push(s);
};
createColours = function(numColours) {
  for(var i=numColours-colours.length; i-->0;) addColour();
  return colours.slice(0,numColours);
}
})();
于 2009-02-04T18:24:03.470 回答
-2

也许是这样:

function createColours(numColours){
   var all  = ["#47092E", "#CC2A43", "#00C66B", .... ];
   var selected = [];
   for(var i=0;i<numColours;i++){
     selected.push(all[i]);
   }
   return selected;
}
于 2009-02-04T18:11:01.407 回答
-2

见这篇文章。它描述了 javascript 中的所有函数实际上是如何成为对象的。

所以这里有一个快速原型:

function createColours(num) {
  if ( typeof createColors.colors == 'undefined' ) {
    // We've not yet created any colors...
    createColors.colors = new array();
   }
  if ( createColors.colors.length >= num ) {
     // Create new colors and add them to the array here...

  }
  // Otherwise, return the array...
  return createColors.colors;
}
于 2009-02-04T18:18:13.093 回答