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?

n00ki3
fonte
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>

Anatoliy
fonte
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!

ZPiDER
fonte
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 .

Adam Cole
fonte
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;
}
Mohsen
fonte
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();
}
Alsciende
fonte
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)`
kigiri
fonte
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)

Nicolas Buduroi
fonte
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(",") + ")";
}
letronje
fonte
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
jt3k
fonte
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/

way2vin
fonte
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;
}
Andrei R
fonte
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)'

ICoffeeConsumer
fonte
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;
  }
}
Cara Funky
fonte
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)

Taha Jahangir
fonte
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

Erin Heyming
fonte
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.

Ollie Edwards
fonte
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

spakmad
fonte
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)}`
Константин Ван
fonte
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);
}
bryc
fonte
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
Salman A
fonte
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.

user1106925
fonte
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;
}
ChandrasekarG
fonte
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
InternalFX
fonte
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))

Larry Battle
fonte
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);
  }
Andy
fonte
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));
}
manikanta
fonte
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;
}
Prostakov
fonte
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
3

map (retorna sempre a cor rgb válida)

`rgb(${[1,2,3].map(x=>Math.random()*256|0)})`

Kamil Kiełczewski
fonte
2

Você pode usar o colorchain.js para gerar uma sequência de cores com tons variados.

alexishacks
fonte