代码之家  ›  专栏  ›  技术社区  ›  Darragh Enright

使用javascript基于字符串创建十六进制颜色

  •  107
  • Darragh Enright  · 技术社区  · 15 年前

    我想创建一个接受任何旧字符串(通常是一个单词)的函数,并从中 以某种方式 在以下值之间生成十六进制值 #000000 #FFFFFF ,所以我可以将它用作HTML元素的颜色。

    甚至可能是一个简短的十六进制值(例如: #FFF )如果不那么复杂的话。事实上,“网络安全”调色板的颜色是理想的。

    11 回复  |  直到 7 年前
        1
  •  121
  •   Community Mohan Dere    8 年前

    只需移植Java Compute hex color code for an arbitrary string 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))
    
        2
  •  145
  •   Martin Tournoij ravi.zombie    9 年前

    以下是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(…)”样式的颜色代码。)

        3
  •  35
  •   bb216b3acfd8f72cbc8f899d4d6963 Josue Alexander Ibarra    7 年前

    我希望HTML元素的颜色具有类似的丰富性,我很惊讶地发现CSS现在支持hsl()颜色,因此我的完整解决方案如下:

    也看到 How to automatically generate N "distinct" colors? 更多类似的替代品。

    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;
    }

    在HSL中,它的色调、饱和度、亮度。所以0-359之间的色调会得到所有的颜色,饱和度是你想要的颜色有多丰富,100%适合我。亮度决定深度,50%为正常,25%为深色,75%为柔和。我有30%,因为它最适合我的配色方案。

        4
  •  8
  •   Community Mohan Dere    8 年前

    我发现生成随机颜色往往会产生没有足够对比度适合我口味的颜色。我找到的最简单的方法就是预先填充一个非常不同颜色的列表。对于每一个 新的 字符串,指定列表中的下一种颜色:

    // 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种颜色的限制,但我发现大多数人无论如何都不能分辨出颜色的不同。我想你总可以多加些颜色。

    虽然这段代码使用硬编码的颜色,但至少可以保证您在开发过程中确切知道在生产中颜色之间的对比度。

    颜色列表已从 this SO answer ,还有其他具有更多颜色的列表。

        5
  •  5
  •   Nathan    12 年前

    如果您的输入不足以让一个简单的哈希使用整个色谱,那么您可以使用种子随机数生成器而不是哈希函数。

    我用的是乔·弗里曼的答案中的颜色编码器, David Bau's seeded random number generator .

    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;
    }
    
        6
  •  5
  •   bb216b3acfd8f72cbc8f899d4d6963 Josue Alexander Ibarra    7 年前

    我已经打开 a pull request Please.js 允许从哈希生成颜色。

    您可以将字符串映射为这样的颜色:

    const color = Please.make_color({
        from_hash: "any string goes here"
    });
    

    例如, "any string goes here" 将返回 "#47291b"
    "another!" 返回为 "#1f0c3d"

        7
  •  4
  •   Community Mohan Dere    8 年前

    另一种随机颜色的解决方案是:

    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_i伪随机函数 here 还有我自己的一些填充物和数学。

    我怀疑函数是否能产生均匀分布的颜色,尽管它看起来很漂亮,而且它应该做到这一点。

        8
  •  4
  •   Community Mohan Dere    8 年前

    这是我提出的一个解决方案,基于输入字符串生成美观的柔和颜色。它使用字符串的前两个字符作为随机种子,然后基于该种子生成r/g/b。

    它可以很容易地扩展,以便种子是字符串中所有字符的XOR,而不仅仅是前两个字符。

    灵感来源于大卫·克劳的回答: Algorithm to randomly generate an aesthetically-pleasing color palette

    //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

        9
  •  2
  •   Kyle Kelley    7 年前

    使用 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”>一个</DIV>
    <DIV id=“two”>两个</DIV>
        10
  •  1
  •   kikito    11 年前

    下面是另一个尝试:

    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;
    }
    
        11
  •  0
  •   Theódór Ágúst Magnússon    7 年前

    这个函数起作用。这是对这个的一种适应,相当长的实施时间 this 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('')}`;
    }