给定这个函数,我想用随机颜色生成器替换颜色。

document.overlay = GPolyline.fromEncoded({
    color: "#0000FF",
    weight: 10,
    points: encoded_points,
    zoomFactor: 32,
    levels: encoded_levels,
    numLevels: 4
});

我该怎么做呢?


当前回答

递归:

var randomColor = (s='') => s.length === 6 ? '#' + s : randomColor(s + '0123456789ABCDEF'[Math.floor(Math.random() * 16)]);
randomColor();

其他回答

投票最多的回答表明,Martin Ankerl的方法比随机十六进制数字更好,尽管我还没有改进Ankerl的方法,但我已经成功地将其翻译成JavaScript。

我想我应该对这个已经非常大的Stack Overflow问题发布一个额外的答案,因为顶部的答案有另一个评论链接到一个带有Ankerl逻辑的JavaScript实现的Gist,而这个链接是坏的(404)。如果我有这样的声誉,我就会简单地注释我创建的jsbin链接。

// Adapted from
// http://jsfiddle.net/Mottie/xcqpF/1/light/
const rgb2hex = (rgb) => {
  return (rgb && rgb.length === 3) ? "#" +
    ("0" + parseInt(rgb[0],10).toString(16)).slice(-2) +
    ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
    ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) : '';
}

// The next two methods are converted from Ruby to JavaScript.
// It is sourced from http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/

// # HSV values in [0..1[
// # returns [r, g, b] values from 0 to 255
const hsv_to_rgb = (h, s, v) => {
  const h_i = Math.floor(h*6)
  const f = h*6 - h_i
  const p = v * (1 - s)
  const q = v * (1 - (f * s))
  const t = v * (1 - (1 - f) * s)
  let r, g, b
  switch(h_i) {
    case(0):
      [r, g, b] = [v, t, p]
      break
    case(1):
      [r, g, b] = [q, v, p]
      break
    case(2):
      [r, g, b] = [p, v, t]
      break
    case(3):
      [r, g, b] = [p, q, v]
      break
    case(4):
      [r, g, b] = [t, p, v]
      break
    case(5):
      [r, g, b] = [v, p, q]
      break
  }
  return [Math.floor(r * 256), Math.floor(g * 256), Math.floor(b * 256)]
}

// # Use the golden ratio
const golden_ratio_conjugate = 0.618033988749895
let h = Math.random() // # Use a random start value
const gen_hex = (numberOfColors) => {
  const colorArray = []
  while (numberOfColors > 0) {
    h += golden_ratio_conjugate
    h %= 1
    colorArray.push(rgb2hex(hsv_to_rgb(h, 0.99, 0.99)))
    numberOfColors -= 1
  }
  console.log(colorArray)
  return colorArray
}

gen_hex(100)

https://jsbin.com/qeyevoj/edit?js,console

这个函数在两个方面超越了其他答案:

它试图生成尽可能不同的颜色 20种颜色中哪一种与欧几里得距离最远 其他的都在HSV锥内。

它允许你限制色调, 饱和度,或值范围,但它仍然试图选择颜色作为 在这个范围内尽可能的不同。

它不是超级高效,但对于合理的值(谁甚至可以轻松地区分100种颜色?)够快了。

请参阅 JSFiddle

  /**
   * Generates a random palette of HSV colors.  Attempts to pick colors
   * that are as distinct as possible within the desired HSV range.
   *
   * @param {number}    [options.numColors=10] - the number of colors to generate
   * @param {number[]}  [options.hRange=[0,1]] - the maximum range for generated hue
   * @param {number[]}  [options.sRange=[0,1]] - the maximum range for generated saturation
   * @param {number[]}  [options.vRange=[0,1]] - the maximum range for generated value
   * @param {number[][]}[options.exclude=[[0,0,0],[0,0,1]]] - colors to exclude
   *
   * @returns {number[][]} an array of HSV colors (each HSV color
   * is a [hue, saturation, value] array)
   */
  function randomHSVPalette(options) {
    function random(min, max) {
      return min + Math.random() * (max - min);
    }

    function HSVtoXYZ(hsv) {
      var h = hsv[0];
      var s = hsv[1];
      var v = hsv[2];
      var angle = h * Math.PI * 2;
      return [Math.sin(angle) * s * v,
              Math.cos(angle) * s * v,
              v];
    }

    function distSq(a, b) {
      var dx = a[0] - b[0];
      var dy = a[1] - b[1];
      var dz = a[2] - b[2];
      return dx * dx + dy * dy + dz * dz;
    }

    if (!options) {
      options = {};
    }

    var numColors = options.numColors || 10;
    var hRange = options.hRange || [0, 1];
    var sRange = options.sRange || [0, 1];
    var vRange = options.vRange || [0, 1];
    var exclude = options.exclude || [[0, 0, 0], [0, 0, 1]];

    var points = exclude.map(HSVtoXYZ);
    var result = [];

    while (result.length < numColors) {
      var bestHSV;
      var bestXYZ;
      var bestDist = 0;
      for (var i = 0; i < 20; i++) {
        var hsv = [random(hRange[0], hRange[1]), random(sRange[0], sRange[1]), random(vRange[0], vRange[1])];
        var xyz = HSVtoXYZ(hsv);
        var minDist = 10;
        points.forEach(function(point) {
          minDist = Math.min(minDist, distSq(xyz, point));
        });
        if (minDist > bestDist) {
          bestHSV = hsv;
          bestXYZ = xyz;
          bestDist = minDist;
        }
      }
      points.push(bestXYZ);
      result.push(bestHSV);
    }

    return result;
  }

  function HSVtoRGB(hsv) {
    var h = hsv[0];
    var s = hsv[1];
    var v = hsv[2];

    var i = ~~(h * 6);
    var f = h * 6 - i;
    var p = v * (1 - s);
    var q = v * (1 - f * s);
    var t = v * (1 - (1 - f) * s);
    v = ~~(255 * v);
    p = ~~(255 * p);
    q = ~~(255 * q);
    t = ~~(255 * t);
    switch (i % 6) {
      case 0: return [v, t, p];
      case 1: return [q, v, p];
      case 2: return [p, v, t];
      case 3: return [p, q, v];
      case 4: return [t, p, v];
      case 5: return [v, p, q];
    }
  }

  function RGBtoCSS(rgb) {
    var r = rgb[0];
    var g = rgb[1];
    var b = rgb[2];
    var rgb = (r << 16) + (g << 8) + b;
    return '#' + ('000000' + rgb.toString(16)).slice(-6);
  }

审查

这里的许多答案都是基于Math.random(). tostring(16)。他们有时会用一个随机数乘以一些数字,并假设转换到十六进制字符串总是会产生一个浮点十六进制表示,在点后面至少有6个数字(并且他们使用这些数字作为颜色)。

这是一个错误的假设

因为有很多数字实际上给出的数字小于6位(在点后面)。如果Math.random()选择这样一个数字,那么结果的十六进制颜色将无效(除非有人处理这种情况)。下面是一个生成器的例子(我是基于这个转换器编写的)。

function calc() { let n = hex2dec(hexInput.value) console.log(`${n} -> ${n.toString(16)}` ); } // Source: https://stackoverflow.com/questions/5055723/converting-hexadecimal-to-float-in-javascript/5055821#5055821 function hex2dec(hex) { hex = hex.split(/\./); var len = hex[1].length; hex[1] = parseInt(hex[1], 16); hex[1] *= Math.pow(16, -len); return parseInt(hex[0], 16) + hex[1]; } Put some 5-digit (or less) hexdecimal number in range 0-1<br> <input id="hexInput" value="0.2D4EE"> <button onclick="calc()">Calc</button>

我已经在没有这个假设的情况下对你的问题给出了两个答案:RGB和十六进制,所以在这个答案中,我不会提出另一个解决方案。

试试这个包- https://www.npmjs.com/package/gen-random-colors。

它还提供了从0到5(0是最暗的)配置颜色集的能力。

如果你像我一样是个新手,对十六进制之类的东西一无所知,这可能更直观。

function r() {
  return Math.floor(Math.random() * 256);
}

const color = "rgb(" + r() + "," + r() + "," + r() + ")";

你只需要以一个字符串结束,比如“rgb(255, 123, 220)”。