Генератор случайных цветов

441

Учитывая эту функцию, я хочу заменить цвет на генератор случайных цветов.

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

Как мне это сделать?

n00ki3
источник
31
'#' + Math.floor (Math.random () * 16777215) .ToString (16);
SepehrM
2
@SepehrM при случайном возврате, 0.001то результатом является "#4189"(недопустимый цвет - 4 цифры)
Камиль Килчевски
Это очень хорошее решение, для меня очень полезное github.com/davidmerfield/randomColor
maikelm
5
'#'+Math.random().toString(16).substr(2,6) (источник: CodeGolf )
ashleedawg

Ответы:

1019

Используйте 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 оборачивает цветовое пространство. У Мартина Анкерла есть хорошая статья о том, как генерировать цвета из других пространств (например, HSV): martin.ankerl.com/2009/12/09/…
Томас Ахле,
13
Шансы попасть в 0 или 15 при использовании Math.round(Math.random()*15)составляют только 1:30, в то время как шансы других чисел 1:15.
user123444555621
3
Вы можете удалить .split ('') вызов. У строки уже есть индексатор массива.
ujeenator
3
Вы также можете использовать функцию генератора как таковую
tsuz
5
Этот код хромает. Вот кто подписал: Math.floor (Math.random () * 16777215) .toString (16)
DDD
269

Я сомневаюсь, что все будет быстрее или короче, чем этот:

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

Вызов!

ZPiDER
источник
18
Вы забыли заполнить нулями.
user123444555621
144
'#'+(Math.random()*0xFFFFFF<<0).toString(16);
Мохсен
15
@Mohsen, FYI время от времени ваш код выдает неверный 5-значный номер
rochal
6
Результат не дополняется до 6 цифр
Таха Джахангир
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
Так что же будет значением параметра?
Экрамул Хок
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». сумасшедший!
Рочал
Как этот, так как #ffffff не появляется слишком часто.
Warface
Есть довольно много случаев, когда это не будет работать. Проверьте следующий вывод для Math.random () ... 0.730224609375, 0.43603515625, 0.957763671875, и этот список можно
продолжить
@eterps Это НЕ правильные случайные числа ! См сырого IEEE 754 двойной в шестнадцатеричном: 0.730224609375 = 0x3fe75e0000000000, 0.43603515625 = 0x3fdbe80000000000, 0.957763671875 = 0x3feea60000000000.Едва ли какая-нибудь мантисса используется! Они просто прославленные фракции. Собственно '12 цифра»результат будет давать результаты , как:0.347876714234 = 0x3fd6439cb1ab32ac, 0.447556256665 = 0x3fdca4c2ff5fc450
БРИКа
С 2015 года я полагаю, что многие веб-браузеры заменили дрянные PRNG, используемые под капотом Math.random()(которые, я должен предположить, отвечает за результаты @ etertp), на более качественные, поэтому такие типы случайных чисел низкого качества должны быть в прошлом. сейчас же.
БРИКа
30

Вы также можете использовать 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)`
kigiri
источник
Спасибо! Мне удалось получить идеальные цвета для фона с:'hsla(' + (Math.floor(Math.random()*360) + ', 100%, 70%, 1)'
jj_
1
Нет проблем, я был удивлен, увидев, что никто не использует силу hsl :)
Кигири
stackoverflow.com/a/23861752/1693593 , hsla не нужна, это alpha = 1, просто используйте hsl
1
Вы не можете генерировать 16 миллионов цветов таким образом (например, вы никогда не получите черно-белый цвет), однако да, если мы будем использовать случайные значения для каждого компонента, тогда мы получим все hsl corols
Камил Келчевский
1
+1 Это облегчает использование яркости и насыщенности, чтобы установить случайные цвета фона, гарантируя, что текст всегда
Освальдо Мария
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();
}
Alsciende
источник
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(",") + ")";
}
letronje
источник
1
Очень круто, хотя в основном генерирует «пастельные», а не более яркие цвета, на которые я надеялся, когда увидел яркость. Все еще собираюсь в мою сумку трюков!
Джей Кросслер
Мне очень нравится этот, потому что вы можете настроить его так, чтобы он гармонировал с цветовой палитрой вашего сайта
Эмануэль Джанико
20
'#'+Math.random().toString(16).slice(-3) // three-numbers format aka #f3c
'#'+Math.random().toString(16).slice(-6) // six-number format aka #abc123
jt3k
источник
Мне это нравится, потому что его удобочитаемость
hitautodestruct,
1
если Math.random()вернуть, 0.125то результатом будет #0.2(недопустимый цвет) (вместо среза нужно добавить отступы)
Камиль Килчевски
18

Статья Пола Айриша (Paul Irish) о генераторе кодов случайных шестнадцатеричных кодов на JavaScript просто потрясающая Использование:

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

Вот ссылка на источник:

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

way2vin
источник
5
это когда-нибудь вернет не правильно сформированные значения цвета, такие как "1fa4c" (должно быть 3 или 6 символов)
jj_
1
@jj_ это? извини, я этого не заметил. Спасибо, что поделились
way2vin
когда случайный возврат, 0.00001то результат #a7(неправильный цвет)
Камиль Келчевски
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)'

ICoffeeConsumer
источник
этот ответ должен быть самым лучшим
Джил Эпштейн
Вы должны использовать 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, и причина, по которой существует стекопоток, заключается в том, что он не использует Google слишком часто;)
Акшат
10

Короткий ответ с блокнотом до точного размера

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

Разбивка того, как это работает:

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
Google Map API поддерживает только шестнадцатеричный цвет HTML в формате "#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

spakmad
источник
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);
}
БРИКа
источник
экстремальный короткий однострочный: при случайном возврате 0.125результат #0.2(неправильный цвет)
Камиль Келчевски
@ 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)но я предпочитаю это
Камиль Келчевски
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)
}, "#")

Требуется прокладка для старых браузеров.

user1106925
источник
в хромированной консоли всегда возвращайся # 000000
Камиль Келчевски
6

Вы могли бы использовать эту простую функцию

function getRandomColor(){
 var color =  "#" + (Math.random() * 0xFFFFFF << 0).toString(16);
 return color;
}
ChandrasekarG
источник
1
когда случайный 0.001результат возвращает результат "#4189"(недопустимый цвет 4 цифры)
Камиль Килчевски
5

Используйте отличные цвета .

Он генерирует палитру визуально отличных цветов.

Отдельные цвета легко настраиваются:

  • Выберите, сколько цветов в палитре
  • Ограничить оттенок определенным диапазоном
  • Ограничить цветность (насыщенность) определенным диапазоном
  • Ограничьте легкость до определенного диапазона
  • Настройте общее качество палитры
InternalFX
источник
3541 строка кода ... где другие ответы здесь ~ 6-10 строк ... я впечатлен тем, как кто-то написал так много строк кода, чтобы выбрать разные цвета ..
vsync
Выбор действительно визуально отличных цветов требует намного больше математики, чем просто генератор случайных цветов.
InternalFX
Я просто сделал это в 2 строки .. изменил эту функцию: stackoverflow.com/a/20129594/104380
vsync
Это не так просто. Рекомендуемое чтение
InternalFX
Спасибо, очень интересная статья. Мой метод всегда дает одни и те же цвета, и результаты являются последовательными и отличительными. Я предполагаю, что в некоторых ситуациях вам могут понадобиться действительно случайные, хорошо распределенные цвета, симпатичные человеческому глазу.
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));
}
manikanta
источник
4
Я сделал цикл for, который запускал этот код 20000 раз и выводил на консоль только если длина была меньше 7, и я нашел случай, когда строка была менее 6 символов. Кроме того, одна проблема с этим кодом состоит в том, что он дополняет только всю 6-значную строку, а не отдельные 2-значные цветовые коды, что означает, что у вас больше шансов иметь нули в красном значении, чем в зеленом или синем.
Эрин Хейминг,
когда случайный 0.00001результат возвращает результат "#000a7"(неправильный цвет - 5 цифр)
Камиль Келчевски
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
shrekuu
2

Вы можете использовать colorchain.js для генерации последовательности цветов с различными оттенками.

alexishacks
источник