我想创建一个函数,它将接受任何旧字符串(通常是一个单词),并从中以某种方式生成一个十六进制值在#000000和#FFFFFF之间,所以我可以使用它作为HTML元素的颜色。
如果不那么复杂的话,甚至可能是一个简化的十六进制值(例如:#FFF)。事实上,“网络安全”调色板中的颜色是最理想的。
我想创建一个函数,它将接受任何旧字符串(通常是一个单词),并从中以某种方式生成一个十六进制值在#000000和#FFFFFF之间,所以我可以使用它作为HTML元素的颜色。
如果不那么复杂的话,甚至可能是一个简化的十六进制值(例如:#FFF)。事实上,“网络安全”调色板中的颜色是最理想的。
当前回答
在看了相当密集的代码和相当古老的答案之后,我想我应该从2021年的角度来回顾这个问题,只是为了好玩,希望对任何人都有用。现在有了HSL颜色模型和加密API在几乎所有浏览器(当然除了IE)中实现,它可以像这样简单地解决:
async function getColor(text, minLightness = 40, maxLightness = 80, minSaturation = 30, maxSaturation = 100) { let hash = await window.crypto.subtle.digest("SHA-1", new TextEncoder().encode(text)); hash = new Uint8Array(hash).join("").slice(16); return "hsl(" + (hash % 360) + ", " + (hash % (maxSaturation - minSaturation) + minSaturation) + "%, " + (hash % (maxLightness - minLightness) + minLightness) + "%)"; } function generateColor() { getColor(document.getElementById("text-input").value).then(color => document.querySelector(".swatch").style.backgroundColor = color); } input { padding: 5px; } .swatch { margin-left: 10px; width: 28px; height: 28px; background-color: white; border: 1px solid gray; } .flex { display: flex; } <html> <body> <div class="flex"> <form> <input id="text-input" type="text" onInput="generateColor()" placeholder="Type here"></input> </form> <div class="swatch"></div> </div> </body> </html>
这应该比手动生成散列快得多,并且还提供了一种定义饱和度和亮度的方法,以防你不想要太平或太亮或太暗的颜色(例如,如果你想在这些颜色上写文本)。
其他回答
只是将Java从Compute的十六进制颜色代码任意字符串移植到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
例子:
http://jsfiddle.net/sUK45/
(另一种/更简单的解决方案可能涉及返回'rgb(…)'风格的颜色代码。)
下面是另一个尝试:
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;
}
在看了相当密集的代码和相当古老的答案之后,我想我应该从2021年的角度来回顾这个问题,只是为了好玩,希望对任何人都有用。现在有了HSL颜色模型和加密API在几乎所有浏览器(当然除了IE)中实现,它可以像这样简单地解决:
async function getColor(text, minLightness = 40, maxLightness = 80, minSaturation = 30, maxSaturation = 100) { let hash = await window.crypto.subtle.digest("SHA-1", new TextEncoder().encode(text)); hash = new Uint8Array(hash).join("").slice(16); return "hsl(" + (hash % 360) + ", " + (hash % (maxSaturation - minSaturation) + minSaturation) + "%, " + (hash % (maxLightness - minLightness) + minLightness) + "%)"; } function generateColor() { getColor(document.getElementById("text-input").value).then(color => document.querySelector(".swatch").style.backgroundColor = color); } input { padding: 5px; } .swatch { margin-left: 10px; width: 28px; height: 28px; background-color: white; border: 1px solid gray; } .flex { display: flex; } <html> <body> <div class="flex"> <form> <input id="text-input" type="text" onInput="generateColor()" placeholder="Type here"></input> </form> <div class="swatch"></div> </div> </body> </html>
这应该比手动生成散列快得多,并且还提供了一种定义饱和度和亮度的方法,以防你不想要太平或太亮或太暗的颜色(例如,如果你想在这些颜色上写文本)。
这个函数很有用。这是一个改编,相当长的执行这个repo ..
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('')}`;
}