Générateur de couleurs aléatoires


441

Compte tenu de cette fonction, je veux remplacer la couleur par un générateur de couleurs aléatoire.

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

Comment puis-je le faire?


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


2
@SepehrM lorsque le retour est aléatoire, le 0.001résultat est "#4189"(couleur non valide - 4 chiffres)
Kamil Kiełczewski

Ceci est une très bonne solution, pour moi très utile github.com/davidmerfield/randomColor
maikelm

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

Réponses:


1019

Utilisation getRandomColor()à la place 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
Notez que cela a un biais vers des couleurs assez sombres et insaturées en raison de la façon dont RVB enveloppe l'espace colorimétrique. Martin Ankerl a aussi un bel article sur la génération de couleurs à partir d'autres espaces (comme HSV): martin.ankerl.com/2009/12/09/…
Thomas Ahle

13
Les chances de frapper 0 ou 15 lors de l'utilisation Math.round(Math.random()*15)ne sont que de 1h30, tandis que les chances des autres numéros sont de 1h15.
user123444555621

3
Vous pouvez supprimer l'appel .split (''). Les chaînes ont déjà un indexeur de tableau.
ujeenator

3
Vous pouvez également utiliser une fonction de générateur en tant que telle
tsuz

5
Ce code est boiteux. Voici un oneliner: Math.floor (Math.random () * 16777215) .toString (16)
DDD

269

Je doute que quelque chose soit plus rapide ou plus court que celui-ci:

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

Défi!


18
Vous avez oublié de remplir avec des zéros.
user123444555621

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

15
@Mohsen, FYI de temps en temps, votre code produit un numéro à 5 chiffres invalide
rochal

6
Le résultat n'est pas complété à 6 chiffres
Taha Jahangir

33
('00000'+(Math.random()*(1<<24)|0).toString(16)).slice(-6)retournera toujours une longueur de 6. bien que cette méthode retourne toujours (rarement) de petits nombres qui donnent des résultats comme 000cf4ou 0000a7qui est un peu hacky je pense. dans ces cas, la composante rouge ne contribue pas à la couleur aléatoire.
bryc

162

Voici une autre vision de ce problème.

Mon objectif était de créer des couleurs vives et distinctes. Pour m'assurer que les couleurs sont distinctes, j'évite d'utiliser un générateur aléatoire et sélectionne des couleurs "régulièrement espacées" de l'arc-en-ciel.

Ceci est parfait pour créer des marqueurs pop-out dans Google Maps qui ont une "unicité" optimale (c'est-à-dire qu'aucun deux marqueurs n'auront des couleurs similaires).

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

Si vous souhaitez voir à quoi cela ressemble en action, voir http://blog.adamcole.ca/2011/11/simple-javascript-rainbow-color.html .


7
Je cherchais quelque chose comme ça! Super truc!
Khôi

J'ai fait une implémentation simplifiée de la même idée que la réponse à une question similaire stackoverflow.com/a/14187677/421010
Andrew

16
Quelle sera donc la valeur du paramètre?
Ekramul Hoque

2
J'ai également créé quelque chose comme ça, mais c'est assez aléatoire et assez distinct. Le pseudo-code est ici . Il utilise hsv plutôt que rgb, car hsv a un comportement beaucoup plus prévisible. Si vous voulez voir l'implémentation de Python, je l'ai utilisée ici et ici . Vous devrez rechercher dans le code "couleur".
zondo

1
@RobertMolina: Désolé, j'ai déplacé mes affaires vers Gitlab. Le pseudo-code est maintenant , avec les projets ici et ici .
zondo

56

Qui peut le battre?

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

Garantie de travailler tout le temps: http://jsbin.com/OjELIfo/2/edit

D'après le commentaire de @eterps, le code ci-dessus peut toujours générer des chaînes plus courtes si la représentation hexadécimale de la couleur aléatoire est très courte ( 0.730224609375=> 0.baf)

Ce code devrait fonctionner dans tous les cas:

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

12
Lorsque Math.random () renvoie 0,022092682472568126, ce code produit une chaîne '# 5a7dd' non valide. fou!
rochal

Comme celui-ci puisque #ffffff n'apparaît pas trop souvent.
Warface

Il y a pas mal d'occurrences où cela ne fonctionnera pas. Vérifiez la sortie suivante pour Math.random () ... 0.730224609375, 0.43603515625, 0.957763671875, et la liste continue ...
eterps

@eterps Ce ne sont PAS des nombres aléatoires appropriés ! Voir IEEE 754 à double brut en hexadécimal: 0.730224609375 = 0x3fe75e0000000000, 0.43603515625 = 0x3fdbe80000000000, 0.957763671875 = 0x3feea60000000000. Presque aucune mantisse n'est utilisée! Ce ne sont que des fractions glorifiées. Une sortie correcte à 12 chiffres produirait des résultats tels que:0.347876714234 = 0x3fd6439cb1ab32ac, 0.447556256665 = 0x3fdca4c2ff5fc450
bryc

Depuis 2015, je crois que de nombreux navigateurs Web ont remplacé les PRNG merdiques utilisés sous le capot Math.random()(dont je dois présumer qu'ils sont responsables des résultats de @ etertp) par de meilleurs, donc ces types de nombres aléatoires de faible qualité devraient être une chose du passé maintenant.
bryc

30

Vous pouvez également utiliser HSL disponible sur tous les bons navigateurs ( http://caniuse.com/#feat=css3-colors )

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

Cela ne vous donnera que des couleurs vives, vous pouvez jouer avec la luminosité, la saturation et l'alpha.

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

Merci! J'ai réussi à obtenir des couleurs parfaites pour les arrière-plans avec:'hsla(' + (Math.floor(Math.random()*360) + ', 100%, 70%, 1)'
jj_

1
Pas de problème, j'ai été surpris de ne voir personne utiliser le pouvoir de hsl :)
kigiri

stackoverflow.com/a/23861752/1693593 , hsla n'est pas nécessaire s'il alpha = 1, utilisez simplement hsl

1
Vous ne pouvez pas générer de couleur 16M de cette façon (par exemple, vous n'obtiendrez jamais de niveaux de gris blanc-noir) - cependant oui - si nous utilisons au hasard pour chaque composant, nous obtenons tous les corols hsl
Kamil Kiełczewski

1
+1 Cela facilite l'utilisation de la luminosité et de la saturation pour définir des couleurs d'arrière-plan aléatoires tout en garantissant que le texte est toujours lisible
Osvaldo Maria

29

Il n'y a pas besoin d'un hachage de lettres hexadécimales. JavaScript peut le faire par lui-même:

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

27

J'aime celui la: '#' + (Math.random().toString(16) + "000000").substring(2,8)


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

@MohammadAnin qui a 1 chance sur 16 de produire moins de 6 chiffres
James

1
Cela pourrait générer des couleurs non valides. Par exemple '#' + (0.125).toString(16).substring(2, 8) === '#2'. C'est dangereux car la probabilité est faible (1 sur 4096 je pense) donc un bug est susceptible de passer au travers des tests. Vous devriez ('#' + Math.random().toString(16) + "000000").substring(2, 8)
James

Correction: devrait être'#' + (Math.random().toString(16) + "000000").substring(2,8)
James

25

Génération aléatoire des couleurs avec contrôle de la luminosité:

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
Très cool, mais génère principalement des «pastels» plutôt que des couleurs plus vibrantes que j'espérais quand j'ai vu la luminosité. Toujours dans mon sac de trucs!
JayCrossler

J'aime vraiment celui-ci parce que vous pouvez le personnaliser pour qu'il soit en harmonie avec la palette de couleurs de votre site Web
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

J'aime ça pour sa lisibilité
hitautodestruct

1
si Math.random()retour, 0.125le résultat sera #0.2(couleur invalide) (vous devez ajouter du rembourrage à la place)
Kamil Kiełczewski

18

L'article écrit par Paul Irish sur Random Hex Color Code Generator en JavaScript est absolument incroyable. Utilisation:

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

Voici le lien source:

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


5
cela retournera parfois des valeurs de couleurs non bien formées comme "1fa4c" (doit être de 3 ou 6 caractères)
jj_

1
@jj_ est-ce? désolé, je ne l'ai pas remarqué. Merci pour le partage
way2vin

lors d'un retour aléatoire, le 0.00001résultat est #a7(couleur invalide)
Kamil Kiełczewski

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

17

Voici un tour sur la solution fournie par @Anatoliy.

Je n'avais besoin de générer que des couleurs claires (pour les arrière-plans), j'ai donc opté pour un format à trois lettres (#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;
}

Je pense que cela est susceptible de produire le plus souvent des couleurs qui sont étroitement similaires bien que légères. Pour une gamme plus clairsemée de couleurs aléatoires, je pense que la réponse de @ Anatoli est meilleure pour la plupart
larrytech

15

Si vous êtes un noob comme moi, ignorant les hexadécimaux et autres, cela pourrait être plus intuitif.

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

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

Vous avez juste besoin de vous retrouver avec une chaîne telle que 'rgb(255, 123, 220)'


cette réponse doit être la meilleure
Gil Epshtain

Vous devez cependant utiliser 256 pour obtenir 0.
Lisa Cerilli

13

Cela peut être trouvé très facilement en utilisant la recherche 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;
    }
}

Version mise à jour:

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
Peut-être; mais sur quel site préféreriez-vous que les revenus Google Adwords soient allés? =)
David dit de réintégrer Monica le

2
quel site vous donne la réponse? s'ils vous fournissent la réponse, ils devraient obtenir les résultats.
Funky Dude

1
@FunkyDude maintenant ce résultat est le meilleur sur google et la raison pour laquelle stackoverflow existe est de ne pas utiliser google trop souvent;)
Akshat

10

Réponse courte avec tampon à la taille exacte

'#'+((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);
}

Une ventilation de comment cela fonctionne:

Math.random()*256 obtient un nombre aléatoire (virgule flottante) de 0 à 256 (0 à 255 inclus)
Exemple de résultat: 116.15200161933899

Ajouter les |0bandes de tout après la virgule décimale.
Ex: 116.15200161933899 -> 116

L'utilisation .toString(16)convertit ce nombre en hexadécimal (base 16).
Ex: 116 -> 74
Autre ex: 228 -> e4

L'ajout de "0"tampons avec un zéro. Cela sera important lorsque nous obtiendrons la sous-chaîne, car notre résultat final doit avoir deux caractères pour chaque couleur.
Ex: 74 -> 074
Un autre ex: 8 -> 08

.substr(-2)obtient uniquement les deux derniers caractères.
Ex: 074 -> 74
Un autre ex: 08 -> 08 (si nous n'avions pas ajouté le"0" , cela aurait produit "8" au lieu de "08")

La forboucle exécute cette boucle trois fois, ajoutant chaque résultat à la chaîne de couleurs, produisant quelque chose comme ceci:
#7408e4


Vous devriez étoffer votre réponse.
joce

8

Donc, bien que toutes les réponses ici soient bonnes, je voulais un peu plus de contrôle sur la sortie. Par exemple, j'aimerais éviter les nuances de blanc proche, tout en m'assurant d'obtenir des couleurs vives et vives et non délavées.

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() +")";
        };

Alors maintenant, je peux spécifier 3 plages arbitraires pour choisir des valeurs RVB. Vous pouvez l'appeler sans argument et obtenir mon jeu par défaut qui générera généralement une couleur assez vibrante avec une teinte dominante évidente, ou vous pouvez fournir votre propre tableau de plages.


1
L'API Google Map ne prend en charge que la couleur HTML hexadécimale au format "#FFFFFF".
Valery Viktorovsky

Bien sûr, assez simple pour convertir un nombre en hexadécimal n.toString (16), seul l'accroc est que vous devrez mettre à zéro le pad pour vous assurer d'obtenir une valeur de retour à deux caractères de la fonction g interne.
Ollie Edwards

8

Le commentaire le plus voté de la réponse du haut suggère que l'approche de Martin Ankerl est meilleure que les nombres hexadécimaux aléatoires, et bien que je n'ai pas amélioré la méthodologie d'Ankerl, je l'ai traduite avec succès en JavaScript. J'ai pensé que je publierais une réponse supplémentaire à ce thread SO déjà de grande taille, car la réponse du haut a un autre commentaire lié à un Gist avec l'implémentation JS de la logique d'Ankerl et ce lien est rompu (404). Si j'avais eu la réputation, j'aurais simplement commenté le lien jsbin que j'ai créé.

// 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

Pour un hasard décent.

Couleur aléatoire

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

Alpha aléatoire, couleur aléatoire.

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

7

Il y a tellement de façons d'y parvenir. En voici quelques-unes que j'ai faites:

Génère six chiffres hexadécimaux aléatoires (0-F)

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

Une doublure extrêmement courte

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

Génère des composants HEX individuels (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;
}

Chaîne hexagonale sur-conçue (XORs 3 sorties ensemble pour former la couleur)

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: lorsque le retour est aléatoire, le 0.125résultat est #0.2(couleur invalide)
Kamil Kiełczewski

@ KamilKiełczewski 0.125= 3FC0000000000000dans l'hex IEEE. 3 chiffres hexadécimaux sont exposants, 13 sont des mantisses. Il y a 1 chance sur 4,5 quadrillions que la mantisse soit complètement vide comme ça. J'ai testé 100m fois dans Firefox / Chrome. Vous essayez juste de le casser;). neMath.random devrait jamais vous donner 0,125. Et si c'est le cas, il y a un problème avec le PRNG, ce qui n'est pas mon problème. Des fractions comme 0,5, 0,25, 0,0625, etc. sont inutiles, elles ne contiennent aucun caractère aléatoire. Peut-être avez-vous une solution à ce cas extrême, hm? ;)
bryc

oui '#'+Math.random().toString(16).split('.')[1].slice(-6).padStart(6,0)mais je préfère cela
Kamil Kiełczewski

6

Encore un autre générateur de couleurs aléatoires:

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 le rend très propre.

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

A besoin d'une cale pour les anciens navigateurs.


dans la console chromée retourne toujours # 000000
Kamil Kiełczewski

6

Vous pouvez utiliser cette fonction simple

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

1
lorsque 0.001le résultat est aléatoire, le résultat est "#4189"(couleur non valide à 4 chiffres)
Kamil Kiełczewski


5

Utilisez des couleurs distinctes .

Il génère une palette de visuellement couleurs distinctes.

distinct-colors est hautement configurable:

  • Choisissez le nombre de couleurs dans la palette
  • Restreindre la teinte à une plage spécifique
  • Restreindre la chrominance (saturation) à une plage spécifique
  • Restreindre la légèreté à une plage spécifique
  • Configurer la qualité générale de la palette

3541 lignes de code..où d'autres réponses ici sont ~ 6-10 lignes ... je suis impressionné comment quelqu'un a écrit autant de lignes de code juste pour choisir des couleurs distinctes ..
vsync

Choisir des couleurs vraiment visuellement distinctes nécessite beaucoup plus de mathématiques qu'un simple générateur de couleurs aléatoires.
InternalFX

Je viens de le faire en 2 lignes .. a modifié cette fonction: stackoverflow.com/a/20129594/104380
vsync

Ce n'est pas aussi simple. lecture suggérée
InternalFX

Merci, article très intéressant. ma méthode fournit toujours les mêmes couleurs et les résultats sont cohérents et distinctifs. Je suppose que dans certaines situations, vous pourriez avoir besoin de couleurs vraiment aléatoires et bien réparties qui sont jolies à l'œil humain.
vsync

3

Voici mes deux versions pour un générateur de code hexadécimal aléatoire.


/* 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

Cette fonction va au-delà des autres réponses de deux manières:

Il tente de générer des couleurs aussi distinctes que possible en trouvant quelle couleur sur 20 essais a la distance euclidienne la plus éloignée des autres dans le cône HSV

Il vous permet de restreindre la teinte, la saturation ou la plage de valeurs, mais tente toujours de choisir des couleurs aussi distinctes que possible dans cette plage.

Ce n'est pas super efficace, mais pour des valeurs raisonnables (qui pourrait même séparer facilement 100 couleurs?) C'est assez rapide.

Voir 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

Presque toutes les méthodes précédentes à main courte génèrent des codes hexadécimaux invalides (cinq chiffres). Je suis tombé sur une technique similaire uniquement sans ce problème ici :

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

Tester

Essayez ceci dans la console:

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

4
J'ai fait une boucle for qui a exécuté ce code 20000 fois et imprimé uniquement sur la console si la longueur était inférieure à 7, et j'ai trouvé un cas où la chaîne était inférieure à 6 caractères. En outre, un problème avec ce code est qu'il ne remplit que la chaîne entière à 6 chiffres, pas les codes de couleur individuels à 2 chiffres, ce qui signifie que vous êtes plus susceptible d'avoir des zéros dans la valeur rouge que dans les valeurs vertes ou bleues.
Erin Heyming

lors d'un retour aléatoire, 0.00001le résultat est "#000a7"(couleur invalide - 5 chiffres)
Kamil Kiełczewski

3

Ma version:

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

Je pense que le non-aléatoire 0rend la couleur randominsuffisante XD
shrekuu

Nous générons de façon aléatoire un nombre hexadécinal de 0à ffffff. Ce qui est une distribution uniforme parfaite . Ce zéro ne sert qu'à compléter la chaîne, en raison de considérations d'utilisation du navigateur. Je vous suggère de regarder plus attentivement cette solution.
Prostakov

J'ai cependant fait quelques ajustements, sans lien avec votre commentaire :)
Prostakov

Merci Prostakov. : D
shrekuu


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.