JavaScriptで文字列に基づいて16進数の色を作成する


141

古い文字列(通常は1つの単語)を受け入れる関数を作成し、そこから何らかの方法で#000000との間の16進値を生成したい#FFFFFFので、HTML要素の色として使用できます。

#FFFそれほど複雑ではない場合は、省略された16進数値(例:)でもかまいません。実際、「Webセーフ」パレットの色が理想的です。


2
サンプル入力および/または同様の質問へのリンクを提供できますか?
qw3n 2010

2
答えではありませんが、次のことが役立つ場合があります。16進数を整数に変換するには、を使用しますparseInt(hexstr, 10)。整数を16進数に変換するには、を使用しますn.toString(16)。nは整数です。
クリスティアンサンチェス

@ qw3n-サンプル入力:「医学」、「手術」、「神経学」、「一般診療」などの短い、プレーンな古いテキスト文字列。3から20までの範囲で... :ここでもう一つが、はJavaの質問ですstackoverflow.com/questions/2464745/... 感謝- @Daniel。私は座って、これについて真剣に取り組む必要があります。役に立つかもしれません。
Darragh Enright 2010

回答:


176

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

変換するには、次のようにします。

intToRGB(hashCode(your_string))

1
すごい!おかげで、これはうまくいきます。ビット単位の演算子などについてはあまり知りませんので、移植にご協力いただければ幸いです。
Darragh Enright 2010

:それはのような、パッドに進文字列を必要とする("00" + ((this >> 24) & 0xFF).toString(16)).slice(-2) + ("00" + ((this >> 16) & 0xFF).toString(16)).slice(-2) + ("00" + ((this >> 8) & 0xFF).toString(16)).slice(-2) + ("00" + (this & 0xFF).toString(16)).slice(-2);
チミン

2
たくさんの音楽ジャンルタグを背景色に変換しているので、時間を大幅に節約できました。
カイルペネル2016

これをphpに変換できるといいのですが。
Nimitz E.

6
私は、例えば、類似文字列のため、ほぼ同じ色でいくつかの問題があります。 intToRGB(hashCode('hello1')) -> "3A019F" intToRGB(hashCode('hello2')) -> "3A01A0" そして、私は、最終的なハッシュ値のための乗算を追加することで、あなたのコードを強化:return 100 * hash;
SirWojtek

185

一貫して6桁のカラーコードを返すCD Sanchezの回答を以下に示します。

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
このコードは、NoSQLの自動生成されたIDと組み合わせて使用​​すると効果的です。同じユーザーの場合、色は常に同じです。
deviavir 2014年

16進コードの透明性のためにもアルファチャネルが必要でした。これは役に立ちました(
Husterknupp

@Tjorriemorrie色ではなく色であることを指摘して賛成。はい、はい、それは本当に話題ではありませんが、それは私にとって重要なことです(実際にそれを入力するとき、私は両方とも「色」とつづりました!)。ありがとうございました。
プリフタン

興味深いことに、異なるブラウザ/ OSの同じ文字列では色が異なります(例:Chrome + WindowsとChrome + Android)-私の電子メール=>色は一方が青で他方が緑です。なぜか?
アベンモア

43

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%)";
};

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%持っています。これは自分の配色に一番合うからです。


3
非常に用途の広いソリューション。
MastaBaba、2015年

2
ソリューションを共有するためのThx。色をどの程度カラフルにするかを決定できます。
Florian Bauer

@haykamスニペットにしてくれてありがとう!
チミン

このアプローチは、私のアプリが必要とする希望の鮮やかさ/繊細さを与えるのに本当に役立ちます。ランダムな16進数は、彩度と明るさが大きく変動しすぎて、ほとんどの状況で役立ちません。これをありがとう!
simey.me

このソリューションでは、返される色が少なすぎます。
カタフェンタミン

9

ランダムな色を生成すると、私の好みに十分なコントラストのない色が作成される傾向があることを発見しました。私がそれを回避するために見つけた最も簡単な方法は、非常に異なる色のリストを事前に入力することです。新しい文字列ごとに、リストの次の色を割り当てます。

// 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色のみという制限がありますが、ほとんどの人間はとにかくそれ以降は違いを見分けることができません。いつでも色を追加できると思います。

このコードはハードコードされた色を使用しますが、少なくとも開発中に、生産中の色の間にどの程度のコントラストが見られるかを正確に知ることが保証されています。

色のリストはこのSOの回答から削除されました。他の色のリストがあります。


Fwiwコントラストを決定するためのアルゴリズムがあります。私はそれを使って何年か前に(C言語で)何かを書きました。それについて心配しすぎると、それはとにかく古い答えですが、コントラストを決定する方法があることを指摘しました。
プリフタン

7

ハッシュから色を生成できるPlease.jsへのプルリクエストを開きまし

次のように文字列を色にマッピングできます。

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

たとえば、"any string goes here"として返されます"#47291b"
"another!"リターンなど"#1f0c3d"


追加してくれて本当にかっこいい。こんにちはGoogleの受信トレイのような名前に基づいて文字が入ったサークルを生成したいのですが:)
marcus7777 '18

この答えを見たとき、私は完璧だと思いました。今度は非常にランダムな色を生成しないようにカラースキーマについて考える必要があります。それから、Please.jsのmake_colorオプションについて読んだところ、私の顔に美しい笑顔が生まれました。
panchicore

6

入力が、単純なハッシュがカラースペクトル全体を使用するほど十分に異なる場合は、ハッシュ関数の代わりにシードされた乱数ジェネレータを使用できます。

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

5

ランダムカラーのさらに別のソリューション:

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擬似ランダム関数をここから使用しました、いくつかのパディングと数学を自分で使用しました。

この関数は見た目が良く、実行すべきことを実行しますが、均等に分散された色を生成するとは思いません。


'0'.repeat(...)javascriptは無効です
kikito 2014年

@kikitoは十分に公正です、おそらく私はプロトタイプをどうにか拡張させました(JQuery?)。とにかく、私は関数をJavaScriptのみで編集したので、指摘してくれてありがとう。
エスタニ2014年

@kikitoそれは有効なES6ですが、使用するとブラウザ間の互換性が無視されます。
Patrick Roberts

5

hashCodeCristian Sanchezのas hslと最新のJavaScript のas を使用して、次のようにコントラストの良いカラーピッカーを作成できます。

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>


4

これは、入力文字列に基づいて美的に楽しいパステルカラーを生成するために思いついたソリューションです。文字列の最初の2文字をランダムシードとして使用し、そのシードに基づいてR / G / Bを生成します。

シードは最初の2つだけではなく、文字列内のすべての文字のXORになるように簡単に拡張できます。

ここでの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はこちら:https : //gist.github.com/ro-sharp/49fd46a071a267d9e5dd


これは本当に奇妙なやり方だと言わざるを得ません。それは一種の作品ですが、利用できる色はそれほど多くありません。最初の2色のXORは順序を区別しないため、文字の組み合わせのみが存在します。色の数を増やすために行った単純な追加は、var seed = 0でした。for(var i in input_str){シード^ = i; }
Gussoh

はい、それは本当にあなたが生成したい色の数に依存します。この例では、UIでさまざまなペインを作成していて、虹ではなく色の数を制限したかったことを思い出します:)
Robert Sharp

1

ここに別の試みがあります:

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

1

本当に必要なのは、優れたハッシュ関数だけです。ノードでは、私は単に使用します

const crypto = require('crypto');
function strToColor(str) {
    return '#' + crypto.createHash('md5').update(str).digest('hex').substr(0, 6);
}

0

これをJava用に変換します。

すべての戦車。

public static int getColorFromText(String text)
    {
        if(text == null || text.length() < 1)
            return Color.BLACK;

        int hash = 0;

        for (int i = 0; i < text.length(); i++)
        {
            hash = text.charAt(i) + ((hash << 5) - hash);
        }

        int c = (hash & 0x00FFFFFF);
        c = c - 16777216;

        return c;
    }

-1

この関数はトリックを行います。それはこのの適応、かなり長い実装です。このレポ ...

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('')}`;
}

これにより、非常に暗い値が多数生成されます。
ラングドン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.