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ć?

n00ki3
źródło
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>

Anatolij
źródło
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!

ZPiDER
źródło
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 .

Adam Cole
źródło
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;
}
Mohsen
źródło
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();
}
Alsciende
źródło
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)`
kigiri
źródło
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)

Nicolas Buduroi
źródło
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(",") + ")";
}
letronje
źródło
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
jt3k
źródło
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/

way2vin
źródło
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;
}
Andrei R.
źródło
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)'

ICoffeeConsumer
źródło
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;
  }
}
Funky Dude
źródło
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)

Taha Jahangir
źródło
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

Erin Heyming
źródło
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.

Ollie Edwards
źródło
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

spakmad
źródło
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)}`
Константин Ван
źródło
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);
}
bryc
źródło
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
Salman A.
źródło
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.

użytkownik1106925
źródło
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;
}
ChandrasekarG
źródło
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
InternalFX
źródło
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))

Larry Battle
źródło
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);
  }
Andy
źródło
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));
}
manikanta
źródło
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;
}
Prostakowa
źródło
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
Dokonałem
Dzięki Prostakov. : D
shrekuu
3

mapa (zwraca zawsze prawidłowy kolor rgb)

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

Kamil Kiełczewski
źródło
2

Za pomocą colorchain.js można wygenerować sekwencję kolorów o różnych odcieniach.

alexishacks
źródło