2013-07-24 2 views
14

У меня есть таблица действий в моем приложении. Я хочу назначить строки случайным цветом на основе идентификатора sessionID этой записи, чтобы помочь увидеть шаблоны/сгруппированные действия.Преобразование случайной строки в шестнадцатеричный цвет

меня это до сих пор:

console.log(stringToColorCode('mj3bPTCbIAVoNr93me1I')); 

function stringToColorCode(str) { 
    return '#'+ ('000000' + (Math.random()*0xFFFFFF<<0).toString(16)).slice(-6); 
} 

Однако мне нужно заменить Math.random() с моей строки-целое число, есть какие-либо методы для преобразования строки в случайное число, которое остается неизменным с случайная строка?

+0

Может быть, я не понимаю, но не '0xFFFFFF << 0' так же, как '0xFFFFFF'? – GolezTrol

+1

@ Обзор GolezTrol [приоритет оператора] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FOperators%2FOperator_Precedence): продукт происходит первым, поэтому << 0 по существу сводится к 32-битовому целому числу – SheetJS

+0

Итак, это литье, замаскированное под операцию с битрейтом? Хороший трюк, но почему бы не использовать Math.Floor или что-то в этом роде? – GolezTrol

ответ

11
var color_codes = {}; 
function stringToColorCode(str) { 
    return (str in color_codes) ? color_codes[str] : (color_codes[str] = '#'+ ('000000' + (Math.random()*0xFFFFFF<<0).toString(16)).slice(-6)); 
} 
+6

Это хорошо работает, но не на перезагрузке страницы. Страница будет выглядеть по-разному при каждой загрузке. В вопросе не указывалось, нужно ли быть согласованным при загрузке, поэтому это может сработать для нужд опроса. –

+1

ah хранение случайного гексагона в объекте - это простое, но эффективное решение, спасибо! – Titan

2

Сладкий вопрос. То, что я сделал, это создать глобальную переменную, чтобы вы могли последовательно получить один и тот же цвет для заданной входной строки. Как только вы вызываете stringToColorCode, он будет генерировать только случайный цвет для этой строки ONCE. Вы можете полагаться на это, чтобы быть последовательным, так что, если вы вызовете функцию назад к одной и той же строке, она вернет тот же случайный цвет. Только недостаток, который я вижу, состоит в том, что возможно (но маловероятно), что две разные строки могут быть сопоставлены одному и тому же цвету, но при необходимости их можно было бы обработать.

Редактировать: Когда я впервые ответил, я не понял, что @Nirk имел практически тот же ответ. Чтобы сделать это немного более уникальным, используйте это, которое даст вам согласованные цвета для перезагрузки страниц.

console.log(stringToColorCode('mj3bPTCbIAVoNr93me1I')); 

function stringToColorCode(str) { 
    var sessionStoreKey = "myStringColors" + str; 
    if (!sessionStorage[sessionStoreKey ]) { 
     sessionStorage[sessionStoreKey] = Math.random()*0xFFFFFF<<0;  
    } 

    var randomColor = sessionStorage[sessionStoreKey]; 

    return '#'+ randomColor; 
} 
+0

Вам не следует использовать массив для этой цели; btw @Nirk halready имеет такое же решение :-) – Bergi

+0

Великие умы думают одинаково! –

+0

Я понимаю, что я (вводящий в заблуждение) объявлял stringTorandomColorMap как [], но я не просто устанавливаю свойства объекта stringToRandomColorMap, когда я это делаю? Аналогично этому: http://stackoverflow.com/questions/7068968/getting-a-custom-objects-properties-by-string-var. Вы все еще думаете, что я неправильно использую массив? Если так, я хотел бы услышать, почему. Благодаря! –

15

As requested, отправляю это как awswer

var stringHexNumber = (      // 1 
    parseInt(        // 2 
     parseInt('mj3bPTCbIAVoNr93me1I', 36) // 3 
      .toExponential()     // 4 
      .slice(2,-5)      // 5 
    , 10) & 0xFFFFFF       // 6 
).toString(16).toUpperCase(); // "32EF01"  // 7 

Итак, что происходит?

  1. Вещи начинают на линии 3 где 'mj3bPTCbIAVoNr93me1I' получает преобразуется в Integer, скажем x, интерпретируя его как номер базы-36.
  2. Далее, x Поставляется в экспоненциальной форме как Строка on line 4. Это связано с тем, что с этим количеством символов x может быть огромным, этот пример составляет около 8e30, поэтому преобразуйте его в форму, которая будет довольно стандартной.
  3. После этого строка 5 обрезает начало и конец, поэтому вы останетесь только с цифрами, например. '8.123e+30'.slice(2, -5) становится '12'.
  4. Теперь мы вернемся к линии 2, где это преобразуется обратно в Integer снова, на этот раз в базе 10.
  5. Затем линия 6 обрезает это число вплоть до диапазона 0..16777215 (=== 0xFFFFFF), используя быстрый побитовое И. Это также преобразует NaN в 0.
  6. Наконец, строка 7 преобразует это обратно в формат шестиугольника в верхнем регистре, который мы используем для просмотра цветов, путем записи номера в базе 16 и смены корпуса.

Если вы хотите использовать это, вы также можете гарантировать, что окончательное число 6 цифр и воткнуть # на фронте, что может быть сделано с помощью

'#' + ('000000' + stringHexNumber).slice(-6); // "#32EF01" 
+0

Ничего себе, это орехи! :-) +1 –

+2

Пара разъяснений для нас, которые не сразу перескочили к этому интересному выводу :). Я узнал, что base-36 имеет имя: hexatridecimal system. Это особый случай, потому что его можно легко представить с помощью 0-9A-Z, поэтому parseInt (sessionID, 36) - предполагает, что sessionID является буквенно-цифровым. После вызова toExponential() выполняется срез (2, -5). Начинается с 2, чтобы пройти мимо первой десятичной точки, заканчивается на -5 с конца, потому что экспоненциальный может иметь 5 символов - max - e + 307, после этого toExponential() возвращает Infinity. –

-1

Я решил это на бэк-бэк. Это работает для меня в Java:

private void createDefaultColorFromName(final String name) { 
    String md5 = "#" + md5(name).substring(0, 6); 
    defaultColor = Color.decode(md5); 
    int darkness = ((defaultColor.getRed() * 299) + (defaultColor.getGreen() * 587) + (defaultColor.getBlue() * 114))/1000; 
    if (darkness > 125) { 
     defaultColor = defaultColor.darker(); 
    } 
} 

Я сделал сгенерированного цвет немного темнее на белом фоне ...

+0

Это не дает ответа на вопрос.Чтобы критиковать или просить разъяснения у автора, оставьте комментарий ниже их сообщения. –

+0

@SantoshA: Я просто написал свое решение для аналогичной проблемы! Что в этом плохого?? – Gatschet

Смежные вопросы