使用 JavaScript 创建基于字符串的十六进制颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/3426404/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Create a hexadecimal colour based on a string with JavaScript
提问by Darragh Enright
I want to create a function that will accept any old string (will usually be a single word) and from that somehowgenerate a hexadecimal value between #000000and #FFFFFF, so I can use it as a colour for a HTML element. 
我想创建一个函数,该函数将接受任何旧字符串(通常是一个单词),并从中以某种方式在#000000和之间生成一个十六进制值#FFFFFF,因此我可以将其用作 HTML 元素的颜色。
Maybe even a shorthand hex value (e.g: #FFF) if that's less complicated. In fact, a colour from a 'web-safe' palette would be ideal.
#FFF如果不那么复杂,甚至可能是一个速记十六进制值(例如:)。事实上,来自“网络安全”调色板的颜色将是理想的。
回答by Joe Freeman
Here's an adaptation of CD Sanchez' answer that consistently returns a 6-digit colour code:
这是 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;
}
Usage:
用法:
stringToColour("greenish");
// -> #9bc63b
Example:
例子:
(An alternative/simpler solution might involve returning an 'rgb(...)'-style colour code.)
(另一种/更简单的解决方案可能涉及返回“rgb(...)”样式的颜色代码。)
回答by Cristian Sanchez
Just porting over the Java from Compute hex color code for an arbitrary stringto Javascript:
只需将 Java 从任意字符串的 Compute hex color code移植到 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;
}
To convert you would do:
要转换你会这样做:
intToRGB(hashCode(your_string))
回答by Thymine
I wanted similar richness in colors for HTML elements, I was surprised to find that CSS now supports hsl() colors, so a full solution for me is below:
我想为 HTML 元素提供类似的丰富颜色,我惊讶地发现 CSS 现在支持 hsl() 颜色,所以我的完整解决方案如下:
Also see How to automatically generate N "distinct" colors?for more alternatives more similar to this.
另请参阅如何自动生成 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%)";
};
document.body.innerHTML = [
  "javascript",
  "is",
  "nice",
].map(colorByHashCode).join("<br/>");
span {
  font-size: 50px;
  font-weight: 800;
}
In HSL its Hue, Saturation, Lightness. So the hue between 0-359 will get all colors, saturation is how rich you want the color, 100% works for me. And Lightness determines the deepness, 50% is normal, 25% is dark colors, 75% is pastel. I have 30% because it fit with my color scheme best.
在 HSL 中,它的色相、饱和度、亮度。因此,0-359 之间的色调将获得所有颜色,饱和度是您想要的颜色的丰富程度,100% 适合我。而Lightness决定了深度,50%是正常的,25%是深色,75%是粉彩。我有 30%,因为它最适合我的配色方案。
回答by Rick Smith
I find that generating random colors tends to create colors that do not have enough contrast for my taste. The easiest way I have found to get around that is to pre-populate a list of very different colors. For every newstring, assign the next color in the list:
我发现生成随机颜色往往会产生对我的口味没有足够对比度的颜色。我发现解决这个问题的最简单方法是预先填充一个非常不同的颜色列表。对于每个新字符串,分配列表中的下一个颜色:
// 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");
While this has a limit to only 64 colors, I find most humans can't really tell the difference after that anyway. I suppose you could always add more colors.
虽然这仅限于 64 种颜色,但我发现大多数人无论如何都无法真正分辨出其中的区别。我想你总是可以添加更多的颜色。
While this code uses hard-coded colors, you are at least guaranteed to know during development exactly how much contrast you will see between colors in production.
虽然此代码使用硬编码颜色,但您至少可以保证在开发过程中确切知道生产中颜色之间的对比度。
Color list has been lifted from this SO answer, there are other lists with more colors.
颜色列表已从这个 SO answer 中删除,还有其他颜色更多的列表。
回答by Josue Alexander Ibarra
I have opened a pull requestto Please.jsthat allows generating a color from a hash.
我已经向Please.js打开了一个拉取请求,允许从哈希生成颜色。
You can map the string to a color like so:
您可以将字符串映射到一种颜色,如下所示:
const color = Please.make_color({
    from_hash: "any string goes here"
});
For example, "any string goes here"will return as "#47291b"
and "another!"returns as "#1f0c3d"
例如,"any string goes here"将返回为"#47291b"
并"another!"返回为"#1f0c3d"
回答by Nathan
If your inputs are not different enough for a simple hash to use the entire color spectrum, you can use a seeded random number generator instead of a hash function.
如果您的输入差异不足以使简单散列使用整个色谱,您可以使用种子随机数生成器而不是散列函数。
I'm using the color coder from Joe Freeman's answer, and David Bau's seeded random number generator.
我正在使用 Joe Freeman 的答案中的颜色编码器和David Bau 的种子随机数生成器。
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;
}
回答by estani
Yet another solution for random colors:
随机颜色的另一种解决方案:
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;
}
It's a mixed of things that does the job for me. I used JFreeman Hash function (also an answer in this thread) and Asyk?ri pseudo random function from hereand some padding and math from myself.
对我来说,这是一种混合的东西。我用JFreeman Hash函数(也是在这个线程的答案)和Asyk?里的伪随机函数从这里,并从自己的一些填充和数学。
I doubt the function produces evenly distributed colors, though it looks nice and does that what it should do.
我怀疑该功能会产生均匀分布的颜色,尽管它看起来不错并且可以做到它应该做的事情。
回答by Kyle Kelley
Using the hashCodeas in Cristian Sanchez's answer with hsland modern javascript, you can create a color picker with good contrast like this:
使用hashCodeCristian Sanchez 的答案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>
Since it's hsl, you can scale luminance to get the contrast you're looking for.
由于它是 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>
回答by Robert Sharp
Here's a solution I came up with to generate aesthetically pleasing pastel colours based on an input string. It uses the first two chars of the string as a random seed, then generates R/G/B based on that seed.
这是我想出的一个解决方案,用于根据输入字符串生成美观的柔和色彩。它使用字符串的前两个字符作为随机种子,然后根据该种子生成 R/G/B。
It could be easily extended so that the seed is the XOR of all chars in the string, rather than just the first two.
它可以很容易地扩展,以便种子是字符串中所有字符的异或,而不仅仅是前两个。
Inspired by David Crow's answer here: Algorithm to randomly generate an aesthetically-pleasing color palette
受 David Crow 在这里回答的启发:随机生成美观调色板的算法
//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 };
}
GIST is here: https://gist.github.com/ro-sharp/49fd46a071a267d9e5dd
要点在这里:https: //gist.github.com/ro-sharp/49fd46a071a267d9e5dd
回答by kikito
Here is another try:
这是另一个尝试:
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;
}

