Generator losowych kolorów


440

Biorąc pod uwagę tę funkcję, chcę zastąpić kolor losowym generatorem kolorów.

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

Jak mogę to zrobić?


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


2
@ SepehrM, gdy losowe zwroty, 0.001to wynik jest "#4189"(nieprawidłowy kolor - 4 cyfry)
Kamil Kiełczewski

To bardzo fajne rozwiązanie, dla mnie bardzo przydatne github.com/davidmerfield/randomColor
maikelm

5
'#'+Math.random().toString(16).substr(2,6) (źródło: CodeGolf )
ashleedawg

Odpowiedzi:


1018

Użyj getRandomColor()zamiast "#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
Zauważ, że ma to tendencję do dość ciemnych i nienasyconych kolorów ze względu na sposób, w jaki RGB otacza przestrzeń kolorów. Martin Ankerl ma również fajny artykuł na temat generowania kolorów z innych przestrzeni (takich jak HSV): martin.ankerl.com/2009/12/09/…
Thomas

13
Szanse na trafienie 0 lub 15 podczas używania Math.round(Math.random()*15)wynoszą tylko 1:30, podczas gdy szanse innych liczb to 1:15.
user123444555621

3
Możesz usunąć połączenie .split (''). Łańcuch ma już indeksator macierzy.
ujeenator

3
Możesz także użyć funkcji generatora jako takiej
tsuz

5
Ten kod jest kiepski. Oto oneliner: Math.floor (Math.random () * 16777215) .toString (16)
DDD

269

Wątpię, aby cokolwiek było szybsze lub krótsze niż ten:

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

Wyzwanie!


18
Zapomniałeś wpisać zera.
user123444555621

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

15
@Mohsen, FYI co jakiś czas kod generuje nieprawidłowy 5-cyfrowy numer
rochal

6
Wynik nie jest dopełniany do 6 cyfr
Taha Jahangir

33
('00000'+(Math.random()*(1<<24)|0).toString(16)).slice(-6)zawsze zwróci długość 6. chociaż ta metoda nadal (rzadko) zwraca małe liczby, które dają wyniki takie jak 000cf4lub, 0000a7co myślę, jest nieco hacky. w tych przypadkach czerwony składnik nie przyczynia się do losowego koloru.
bryc

162

Oto kolejne spojrzenie na ten problem.

Moim celem było stworzenie żywych i wyrazistych kolorów. Aby upewnić się, że kolory są wyraźne, unikam używania losowego generatora i wybieram kolory „równomiernie rozmieszczone” z tęczy.

Jest to idealne do tworzenia wyskakujących znaczników w Mapach Google, które mają optymalną „unikalność” (to znaczy, że żadne dwa znaczniki nie będą miały podobnych kolorów).

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

Jeśli chcesz zobaczyć, jak to wygląda w akcji, zobacz http://blog.adamcole.ca/2011/11/simple-javascript-rainbow-color.html .


7
Szukałem czegoś takiego! Świetne rzeczy!
Khôi

Uczyniłem uproszczoną implementację tego samego pomysłu, co odpowiedź na podobne pytanie stackoverflow.com/a/14187677/421010
Andrew

16
Jaka będzie wartość parametru?
Ekramul Hoque

2
Stworzyłem też coś takiego, ale jest to dość losowe i wyraźne. Pseudo-kod jest tutaj . Używa hsv zamiast rgb, ponieważ hsv ma ​​znacznie bardziej przewidywalne zachowanie. Jeśli zależy ci na implementacji Pythona, użyłem jej tu i tutaj . Musisz przeszukać kod pod kątem „koloru”.
zondo

1
@RobertMolina: Przepraszam, przeniosłem swoje rzeczy do Gitlab. Pseudo-kod jest teraz tutaj , z projektami tu i tutaj .
zondo

56

Kto może to pokonać?

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

Gwarantujemy pracę przez cały czas: http://jsbin.com/OjELIfo/2/edit

Na podstawie komentarza @eterps powyższy kod może nadal generować krótsze ciągi, jeśli szesnastkowa reprezentacja losowego koloru jest bardzo krótka ( 0.730224609375=> 0.baf)

Ten kod powinien działać we wszystkich przypadkach:

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

12
Gdy Math.random () zwraca 0,022092682472568126, ten kod generuje niepoprawny ciąg „# 5a7dd”. zwariowany!
rochal

Tak jak ten, ponieważ #ffffff nie pojawia się zbyt często.
Warface

Jest kilka przypadków, w których to nie zadziała. Sprawdź następujące dane wyjściowe dla Math.random () ... 0.730224609375, 0.43603515625, 0.957763671875, a lista jest długa ...
eterps

@eterps NIE są to prawidłowe liczby losowe ! Zobacz surowy IEEE 754 double w hex: 0.730224609375 = 0x3fe75e0000000000, 0.43603515625 = 0x3fdbe80000000000, 0.957763671875 = 0x3feea60000000000. Rzadko używana jest mantysa! To tylko uwielbione frakcje. Właściwa '12 cyfra”wyjście przyniosą rezultatów, takich jak:0.347876714234 = 0x3fd6439cb1ab32ac, 0.447556256665 = 0x3fdca4c2ff5fc450
bryc

Od 2015 roku uważam, że wiele przeglądarek internetowych zastąpiło kiepskie PRNG używane pod maską Math.random()( dla których muszę założyć, że odpowiada za wyniki @ etertp) na lepsze, więc te losowe liczby niskiej jakości powinny być przeszłością teraz.
bryc

29

Nie ma potrzeby mieszania liter szesnastkowych. JavaScript może to zrobić sam:

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

Możesz także korzystać z HSL dostępnego w każdej dobrej przeglądarce ( http://caniuse.com/#feat=css3-colours )

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

Daje to tylko jasne kolory, możesz bawić się jasnością, nasyceniem i alfa.

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

Dzięki! Udało mi się uzyskać idealne kolory tła:'hsla(' + (Math.floor(Math.random()*360) + ', 100%, 70%, 1)'
jj_

1
Nie ma problemu, zdziwiłem się, że nikt nie korzysta z mocy hsl :)
kigiri,

stackoverflow.com/a/23861752/1693593 , hsla nie jest potrzebny, to alpha = 1, wystarczy użyć hsl

1
Nie możesz wygenerować 16M kolor w ten sposób (np. Nigdy nie dostaniesz biało-czarnej skali szarości) - jednak tak - jeśli użyjemy losowo do każdego komponentu, otrzymamy wszystkie hsl corols
Kamil Kiełczewski

1
+1 Ułatwia to użycie jasności i nasycenia do ustawiania losowych kolorów tła, zapewniając jednocześnie czytelność tekstu
Osvaldo Maria

27

Podoba mi się ten: '#' + (Math.random().toString(16) + "000000").substring(2,8)


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

@MohammadAnin, który ma 1 na 16 szansy na wyprodukowanie mniej niż 6 cyfr
James

1
Może to generować nieprawidłowe kolory. Na przykład '#' + (0.125).toString(16).substring(2, 8) === '#2'. Jest to niebezpieczne, ponieważ prawdopodobieństwo jest niskie (chyba 1 na 4096), więc błąd prawdopodobnie przejdzie przez testy. Zalecana ('#' + Math.random().toString(16) + "000000").substring(2, 8)
James

Korekta: powinno być'#' + (Math.random().toString(16) + "000000").substring(2,8)
James

25

Losowe generowanie kolorów z kontrolą jasności:

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
Bardzo fajnie, choć generuje raczej „pastele” niż żywsze kolory, na które liczyłem, kiedy zobaczyłem jasność. Wciąż wchodzę w moją torbę sztuczek!
JayCrossler,

Naprawdę podoba mi się ten, ponieważ można go dostosować, aby był w harmonii z paletą kolorów witryny
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

Podoba mi się to ze względu na czytelność
hitautodestruct

1
jeśli Math.random()powrót, 0.125to wynik będzie #0.2(niepoprawny kolor) (trzeba dodać dopełnienie zamiast plasterka)
Kamil Kiełczewski

18

Artykuł napisany przez Paula Irlanda na temat generatora losowych kodów kolorów heksadecymalnych w JavaScript jest absolutnie niesamowity. Posługiwać się:

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

Oto link źródłowy:

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


5
to kiedyś zwróci źle sformułowane wartości kolorów, takie jak „1fa4c” (muszą mieć 3 lub 6 znaków)
jj_

1
@jj_ to jest? przepraszam, nie zauważyłem tego. Dzięki za udostępnienie
way2vin,

kiedy losowy powrót 0.00001to wynik jest #a7(nieprawidłowy kolor)
Kamil Kiełczewski

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

17

Oto zwrot rozwiązania dostarczonego przez @Anatoliy.

Musiałem wygenerować tylko jasne kolory (dla tła), więc wybrałem format trzyliterowy (#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;
}

Myślę, że prawdopodobnie spowoduje to powstanie najczęściej podobnych kolorów, choć jasnych. Dla bardziej rzadkiego zakresu przypadkowych kolorów, myślę, że odpowiedź @ Anatoli jest w większości
lepsza

15

Jeśli jesteś noobem takim jak ja, nieświadomym o liczbach szesnastkowych itp., Może to być bardziej intuicyjne.

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

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

Musisz skończyć z ciągiem takim jak 'rgb(255, 123, 220)'


ta odpowiedź musi być najważniejsza
Gil Epshtain

Musisz jednak użyć 256, aby uzyskać 0.
Lisa Cerilli

13

Można to bardzo łatwo znaleźć za pomocą wyszukiwarki 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;
    }
}

Zaktualizowana wersja:

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
Może tak; ale do której witryny wolelibyście potencjalne przychody z Google Adwords? =)
David mówi, że przywróć Monikę

2
która strona daje odpowiedź? jeśli udzielą ci odpowiedzi, powinni uzyskać trafienia.
Funky Dude

1
@FunkyDude teraz ten wynik jest najlepszy w Google i powodem, dla którego istnieje
przepełnienie stosu,

10

Krótka odpowiedź z podkładką do dokładnego rozmiaru

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

Podział tego, jak to działa:

Math.random()*256pobiera liczbę losową (zmiennoprzecinkową) od 0 do 256 (od 0 do 255 włącznie)
Przykładowy wynik: 116.15200161933899

Dodanie |0pasków wszystkiego po przecinku.
Np .: 116,15200161933899 -> 116

Użycie .toString(16)przekształca tę liczbę na szesnastkową (podstawa 16).
Przykład: 116 -> 74
Kolejny przykład: 228 -> e4

Dodanie "0"powoduje wstawienie go do zera. Będzie to ważne, gdy otrzymamy podłańcuch, ponieważ nasz końcowy wynik musi mieć po dwie znaki dla każdego koloru.
Przykład: 74 -> 074
Kolejny przykład: 8 -> 08

.substr(-2)dostaje tylko dwie ostatnie postacie.
Przykład: 074 -> 74
Kolejny przykład: 08 -> 08 (gdybyśmy go nie dodali "0", to dałoby to „8” zamiast „08”)

forPętla działa ta pętla trzykrotnie, dodając każdy wynik do ciągu barw, tworząc coś takiego:
#7408e4


Powinieneś udzielić odpowiedzi.
joce

8

Tak więc, chociaż wszystkie odpowiedzi tutaj są dobre, chciałem nieco więcej kontroli nad wyjściem. Na przykład chciałbym zapobiec prawie białym odcieniom, zapewniając jednocześnie jasne, żywe kolory, a nie odcienie.

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

Teraz mogę określić 3 dowolne zakresy, z których można wybierać wartości rgb. Możesz to nazwać bez argumentów i uzyskać mój domyślny zestaw, który zwykle generuje dość żywy kolor z oczywistym dominującym odcieniem, lub możesz podać własną tablicę zakresów.


1
Interfejs API Map Google obsługuje tylko szesnastkowy kolor HTML w formacie „#FFFFFF”.
Valery Viktorovsky

Jasne, dość proste, aby przekonwertować liczbę na heks n.toString (16) tylko szkopuł, musisz wyzerować pad, aby upewnić się, że otrzymujesz dwuznakową wartość zwrotną z wewnętrznej funkcji g.
Ollie Edwards,

8

Najwyżej głosowany komentarz najwyższej odpowiedzi sugeruje, że podejście Martina Ankerla jest lepsze niż losowe liczby szesnastkowe i chociaż nie ulepszyłem metodologii Ankerla, z powodzeniem przetłumaczyłem ją na JavaScript. Pomyślałem, że opublikuję dodatkową odpowiedź na ten już gigantyczny wątek SO, ponieważ pierwsza odpowiedź zawiera inny komentarz prowadzący do Gist z implementacją JS logiki Ankerla i ten link jest zepsuty (404). Gdybym miał reputację, po prostu skomentowałbym utworzony link 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) : '';
}

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

Za przyzwoitą losowość.

Losowy kolor

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

Losowy alfa, losowy kolor.

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

7

Jest tak wiele sposobów na osiągnięcie tego. Oto niektóre zrobiłem:

Generuje sześć losowych cyfr szesnastkowych (0-F)

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

Niezwykle krótki jednowarstwowy

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

Generuje poszczególne komponenty HEX (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;
}

Przepracowany ciąg szesnastkowy (XOR 3 razem tworzy kolor)

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: gdy losowe zwroty, 0.125wynik jest #0.2(nieprawidłowy kolor)
Kamil Kiełczewski

@ KamilKiełczewski 0.125= 3FC0000000000000in hex IEEE. 3 cyfry szesnastkowe oznaczają wykładnik, 13 to mantysa. Istnieje szansa 1 na 4,5 biliarda, że mantysa jest zupełnie pusta. Testowałem 100 milionów razy w obu przeglądarkach Firefox / Chrome. Po prostu próbujesz to złamać;). nigdy nieMath.random powinien dać ci 0,125. A jeśli tak, to jest problem z PRNG, który nie jest moim problemem. Frakcje takie jak 0,5, 0,25, 0,0625 itd. Są bezużyteczne, nie zawierają losowości. Może masz rozwiązanie tej ekstremalnej skrzynki, hm? ;)
bryc

tak, '#'+Math.random().toString(16).split('.')[1].slice(-6).padStart(6,0)ale wolę to
Kamil Kiełczewski

6

Kolejny generator losowych kolorów:

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 sprawia, że ​​jest bardzo czysty.

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

Potrzebuje podkładki dla starych przeglądarek.


w chromowanej konsoli zawsze zwracaj # 000000
Kamil Kiełczewski

6

Możesz użyć tej prostej funkcji

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

1
gdy losowy zwraca 0.001wynik jest "#4189"(niepoprawny kolor 4 cyfry)
Kamil Kiełczewski


5

Używaj wyraźnych kolorów .

Generuje paletę wizualnie wyraźnych kolorów.

wyraźne kolory są wysoce konfigurowalne:

  • Wybierz, ile kolorów jest w palecie
  • Ogranicz odcień do określonego zakresu
  • Ogranicz nasycenie (nasycenie) do określonego zakresu
  • Ogranicz lekkość do określonego zakresu
  • Skonfiguruj ogólną jakość palety

3541 linii kodu .. gdzie inne odpowiedzi są ~ 6-10 linii ... Jestem pod wrażeniem, jak ktoś napisał tak wiele linii kodu, aby wybrać wyraźne kolory ..
vsync

Wybór naprawdę wyraźnych wizualnie kolorów wymaga znacznie więcej matematyki niż tylko losowego generatora kolorów.
InternalFX

Właśnie zrobiłem to w 2 liniach .. zmodyfikowałem tę funkcję: stackoverflow.com/a/20129594/104380
vsync

To nie takie proste. sugerowana lektura
InternalFX

Dzięki, bardzo interesujący artykuł. moja metoda zawsze zapewnia te same kolory, a wyniki są spójne i charakterystyczne. Myślę, że w niektórych sytuacjach możesz potrzebować naprawdę przypadkowych, dobrze rozłożonych kolorów, które są ładne dla ludzkiego oka.
vsync

3

Oto moje dwie wersje losowego generatora kodu szesnastkowego.


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

Ta funkcja wykracza poza inne odpowiedzi na dwa sposoby:

Próbuje generować kolory tak wyraźne, jak to możliwe, znajdując, który z 20 prób ma największą odległość euklidesową od innych w stożku HSV

Pozwala ograniczyć odcień, nasycenie lub zakres wartości, ale nadal próbuje wybrać kolory tak wyraźne, jak to możliwe w tym zakresie.

Nie jest super wydajny, ale dla rozsądnych wartości (kto mógłby nawet łatwo rozdzielić 100 kolorów?) Jest wystarczająco szybki.

Zobacz 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

Prawie wszystkie poprzednie metody krótkiej ręki generują nieprawidłowe kody szesnastkowe (pięć cyfr). Natrafiłem na podobną technikę tylko bez tego problemu tutaj :

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

Test

Wypróbuj to w konsoli:

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

4
Zrobiłem pętlę for, która uruchamiała ten kod 20000 razy i drukowałem na konsoli tylko wtedy, gdy długość była mniejsza niż 7, i znalazłem przypadek, w którym łańcuch był mniejszy niż 6 znaków. Ponadto jednym problemem z tym kodem jest to, że wypełnia on tylko cały 6-cyfrowy ciąg, a nie poszczególne 2-cyfrowe kody kolorów, co oznacza, że ​​bardziej prawdopodobne jest, że będziesz mieć zera w wartości czerwonej niż w wartościach zielonych lub niebieskich.
Erin Heyming

gdy losowy zwraca 0.00001wynik jest "#000a7"(nieprawidłowy kolor - 5 cyfr)
Kamil Kiełczewski

3

Moja wersja:

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

Myślę, że nieprzypadkowy 0sprawia, że ​​kolor nie randomwystarcza XD
shrekuu

Losowo generujemy liczbę szesnastkową od 0do ffffff. Co jest idealnym równomiernym rozkładem . To zero służy jedynie do uzupełnienia ciągu, ze względu na względy użytkowania przeglądarki. Sugeruję, abyś bardziej uważał na to rozwiązanie.
Prostakov


Dzięki Prostakov. : D
shrekuu


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.