Gerador aleatório de cores


440

Dada essa função, desejo substituir a cor por um gerador de cores aleatório.

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

Como eu posso fazer isso?


31
'#' + Math.floor (Math.random () * 16777215) .toString (16);
— SepehrM


2
@SepehrM quando retorna aleatórios 0.001seguida resultado é "#4189"(cor inválido - 4 dígitos)
— Kamil Kiełczewski

Esta é uma solução muito agradável, para mim muito útil github.com/davidmerfield/randomColor
— maikelm

5
'#'+Math.random().toString(16).substr(2,6) (fonte: CodeGolf )
— ashleedawg

Respostas:


1018

Use getRandomColor()no lugar de "#0000FF":

function getRandomColor() {
  var letters = '0123456789ABCDEF';
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}



function setRandomColor() {
  $("#colorpad").css("background-color", getRandomColor());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="colorpad" style="width:300px;height:300px;background-color:#000">

</div>
<button onclick="setRandomColor()">Random Color</button>


87
Observe que isso tem um viés em direção a cores bastante escuras e insaturadas, devido à maneira como o RGB envolve o espaço de cores. Martin Ankerl tem um bom artigo sobre a geração de cores de outros espaços (como HSV): martin.ankerl.com/2009/12/09/…
— Thomas Ahle

13
As chances de atingir 0 ou 15 ao usar Math.round(Math.random()*15)são apenas 1:30, enquanto as chances dos outros números são 1:15.
— user123444555621

3
Você pode remover a chamada .split (''). A string já possui um indexador de matriz.
— ujeenator

3
Você também pode usar uma função Generator como tal
— tsuz

4
Este código é coxo. Aqui está um oneliner: Math.floor (Math.random () * 16777215) .toString (16)
— DDD

269

Duvido que algo seja mais rápido ou mais curto que este:

"#"+((1<<24)*Math.random()|0).toString(16)

Desafio!


18
Você esqueceu de preencher com zeros.
— User123444555621

144
'#'+(Math.random()*0xFFFFFF<<0).toString(16);
— Mohsen

15
@Mohsen, FYI a cada momento e, em seguida, seu código produz inválido número de 5 dígitos
— rochal

6
O resultado não é preenchido com 6 dígitos
— Taha Jahangir

33
('00000'+(Math.random()*(1<<24)|0).toString(16)).slice(-6)sempre retornará um comprimento de 6. embora esse método ainda (raramente) retorne pequenos números que dão resultados como 000cf4ou 0000a7que são um pouco hacky, eu acho. nesses casos, o componente vermelho não contribui para a cor aleatória.
— bryc

162

Aqui está outra opinião sobre esse problema.

Meu objetivo era criar cores vibrantes e distintas. Para garantir que as cores sejam distintas, evito usar um gerador aleatório e seleciono cores "espaçadas igualmente" no arco-íris.

Isso é perfeito para criar marcadores pop-out no Google Maps que tenham uma "exclusividade" ideal (ou seja, dois marcadores não terão cores semelhantes).

function rainbow(numOfSteps, step) {
    // This function generates vibrant, "evenly spaced" colours (i.e. no clustering). This is ideal for creating easily distinguishable vibrant markers in Google Maps and other apps.
    // Adam Cole, 2011-Sept-14
    // HSV to RBG adapted from: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
    var r, g, b;
    var h = step / numOfSteps;
    var i = ~~(h * 6);
    var f = h * 6 - i;
    var q = 1 - f;
    switch(i % 6){
        case 0: r = 1; g = f; b = 0; break;
        case 1: r = q; g = 1; b = 0; break;
        case 2: r = 0; g = 1; b = f; break;
        case 3: r = 0; g = q; b = 1; break;
        case 4: r = f; g = 0; b = 1; break;
        case 5: r = 1; g = 0; b = q; break;
    }
    var c = "#" + ("00" + (~ ~(r * 255)).toString(16)).slice(-2) + ("00" + (~ ~(g * 255)).toString(16)).slice(-2) + ("00" + (~ ~(b * 255)).toString(16)).slice(-2);
    return (c);
}

Se você deseja ver como isso fica em ação, consulte http://blog.adamcole.ca/2011/11/simple-javascript-rainbow-color.html .


7
Eu estive procurando por algo assim! Coisas boas!
— Khôi 17/10/12

Eu fiz uma implementação simplificada da mesma idéia que a resposta à pergunta semelhante stackoverflow.com/a/14187677/421010
— Andrew

16
Então, qual será o valor do parâmetro?
— Ekramul Hoque

2
Eu também criei algo assim, mas é bastante aleatório e bastante distinto. O pseudo-código está aqui . Ele usa hsv em vez de rgb, porque o hsv tem um comportamento muito mais previsível. Se você gostaria de ver a implementação do Python, usei aqui e aqui . Você terá que procurar no código por "cor".
— Zondo

1
@RobertMolina: Desculpe, mudei minhas coisas para o Gitlab. O pseudo-código está agora aqui , com os projetos aqui e aqui .
— zondo 20/02/19

56

Quem pode vencê-lo?

'#'+Math.random().toString(16).substr(-6);

Garantido para trabalhar o tempo todo: http://jsbin.com/OjELIfo/2/edit

Com base no comentário @eterps, o código acima ainda pode gerar seqüências mais curtas se a representação hexadecimal da cor aleatória for muito curta ( 0.730224609375=> 0.baf)

Este código deve funcionar em todos os casos:

function makeRandomColor(){
  var c = '';
  while (c.length < 7) {
    c += (Math.random()).toString(16).substr(-6).substr(-1)
  }
  return '#'+c;
}

12
Quando Math.random () retorna 0,022092682472568126, esse código produz uma string '# 5a7dd' inválida. louco!
— rochal

Como este, pois #ffffff não aparece com muita frequência.
— Warface

Existem algumas ocorrências em que isso não funciona. Verifique a saída a seguir para Math.random () ... 0.730224609375, 0.43603515625, 0.957763671875, e a lista continua ...
— eterps 27/03

@eterps Esses NÃO são números aleatórios adequados ! Veja matéria IEEE 754 double em hexadecimal: 0.730224609375 = 0x3fe75e0000000000, 0.43603515625 = 0x3fdbe80000000000, 0.957763671875 = 0x3feea60000000000. Quase nenhuma mantissa está sendo usada! São apenas frações glorificadas. Uma saída adequada de '12 dígitos 'produziria resultados como:0.347876714234 = 0x3fd6439cb1ab32ac, 0.447556256665 = 0x3fdca4c2ff5fc450
— bryc 28/02/19

Desde 2015, acredito que muitos navegadores substituíram os PRNGs Math.random()de baixa qualidade usados ​​sob o capô (os quais, suponho, são responsáveis ​​pelos resultados da @ etertp) pelos melhores, então esses tipos de números aleatórios de baixa qualidade devem ser uma coisa do passado agora.
— bryc 28/02/19

29

Não há necessidade de um hash de letras hexadecimais. O JavaScript pode fazer isso sozinho:

function get_random_color() {
  function c() {
    var hex = Math.floor(Math.random()*256).toString(16);
    return ("0"+String(hex)).substr(-2); // pad with zero
  }
  return "#"+c()+c()+c();
}

29

Você também pode usar o HSL disponível em todos os bons navegadores ( http://caniuse.com/#feat=css3-colors )

function randomHsl() {
    return 'hsla(' + (Math.random() * 360) + ', 100%, 50%, 1)';
}

Isso fornecerá apenas cores brilhantes. Você pode brincar com brilho, saturação e alfa.

// es6
const randomHsl = () => `hsla(${Math.random() * 360}, 100%, 50%, 1)`

Obrigado! Consegui obter cores perfeitas para fundos com:'hsla(' + (Math.floor(Math.random()*360) + ', 100%, 70%, 1)'
— jj_ 28/10

1
Sem problemas, fiquei surpreso ao ver ninguém usando o poder do HSL :)
— kigiri

stackoverflow.com/a/23861752/1693593 , o hsla não é necessário, alpha = 1, basta usar o hsl

1
Você não pode gerar 16M kolor desta forma (por exemplo, você nunca vai ficar em tons de cinza branco-preto) - no entanto sim - se usarmos aleatória para cada componente, em seguida, temos todas corols HSL
— Kamil Kiełczewski

1
+1 Isto torna mais fácil de usar luminosidade e saturação para definir cores de fundo aleatório, assegurando que o texto é sempre legível
— Osvaldo Maria

27

Eu gosto deste: '#' + (Math.random().toString(16) + "000000").substring(2,8)


Ou'#' + Math.floor(Math.random()*16777215).toString(16);
— Mohammad Anini

@MohammadAnin que tem um 1 em 16 chances de produzir menos de 6 dígitos
— James

1
Isso pode gerar cores inválidas. Por exemplo '#' + (0.125).toString(16).substring(2, 8) === '#2'. É perigoso porque a probabilidade é baixa (1 em 4096, eu acho), portanto é provável que um bug seja submetido ao teste. Você deveria ('#' + Math.random().toString(16) + "000000").substring(2, 8)
— James

Correção: deve ser #'#' + (Math.random().toString(16) + "000000").substring(2,8)
— James

25

Geração aleatória de cores com controle de brilho:

function getRandColor(brightness){

    // Six levels of brightness from 0 to 5, 0 being the darkest
    var rgb = [Math.random() * 256, Math.random() * 256, Math.random() * 256];
    var mix = [brightness*51, brightness*51, brightness*51]; //51 => 255/5
    var mixedrgb = [rgb[0] + mix[0], rgb[1] + mix[1], rgb[2] + mix[2]].map(function(x){ return Math.round(x/2.0)})
    return "rgb(" + mixedrgb.join(",") + ")";
}

1
Muito legal, embora gere principalmente 'pastéis' em vez de cores mais vibrantes que eu esperava quando vi o brilho. Ainda vou para a minha sacola de truques!
— JayCrossler

Eu realmente como este, porque você pode personalizá-lo para estar em harmonia com sua paleta de cores website
— Emanuel Gianico

20
'#'+Math.random().toString(16).slice(-3) // three-numbers format aka #f3c
'#'+Math.random().toString(16).slice(-6) // six-number format aka #abc123

I como este para a sua legibilidade
— hitautodestruct

1
Se Math.random()retorno 0.125, em seguida resultado será #0.2(cor inválida) (você precisa adicionar algum estofamento em vez fatia)
— Kamil Kiełczewski

18

O artigo escrito por Paul Irish no Random Hex Color Code Generator em JavaScript é absolutamente incrível. Usar:

'#'+Math.floor(Math.random()*16777215).toString(16);

Aqui está o link da fonte:

http://www.paulirish.com/2009/random-hex-color-code-snippets/


5
isso vai voltar algures valores de cor não-formados, bem como "1fa4c" (necessidade de ser 3 ou 6 caracteres)
— jj_

1
@jj_ é? desculpe, eu não percebi isso. Obrigado por compartilhar
— way2vin

quando o retorno aleatório 0.00001seguida resultado é #a7(cor inválido)
— Kamil Kiełczewski

1
'#' + Math.floor(Math.random()*16777215).toString(16).padStart(6, '0')
— Haytam

17

Aqui está uma reviravolta na solução fornecida pela @Anatoliy.

Eu precisava gerar apenas cores claras (para planos de fundo), então usei o formato de três letras (#AAA):

function get_random_color() {
    var letters = 'ABCDE'.split('');
    var color = '#';
    for (var i=0; i<3; i++ ) {
        color += letters[Math.floor(Math.random() * letters.length)];
    }
    return color;
}

Eu acho que isso provavelmente produzirá cores mais semelhantes, embora leves. Para uma gama mais escassa de cores aleatórias, eu acho @ resposta de Anatoli é melhor para a maior parte
— larrytech

15

Se você é um noob como eu, sem noção sobre hexadecimais e coisas assim, isso pode ser mais intuitivo.

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

var color = 'rgb(' + r() + "," + r() + "," + r() + ')';

Você só precisa terminar com uma string como 'rgb(255, 123, 220)'


esta resposta tem de ser a de cima
— Gil Epshtain

Você precisaria usar 256 para obter 0.
— Lisa Cerilli

13

Isso pode ser facilmente encontrado usando a Pesquisa do Google:

function random_color(format)
{
    var rint = Math.round(0xffffff * Math.random());
    switch(format)
    {
        case 'hex':
            return ('#0' + rint.toString(16)).replace(/^#0([0-9a-f]{6})$/i, '#$1');
            break;

        case 'rgb':
            return 'rgb(' + (rint >> 16) + ',' + (rint >> 8 & 255) + ',' + (rint & 255) + ')';
            break;

        default:
            return rint;
            break;
    }
}

Versão atualizada:

function random_color( format ){
  var rint = Math.floor( 0x100000000 * Math.random());
  switch( format ){
    case 'hex':
      return '#' + ('00000'   + rint.toString(16)).slice(-6).toUpperCase();
    case 'hexa':
      return '#' + ('0000000' + rint.toString(16)).slice(-8).toUpperCase();
    case 'rgb':
      return 'rgb('  + (rint & 255) + ',' + (rint >> 8 & 255) + ',' + (rint >> 16 & 255) + ')';
    case 'rgba':
      return 'rgba(' + (rint & 255) + ',' + (rint >> 8 & 255) + ',' + (rint >> 16 & 255) + ',' + (rint >> 24 & 255)/255 + ')';
    default:
      return rint;
  }
}

1
Talvez sim; mas em qual site você prefere a possível receita do Google Adwords? =)
— David diz para reinstalar Monica

2
qual site dá a resposta? se eles fornecerem a resposta, eles devem receber os hits.
— 21339 Funky Dude

1
@FunkyDude agora este resultado é o topo um no Google e no stackoverflow razão existe é a de não usar o Google muitas vezes;)
— Akshat

10

Resposta curta com teclado para o tamanho exato

'#'+((1<<24)*(Math.random()+1)|0).toString(16).substr(1)


10
var color = "#";
for (k = 0; k < 3; k++) {
    color += ("0" + (Math.random()*256|0).toString(16)).substr(-2);
}

Um detalhamento de como isso funciona:

Math.random()*256obtém um número aleatório (ponto flutuante) de 0 a 256 (inclusive 0 a 255)
Resultado do exemplo: 116.15200161933899

Adicionando as |0tiras de tudo depois do ponto decimal.
Ex: 116.15200161933899 -> 116

Usar .toString(16)converte esse número em hexadecimal (base 16).
Ex: 116 -> 74
Outro ex: 228 -> e4

Adicionar "0"almofadas com um zero. Isso será importante quando obtivermos a substring, pois nosso resultado final deve ter dois caracteres para cada cor.
Ex: 74 -> 074
Outro ex: 8 -> 08

.substr(-2)recebe apenas os dois últimos caracteres.
Ex: 074 -> 74
Outro ex: 08 -> 08 (se não o tivéssemos adicionado "0", isso teria produzido "8" em vez de "08")

O forloop executa esse loop três vezes, adicionando cada resultado à sequência de cores, produzindo algo como isto:
#7408e4


Você deve elaborar sua resposta.
— joce

8

Portanto, embora todas as respostas aqui sejam boas, eu queria um pouco mais de controle sobre a saída. Por exemplo, eu gostaria de evitar tons quase brancos, garantindo cores vibrantes e brilhantes e não tons desbotados.

function generateColor(ranges) {
            if (!ranges) {
                ranges = [
                    [150,256],
                    [0, 190],
                    [0, 30]
                ];
            }
            var g = function() {
                //select random range and remove
                var range = ranges.splice(Math.floor(Math.random()*ranges.length), 1)[0];
                //pick a random number from within the range
                return Math.floor(Math.random() * (range[1] - range[0])) + range[0];
            }
            return "rgb(" + g() + "," + g() + "," + g() +")";
        };

Então agora eu posso especificar 3 intervalos arbitrários para escolher os valores rgb. Você pode chamá-lo sem argumentos e obter meu conjunto padrão, que geralmente gera uma cor bastante vibrante com uma sombra dominante óbvia, ou pode fornecer sua própria variedade de intervalos.


1
A API do Google Map suporta apenas cores HTML hexadecimais no formato "#FFFFFF".
— Valery Viktorovsky

Claro, bastante simples para converter um número em hexadecimal n.toString (16), apenas você precisará zerar pad para garantir um valor de retorno de dois caracteres a partir da função g interna.
— Ollie Edwards

8

O comentário mais votado da resposta principal sugere que a abordagem de Martin Ankerl é melhor que os números hexadecimais aleatórios e, embora eu não tenha melhorado a metodologia de Ankerl, eu a traduzi com sucesso para JavaScript. Eu imaginei que postaria uma resposta adicional para esse segmento SO já de tamanho mega, porque a resposta principal tem outro comentário vinculado a um Gist com a implementação JS da lógica de Ankerl e esse link está quebrado (404). Se eu tivesse reputação, teria simplesmente comentado o link jsbin que criei.

// 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) : '';
}

// next two methods converted from Ruby to JS
// soured 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 golden ratio
const golden_ratio_conjugate = 0.618033988749895
let h = Math.random() // # use 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


7

Para uma aleatoriedade decente.

Cor aleatória

`#${crypto.getRandomValues(new Uint32Array(1))[0].toString(16).padStart(8, 0).slice(-6)}`

Alfa aleatória, cor aleatória.

`#${crypto.getRandomValues(new Uint32Array(1))[0].toString(16).padStart(8, 0)}`

7

Existem muitas maneiras de conseguir isso. Aqui estão alguns que eu fiz:

Gera seis dígitos hexadecimais aleatórios (0-F)

function randColor() {
    for (var i=0, col=''; i<6; i++) {
        col += (Math.random()*16|0).toString(16);
    }
    return '#'+col;
}

Uma linha extremamente curta

'#'+Math.random().toString(16).slice(-6)

Gera componentes HEX individuais (00-FF)

function randColor2() {
    var r = ('0'+(Math.random()*256|0).toString(16)).slice(-2),
        g = ('0'+(Math.random()*256|0).toString(16)).slice(-2),
        b = ('0'+(Math.random()*256|0).toString(16)).slice(-2);
    return '#' +r+g+b;
}

Sequência hexadecimal com engenharia excessiva (os XORs 3 saem juntos para formar cores)

function randColor3() {
    var str = Math.random().toString(16) + Math.random().toString(16),
    sg = str.replace(/0./g,'').match(/.{1,6}/g),
    col = parseInt(sg[0], 16) ^ 
          parseInt(sg[1], 16) ^ 
          parseInt(sg[2], 16);
    return '#' + ("000000" + col.toString(16)).slice(-6);
}

extremley shor one-liner: quando os retornos aleatórios 0.125seguida resultado é #0.2(cor inválido)
— Kamil Kiełczewski

@ KamilKiełczewski 0.125= 3FC0000000000000em hexadecimal IEEE. 3 dígitos hexadecimais são expoente, 13 são mantissa. Há uma chance de 1 em 4,5 quadrilhões de que a mantissa esteja completamente vazia assim. Testei 100 milhões de vezes no Firefox / Chrome. Você está apenas tentando quebrá-lo;). nuncaMath.random deve lhe dar 0,125. E se isso acontecer, há um problema com o PRNG, que não é meu problema. Frações como 0,5, 0,25, 0,0625 etc. são inúteis, elas não contêm aleatoriedade. Talvez você tenha uma solução para esse caso extremo, hm? ;)
— bryc

sim, '#'+Math.random().toString(16).split('.')[1].slice(-6).padStart(6,0)mas eu prefiro isso #
— Kamil Kiełczewski 19/03/19

6

Outro gerador aleatório de cores:

var randomColor;
randomColor = Math.random() * 0x1000000; // 0 < randomColor < 0x1000000 (randomColor is a float)
randomColor = Math.floor(randomColor); // 0 < randomColor <= 0xFFFFFF (randomColor is an integer)
randomColor = randomColor.toString(16); // hex representation randomColor
randomColor = ("000000" + randomColor).slice(-6); // leading zeros added
randomColor = "#" + randomColor; // # added

6

Array.prototype.reduce torna muito limpo.

["r","g","b"].reduce(function(res) {
    return res + ("0"+~~(Math.random()*256).toString(16)).slice(-2)
}, "#")

Precisa de um calço para navegadores antigos.


no console do Chrome sempre retorne # 000000 #
— Kamil Kiełczewski 19/03/19

6

Você poderia usar esta função simples

function getRandomColor(){
 var color =  "#" + (Math.random() * 0xFFFFFF << 0).toString(16);
 return color;
}

1
quando retornos aleatórios, 0.001o resultado é "#4189"(cor inválida, 4 dígitos) #
— Kamil Kiełczewski 19/03/19


5

Use cores distintas .

Ele gera uma paleta de cores visualmente distintas.

cores distintas é altamente configurável:

  • Escolha quantas cores estão na paleta
  • Restrinja o matiz a um intervalo específico
  • Restrinja o croma (saturação) a um intervalo específico
  • Restrinja a luminosidade a um intervalo específico
  • Configurar a qualidade geral da paleta

3541 linhas de code..where outras respostas aqui são ~ 6-10 linhas ... Estou impressionado como é que alguém escreveu tantas linhas de código apenas para escolher cores distintas ..
— vsync

Escolher cores verdadeiramente visualmente distintas requer muito mais matemática do que apenas um gerador de cores aleatório.
— InternalFX

Acabei de fazê-lo em 2 linhas .. modifiquei esta função: stackoverflow.com/a/20129594/104380
— vsync

Não é tão simples assim. leitura sugerida
— InternalFX

Obrigado, artigo muito interessante. meu método sempre fornece as mesmas cores e os resultados são consistentes e distintos. Eu acho que em algumas situações você pode precisar de cores realmente aleatórias e bem distribuídas, que são bonitas para o olho humano.
— vsync

3

Aqui estão minhas duas versões para um gerador aleatório de código hexadecimal.


/* Slowest but shortest. */
"#000000".replace(/0/g,function(){return (~~(Math.random()*16)).toString(16);});    

/* Good performance with small size. */
"#"+(function(a,b){while(a--){b+=""+(~~(Math.random()*16)).toString(16);} return b;})(6,"");

/* Remy Sharp provided one that's the fastest but a little bit too long */
(function(h){return '#000000'.substr(0,7-h.length)+h})((~~(Math.random()*(1<<24))).toString(16))


3

Essa função vai acima e além de outras respostas de duas maneiras:

Ele tenta gerar cores o mais distintas possível, descobrindo qual das 20 tentativas tem a maior distância euclidiana das outras no cone do HSV

Ele permite restringir o matiz, a saturação ou o intervalo de valores, mas ainda tenta escolher cores o mais distintas possível dentro desse intervalo.

Não é super eficiente, mas por valores razoáveis ​​(quem pode escolher 100 cores facilmente?) É rápido o suficiente.

Veja 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);
  }

3

Quase todos os métodos anteriores de mão curta estão gerando códigos hexadecimais inválidos (cinco dígitos). Me deparei com uma técnica semelhante apenas sem esse problema aqui :

"#"+("000"+(Math.random()*(1<<24)|0).toString(16)).substr(-6)

Teste

Tente isso no console:

for(i = 0; i < 200; i++) {
    console.log("#" + ("000" + (Math.random()*(1<<24)|0).toString(16)).substr(-6));
}

4
Fiz um loop for que executou esse código 20000 vezes e só imprimiu no console se o comprimento fosse menor que 7 e encontrei um caso em que a string tinha menos de 6 caracteres. Além disso, um problema com esse código é que ele apenas preenche toda a cadeia de 6 dígitos, não os códigos de cores individuais de 2 dígitos, o que significa que é mais provável que você tenha zeros no valor vermelho do que nos valores verde ou azul.
— Erin Heyming

quando os retornos aleatórios 0.00001o resultado é "#000a7"(cor inválido - 5 dígitos)
— Kamil Kiełczewski

3

Minha versão:

function RandomColor() {
  var hex = (Math.round(Math.random()*0xffffff)).toString(16);
  while (hex.length < 6) hex = "0" + hex;
  return hex;
}

Eu acho que os não-aleatórias 0torna a cor não randomo suficiente XD
— shrekuu

Geramos um número hexadecinal de 0para ffffff. Qual é uma distribuição uniforme perfeita . Esse zero é apenas para concluir a sequência, devido a considerações de uso do navegador. Eu sugiro que você pareça mais cuidadoso com esta solução.
— Prostakov

Fiz alguns ajustes, porém, não vinculados ao seu comentário :) #
— Prostakov

Obrigado Prostakov. : D
— shrekuu


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.