Создание шестнадцатеричного цвета на основе строки с помощью JavaScript
Я хочу создать функцию, которая принимает любую старую строку (обычно одно слово) и от как-то создать шестнадцатеричное значение между #000000
и #FFFFFF
, поэтому я могу использовать его в качестве цвета для элемента HTML.
может быть, даже сокращенное шестнадцатеричное значение (например:#FFF
) если это не так сложно. На самом деле, цвет из веб-безопасной палитры было бы идеально.
11 ответов:
просто портирование Java из вычислить шестнадцатеричный цветовой код для произвольной строки на Javascript:
function hashCode(str) { // java String#hashCode var hash = 0; for (var i = 0; i < str.length; i++) { hash = str.charCodeAt(i) + ((hash << 5) - hash); } return hash; } function intToRGB(i){ var c = (i & 0x00FFFFFF) .toString(16) .toUpperCase(); return "00000".substring(0, 6 - c.length) + c; }
для преобразования вы бы сделали:
intToRGB(hashCode(your_string))
вот адаптация ответа CD Sanchez, который последовательно возвращает 6-значный цветовой код:
var stringToColour = function(str) { var hash = 0; for (var i = 0; i < str.length; i++) { hash = str.charCodeAt(i) + ((hash << 5) - hash); } var colour = '#'; for (var i = 0; i < 3; i++) { var value = (hash >> (i * 8)) & 0xFF; colour += ('00' + value.toString(16)).substr(-2); } return colour; }
использование:
stringToColour("greenish"); // -> #9bc63b
пример:
(альтернативное / более простое решение может включать возврат ' rgb(...)'-стиль цветовой код.)
Я хотел подобное богатство цветов для HTML-элементов, я был удивлен, обнаружив, что CSS теперь поддерживает цвета hsl (), поэтому полное решение для меня ниже:
см. Также как автоматически генерировать N "различных" цветов? для большего количества альтернатив, более похожих на это.
function colorByHashCode(value) { return "<span style='color:" + value.getHashCode().intToHSL() + "'>" + value + "</span>"; } String.prototype.getHashCode = function() { var hash = 0; if (this.length == 0) return hash; for (var i = 0; i < this.length; i++) { hash = this.charCodeAt(i) + ((hash << 5) - hash); hash = hash & hash; // Convert to 32bit integer } return hash; }; Number.prototype.intToHSL = function() { var shortened = this % 360; return "hsl(" + shortened + ",100%,30%)"; };
в HSL его оттенок, насыщенность, легкость. Таким образом, оттенок между 0-359 получит все цвета, насыщенность-это то, насколько богатый вы хотите цвет, 100% работает для меня. И легкость определяет глубина, 50% нормально, 25% темные цвета, 75% пастельные. У меня есть 30%, потому что он лучше всего подходит к моей цветовой гамме.
Я считаю, что генерация случайных цветов имеет тенденцию создавать цвета, которые не имеют достаточного контраста на мой вкус. Самый простой способ я нашел, чтобы обойти это, чтобы предварительно заполнить список очень разных цветов. Для каждого новая строка, назначить следующий цвет в списке:
// Takes any string and converts it into a #RRGGBB color. var StringToColor = (function(){ var instance = null; return { next: function stringToColor(str) { if(instance === null) { instance = {}; instance.stringToColorHash = {}; instance.nextVeryDifferntColorIdx = 0; instance.veryDifferentColors = ["#000000","#00FF00","#0000FF","#FF0000","#01FFFE","#FFA6FE","#FFDB66","#006401","#010067","#95003A","#007DB5","#FF00F6","#FFEEE8","#774D00","#90FB92","#0076FF","#D5FF00","#FF937E","#6A826C","#FF029D","#FE8900","#7A4782","#7E2DD2","#85A900","#FF0056","#A42400","#00AE7E","#683D3B","#BDC6FF","#263400","#BDD393","#00B917","#9E008E","#001544","#C28C9F","#FF74A3","#01D0FF","#004754","#E56FFE","#788231","#0E4CA1","#91D0CB","#BE9970","#968AE8","#BB8800","#43002C","#DEFF74","#00FFC6","#FFE502","#620E00","#008F9C","#98FF52","#7544B1","#B500FF","#00FF78","#FF6E41","#005F39","#6B6882","#5FAD4E","#A75740","#A5FFD2","#FFB167","#009BFF","#E85EBE"]; } if(!instance.stringToColorHash[str]) instance.stringToColorHash[str] = instance.veryDifferentColors[instance.nextVeryDifferntColorIdx++]; return instance.stringToColorHash[str]; } } })(); // Get a new color for each string StringToColor.next("get first color"); StringToColor.next("get second color"); // Will return the same color as the first time StringToColor.next("get first color");
в то время как это имеет предел только 64 цветов, я считаю, что большинство людей не могут действительно сказать разницу после этого в любом случае. Я полагаю, вы всегда можете добавить больше цветов.
хотя этот код использует жестко закодированные цвета, вы, по крайней мере, гарантированно знаете во время разработки, сколько контраста вы увидите между цветами в производстве.
список цветов был снят с это так ответ есть и другие списки с большим количеством цветов.
Если ваши входные данные недостаточно отличаются для простого хэша, чтобы использовать весь цветовой спектр, вы можете использовать генератор случайных чисел вместо хэш-функции.
Я использую цветовой кодер из ответа Джо Фримена, и генератор случайных чисел Дэвида Бау.
function stringToColour(str) { Math.seedrandom(str); var rand = Math.random() * Math.pow(255,3); Math.seedrandom(); // don't leave a non-random seed in the generator for (var i = 0, colour = "#"; i < 3; colour += ("00" + ((rand >> i++ * 8) & 0xFF).toString(16)).slice(-2)); return colour; }
еще одно решение для случайных цветов:
function colorize(str) { for (var i = 0, hash = 0; i < str.length; hash = str.charCodeAt(i++) + ((hash << 5) - hash)); color = Math.floor(Math.abs((Math.sin(hash) * 10000) % 1 * 16777216)).toString(16); return '#' + Array(6 - color.length + 1).join('0') + color; }
это смешанные вещи, которые делают работу за меня. Я использовал хэш-функцию JFreeman (также ответ в этом потоке) и псевдослучайную функцию Asykäri от здесь и некоторые дополнения и математику от себя.
Я сомневаюсь, что функция производит равномерно распределенные цвета, хотя она выглядит красиво и делает то, что она должна делать.
Я только что построил функцию, которая соответствует счету, пожалуйста.js, он все еще не слились с основным РЕПО, Но вы можете увидеть его здесь:
https://github.com/ibarrajo/PleaseJS
вы можете сопоставить строку с цветом так:
var color = Please.make_color({from_hash: 'any string goes here'});
"any string goes here"
возврат"#47291b"
и"another!"
возвращает как"#1f0c3d"
вот решение, которое я придумал для создания эстетически приятных пастельных цветов на основе входной строки. Он использует первые два символа строки как случайное семя, а затем генерирует R/G/B на основе этого семени.
его можно легко расширить, чтобы семя было XOR всех символов в строке, а не только первых двух.
вдохновленный ответом Дэвида Кроу здесь:алгоритм для случайного создания эстетически приятного цвета палитра
//magic to convert strings to a nice pastel colour based on first two chars // // every string with the same first two chars will generate the same pastel colour function pastel_colour(input_str) { //TODO: adjust base colour values below based on theme var baseRed = 128; var baseGreen = 128; var baseBlue = 128; //lazy seeded random hack to get values from 0 - 256 //for seed just take bitwise XOR of first two chars var seed = input_str.charCodeAt(0) ^ input_str.charCodeAt(1); var rand_1 = Math.abs((Math.sin(seed++) * 10000)) % 256; var rand_2 = Math.abs((Math.sin(seed++) * 10000)) % 256; var rand_3 = Math.abs((Math.sin(seed++) * 10000)) % 256; //build colour var red = Math.round((rand_1 + baseRed) / 2); var green = Math.round((rand_2 + baseGreen) / 2); var blue = Math.round((rand_3 + baseBlue) / 2); return { red: red, green: green, blue: blue }; }
суть здесь:https://gist.github.com/ro-sharp/49fd46a071a267d9e5dd
С помощью
hashCode
как в ответе Кристиана Санчеса сhsl
и современный javascript, вы можете создать палитру цветов с хорошим контрастом, как это:function hashCode(str) { let hash = 0; for (var i = 0; i < str.length; i++) { hash = str.charCodeAt(i) + ((hash << 5) - hash); } return hash; } function pickColor(str) { return `hsl(${hashCode(str) % 360}, 100%, 80%)`; } one.style.backgroundColor = pickColor(one.innerText) two.style.backgroundColor = pickColor(two.innerText)
div { padding: 10px; }
<div id="one">One</div> <div id="two">Two</div>
так как это hsl, вы можете масштабировать яркость, чтобы получить контраст, который вы ищете.
function hashCode(str) { let hash = 0; for (var i = 0; i < str.length; i++) { hash = str.charCodeAt(i) + ((hash << 5) - hash); } return hash; } function pickColor(str) { // Note the last value here is now 50% instead of 80% return `hsl(${hashCode(str) % 360}, 100%, 50%)`; } one.style.backgroundColor = pickColor(one.innerText) two.style.backgroundColor = pickColor(two.innerText)
div { color: white; padding: 10px; }
<div id="one">One</div> <div id="two">Two</div>
вот еще одна попытка:
function stringToColor(str){ var hash = 0; for(var i=0; i < str.length; i++) { hash = str.charCodeAt(i) + ((hash << 3) - hash); } var color = Math.abs(hash).toString(16).substring(0, 6); return "#" + '000000'.substring(0, 6 - color.length) + color; }
эта функция делает трюк. Это адаптация этого, довольно длинная реализация этот РЕПО ..
const color = (str) => { let rgb = []; // Changing non-hexadecimal characters to 0 str = [...str].map(c => (/[0-9A-Fa-f]/g.test(c)) ? c : 0).join(''); // Padding string with zeroes until it adds up to 3 while (str.length % 3) str += '0'; // Dividing string into 3 equally large arrays for (i = 0; i < str.length; i += str.length / 3) rgb.push(str.slice(i, i + str.length / 3)); // Formatting a hex color from the first two letters of each portion return `#${rgb.map(string => string.slice(0, 2)).join('')}`; }