Випадковий генератор кольорів


440

З огляду на цю функцію, я хочу замінити колір на генератор випадкових кольорів.

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

Як я можу це зробити?


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


2
@SepehrM, коли випадкові результати повертаються, 0.001то результат "#4189"(недійсний колір - 4 цифри)
Kamil Kiełczewski

Це дуже приємне рішення, для мене дуже корисне github.com/davidmerfield/randomColor
maikelm

5
'#'+Math.random().toString(16).substr(2,6) (джерело: CodeGolf )
ashleedawg

Відповіді:


1018

Використання getRandomColor()замість "#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
Зауважте, що це має ухил до досить темних та ненасичених кольорів через те, як RGB обертає кольоровий простір. У Martin Ankerl є чудова стаття про генерування кольорів з інших просторів (наприклад, HSV): martin.ankerl.com/2009/12/09/…
Thomas Ahle

13
Шанси влучити 0 або 15 при використанні Math.round(Math.random()*15)лише 1:30, тоді як інші цифри - 1:15.
користувач123444555621

3
Ви можете видалити .split ('') виклик. У рядку вже є індексатор масиву.
ujeenator

3
Ви також можете використовувати функцію генератора як таку
tsuz

5
Цей код кульгавий. Ось онлінер: Math.floor (Math.random () * 16777215) .toString (16)
DDD

269

Сумніваюся, що все буде швидше або коротше, ніж це:

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

Виклик!


18
Ви забули прокладати нулі.
користувач123444555621

144
'#'+(Math.random()*0xFFFFFF<<0).toString(16);
Мохсен

15
@Mohsen, FYI раз у раз ваш код видає недійсний 5-значний номер
rochal

6
Результат не зафіксований до 6 цифр
Taha Jahangir

33
('00000'+(Math.random()*(1<<24)|0).toString(16)).slice(-6)завжди повертає довжину 6. Хоча цей метод все ще (рідко) повертає невеликі цифри, які дають результати на кшталт 000cf4або 0000a7які трохи гакітні, я думаю. у цих випадках червоний компонент не сприяє випадковому забарвленню.
bryc

162

Ось ще одне питання щодо цієї проблеми.

Моєю метою було створити яскраві та виразні кольори. Щоб кольори були виразними, я уникаю використання генератора випадкових випадків і вибору кольорів "рівномірно розташованих" від веселки.

Це ідеально підходить для створення маркерів спливаючих вікон на Картах Google, які мають оптимальну «унікальність» (тобто жоден два маркери не матимуть подібних кольорів).

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

Якщо ви хочете побачити, як це виглядає в дії, дивіться http://blog.adamcole.ca/2011/11/simple-javascript-rainbow-color.html .


7
Я шукав щось подібне! Чудові речі!
Хой

Я зробив спрощену реалізацію тієї самої ідеї, що і відповідь на подібне запитання stackoverflow.com/a/14187677/421010
Андрій

16
То яке значення буде параметром?
Ekramul Hoque

2
Я також створив щось подібне, але це досить випадково і досить виразно. Псевдокод тут . Він використовує hsv, а не rgb, тому що hsv має набагато більш передбачувану поведінку. Якщо ви хочете побачити реалізацію Python, я використовував її тут і тут . Вам доведеться шукати код "колір".
zondo

1
@RobertMolina: Вибачте, я перемістив свої речі до Gitlab. Псевдокод зараз тут , з проектами тут і тут .
zondo

56

Хто може це перемогти?

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

Гарантовано працювати весь час: http://jsbin.com/OjELIfo/2/edit

На підставі коментаря @eterps, наведений вище код все ще може генерувати більш короткі рядки, якщо шістнадцяткове подання випадкового кольору дуже коротке ( 0.730224609375=> 0.baf)

Цей код повинен працювати у всіх випадках:

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

12
Коли Math.random () повертає 0,022092682472568126, цей код створює недійсну рядок "# 5a7dd". божевільний!
rochal

Як ця, оскільки #ffffff не з’являється занадто часто.
Warface

Існує досить багато випадків, коли це не вийде. Перевірте наступний вихід для Math.random () ... 0.730224609375, 0.43603515625, 0.957763671875, і список продовжується ...
eterps

@eterps Це НЕ належні випадкові числа ! Див сирого IEEE 754 подвійний в шістнадцятковому: 0.730224609375 = 0x3fe75e0000000000, 0.43603515625 = 0x3fdbe80000000000, 0.957763671875 = 0x3feea60000000000. Ледь не використовується будь-яка з мантій! Вони просто прославлені дроби. Власне '12 цифра »результат буде давати результати , як:0.347876714234 = 0x3fd6439cb1ab32ac, 0.447556256665 = 0x3fdca4c2ff5fc450
БРІКу

Починаючи з 2015 року, я вважаю, що багато веб-браузерів замінили хитрі PRNG, які використовуються під кришкою Math.random()( для яких я маю припустити, що відповідає за результати @ etertp), на кращі, тому ці типи випадкових чисел низької якості повинні бути минулим. зараз.
bryc

29

Немає потреби в хеш-шістнадцяткових буквах. JavaScript може зробити це сам:

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

Ви також можете використовувати HSL, доступний у кожному хорошому браузері ( http://caniuse.com/#feat=css3-colors )

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

Це дасть вам лише яскраві кольори, ви можете пограти яскравістю, насиченістю та альфа.

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

Дякую! Мені вдалося отримати ідеальні кольори для фонів за допомогою:'hsla(' + (Math.floor(Math.random()*360) + ', 100%, 70%, 1)'
jj_

1
Жодної проблеми, я був здивований, коли ніхто не використовував силу hsl :)
kigiri

stackoverflow.com/a/23861752/1693593 , HSLA не потрібно його альфа = 1, просто використовувати HSL

1
Ви не можете генерувати 16-метровий колор таким чином (наприклад, ви ніколи не отримаєте біло-чорний відтінок сірого) - однак так - якщо ми використовуємо випадково кожен компонент, тоді ми отримуємо всі колядки hsl
Kamil Kiełczewski

1
+1 Це полегшує використання легкості та насиченості для встановлення випадкових кольорів фону, гарантуючи, що текст завжди читається
Освальдо Марія,

27

Мені подобається цей: '#' + (Math.random().toString(16) + "000000").substring(2,8)


Або'#' + Math.floor(Math.random()*16777215).toString(16);
Мохаммед Аніні

@MohammadAnin, який має шанси 1 на 16 створити менше 6 цифр
Джеймс

1
Це може генерувати недійсні кольори. Наприклад '#' + (0.125).toString(16).substring(2, 8) === '#2'. Це небезпечно, оскільки ймовірність низька (1 на 4096, я думаю), тому помилка, ймовірно, потрапить через тестування. Вам слід ('#' + Math.random().toString(16) + "000000").substring(2, 8)
Джеймс

Виправлення: має бути'#' + (Math.random().toString(16) + "000000").substring(2,8)
Джеймс

25

Випадкове генерація кольорів з регулюванням яскравості:

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
Дуже круто, хоча в основному створює «пастелі», а не яскравіші кольори, на які я сподівався, побачивши яскравість. Все ще заходжу в мій трюк!
JayCrossler

Мені це дуже подобається, тому що ви можете налаштувати його так, щоб він відповідав кольоровій палітрі веб-сайту
Емануель Джаніко

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

Мені це подобається за її розбірливість
hitautodestruct

1
якщо Math.random()повернення, 0.125то результат буде #0.2(недійсний колір) (вам потрібно додати трохи
накладки

18

Стаття, написана Полом Ірландським про генератор випадкових шістнадцяткових кольорових кодів на JavaScript, абсолютно дивовижна. Використання:

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

Ось джерело посилання:

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


5
це колись поверне не добре сформовані значення кольору, наприклад "1fa4c" (потрібно 3 або 6 символів)
jj_

1
@jj_ це? шкода, що я цього не помітив. Дякуємо, що поділилися
way2vin

коли випадкове повернення 0.00001тоді результат #a7(недійсний колір)
Kamil Kiełczewski

1
'#' + Math.floor(Math.random()*16777215).toString(16).padStart(6, '0')
Хайтам

17

Ось поворот у вирішенні, яке надає @Anatoliy.

Мені потрібно було генерувати лише світлі кольори (для фонів), тому я перейшов у форматі трьох літер (#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;
}

Я думаю, що це, ймовірно, дає найчастіше кольори, близькі, хоча і світлі. Що стосується більш рідкого діапазону випадкових кольорів, я думаю, @ відповідь Анатолія краща здебільшого
larrytech

15

Якщо ви такий нобій, як я, не знаю про шістнадцяткові знаки та інше, це може бути більш інтуїтивно зрозумілим.

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

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

Вам просто потрібно закінчити такий рядок, як 'rgb(255, 123, 220)'


ця відповідь повинна бути першою
Гіл Епштейн

Вам доведеться використовувати 256, щоб отримати 0.
Ліза Черіллі

13

Це можна легко знайти за допомогою Пошуку 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;
    }
}

Оновлена ​​версія:

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
Можливо, так; але на якому веб-сайті ви б не хотіли можливих надходжень від Google Adwords? =)
Девід каже повернути Моніку

2
який веб-сайт дає відповідь? якщо вони дадуть вам відповідь, вони повинні отримати хіти.
Funky Dude

1
@FunkyDude зараз цей результат - найкращий в Google, і причина того, що існує
stackoverflow


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

Розбиття, як це працює:

Math.random()*256отримує випадкове (плаваюча точка) число від 0 до 256 (від 0 до 255 включно)
Приклад результату: 116.15200161933899

Додавання |0смужок все після десяткової крапки.
Наприклад: 116.15200161933899 -> 116

Використання .toString(16)перетворює це число у шістнадцятковий (основа 16).
Наприклад: 116 -> 74
Ще один приклад: 228 -> e4

Додавши "0"прокладки до нуля. Це буде важливо, коли ми отримаємо підрядку, оскільки наш кінцевий результат повинен мати два символи для кожного кольору.
Наприклад: 74 -> 074
Ще один приклад: 8 -> 08

.substr(-2)отримує лише останні два символи.
Наприклад: 074 -> 74
Ще один приклад: 08 -> 08 (якби ми не додали "0", це дало б "8" замість "08")

forЦикл виконується в цьому циклі три рази, додаючи кожен результат в рядок кольору, створюючи що - щось на зразок цього:
#7408e4


Ви повинні конкретизувати свою відповідь.
жарт

8

Тому, хоча всі відповіді тут хороші, я хотів трохи більше контролювати результат. Наприклад, я хотів би запобігти будь-які майже білі відтінки, домагаючись того, щоб я отримав яскраві яскраві кольори, а не вимиті відтінки.

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

Тож тепер я можу вказати 3 довільних діапазони для вибору значень rgb. Ви можете викликати це без аргументів і отримати мій набір за замовчуванням, який, як правило, генерує досить яскравий колір з колись очевидним домінуючим відтінком, або ви можете надати свій власний масив діапазонів.


1
API Google Map підтримує лише шістнадцятковий колір у форматі "#FFFFFF".
Валерій Вікторовський

Зрозуміло, досить просто перетворити число в шістнадцятковий n.toString (16) лише забій - вам знадобиться нульовий майданчик, щоб переконатися, що ви отримаєте два символи повернення значення з внутрішньої функції g.
Оллі Едвардс

8

Голосований коментар верхньої відповіді говорить про те, що підхід Мартіна Анкерла кращий, ніж випадкові шістнадцяткові числа, і хоча я не вдосконалювався в методології Анкерла, я успішно переклав його на JavaScript. Я подумав, що опублікую додаткову відповідь на цю вже мегапоточну тему SO, тому що у верхній відповіді є ще один коментар, що посилається на Gist із реалізацією JS-логіки Ankerl, і це посилання розірвано (404). Якби у мене була репутація, я б просто прокоментував створене мною посилання 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

Для гідної випадковості.

Випадковий колір

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

Випадкова альфа, випадковий колір.

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

7

Є так багато способів, як ви можете це досягти. Ось я зробив:

Створює шість випадкових шістнадцяткових цифр (0-F)

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

Надзвичайно короткий однолінійний

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

Створює окремі компоненти 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;
}

Шестнадцятковий шістнадцятковий рядок (XOR 3 виходи разом для формування кольору)

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 short one-liner: коли випадкові повернення 0.125тоді результат #0.2(недійсний колір)
Kamil Kiełczewski

@ KamilKiełczewski 0.125= 3FC0000000000000в шістнадцятковій IEEE. 3 шістнадцяткові цифри є експонентами, 13 - мантіссами. Є ймовірність 1 на 4,5 квадрильона, що мантіса повністю порожня. Я тестував 100 м разів у Firefox / Chrome. Ви просто намагаєтесь її зламати;). ніколи неMath.random повинен давати вам 0,125. І якщо це станеться, є проблема з PRNG, що не є моєю проблемою. Дроби, такі як 0,5, 0,25, 0,0625 тощо, марні, вони не містять випадковості. Можливо, у вас є рішення цього крайнього крайнього випадку, гм? ;)
bryc

так, '#'+Math.random().toString(16).split('.')[1].slice(-6).padStart(6,0)але я вважаю за краще це
Kamil Kiełczewski

6

Ще один генератор випадкових кольорів:

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 робить його дуже чистим.

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

Потрібна шина для старих браузерів.


у хромованій консолі завжди повертаються # 000000
Kamil Kiełczewski

6

Ви можете використовувати цю просту функцію

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

1
коли випадкове повернення 0.001отримує результат "#4189"(недійсний кольоровий 4 цифри)
Kamil Kiełczewski


5

Використовуйте різні кольори .

Він створює палітру візуально чітких кольорів.

чіткі кольори можна налаштувати:

  • Виберіть кількість кольорів у палітрі
  • Обмежте відтінок певним діапазоном
  • Обмежте кольоровість (насиченість) певним діапазоном
  • Обмежте світлоту на певний діапазон
  • Налаштуйте загальну якість палітри

3541 рядок коду ... де інші відповіді тут - 6-10 рядків ... Мене вразило, як хтось написав так багато рядків коду, щоб вибрати різні кольори ..
vsync

Вибір по-справжньому візуально виразних кольорів вимагає набагато більше математики, ніж просто випадковий генератор кольорів.
InternalFX

Я просто зробив це в 2 рядки .. модифікував цю функцію: stackoverflow.com/a/20129594/104380
VSync


Дякую, дуже цікава стаття. мій метод завжди забезпечує однакові кольори, а результати послідовні та відмінні. Я думаю, що в деяких ситуаціях вам можуть знадобитися справді випадкові, добре розподілені кольори, які досить людському оці.
vsync

3

Ось дві мої версії для генератора випадкових шістнадцяткових кодів


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

Ця функція перевершує інші відповіді двома способами:

Він намагається генерувати кольори якомога виразніше, знаходячи, який колір із 20 спроб має найдальшу евклідову відстань від інших у конусі HSV

Це дозволяє обмежити відтінок, насиченість або діапазон значень, але все ж намагається підібрати кольори максимально чітко в межах цього діапазону.

Це не надто ефективно, але для розумних значень (хто навіть міг легко підібрати 100 кольорів?) Це досить швидко.

Див. 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

Майже всі попередні методи короткої руки генерують недійсні шістнадцяткові коди (п'ять цифр). Я натрапив на аналогічні технік тільки без цього питання тут :

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

Тест

Спробуйте це в консолі:

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

4
Я зробив цикл for-циклу, який запустив цей код 20000 разів і надрукував на консолі лише, якщо довжина була меншою за 7, і я знайшов випадок, коли рядок був менше 6 символів. Крім того, одна проблема з цим кодом полягає в тому, що він вкладає лише весь 6-розрядний рядок, а не окремі двоцифрові кольорові коди, а це означає, що ви, швидше за все, матимете нулі в червоному значенні, ніж у значенні зеленого або синього.
Ерін Хеймінг

коли випадкове повернення 0.00001отримує результат "#000a7"(недійсний колір - 5 цифр)
Kamil Kiełczewski

3

Моя версія:

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

Я думаю, що невипадковість 0робить колір randomнедостатньо XD
shrekuu

Ми згенеруємо гексадецинальне число від 0до ffffff. Що є ідеальним рівномірним розподілом . Цей нуль є лише для завершення рядка через міркування використання браузера. Я пропоную вам уважніше поставитися до цього рішення.
Простаков

Я вніс кілька коригувань, але не пов’язаних із вашим коментарем :)
Простаков

Спасибі Простаков. : D
шрекуу


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.