JavaScript içeren bir dizeye dayalı onaltılık bir renk oluşturma


141

Herhangi bir eski dize (genellikle tek bir kelime olacak) kabul edecek ve bir şekilde bir onaltılık değer #000000ve #FFFFFFbir HTML öğesi için bir renk olarak kullanabileceğiniz bir işlev oluşturmak istiyorum .

Belki de daha #FFFaz karmaşıksa steno altıgen değeri (örneğin:) . Aslında, 'web uyumlu' bir paletteki bir renk ideal olacaktır.


2
Benzer sorulara bazı örnek girdiler ve / veya bağlantılar verebilir misiniz?
qw3n

2
Yanıt değil, ancak aşağıdakileri yararlı bulabilirsiniz: Onaltılık bir tamsayıyı dönüştürmek için kullanın parseInt(hexstr, 10). Bir tamsayıyı onaltılık biçime dönüştürmek için, kullanın n.toString(16), burada n bir tamsayıdır.
Cristian Sanchez

@ qw3n - örnek giriş: sadece kısa, düz eski metin dizeleri ... 'Tıp', 'Cerrahi', 'Nöroloji', 'Genel Uygulama' vb. 3 ile söyle, 20 karakter arasında ... diğeri ama burada java soru: stackoverflow.com/questions/2464745/… @Daniel - Teşekkürler. Oturup buna ciddi bir bakmam lazım. yararlı olabilir.
Darragh Enright

Yanıtlar:


177

Java üzerinde isteğe bağlı bir dizenin Compute hex renk kodundan Javascript'e taşınması :

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

Dönüştürmek için:

intToRGB(hashCode(your_string))

1
harika! teşekkürler, bu iyi çalışıyor. Bitsel operatörler ve şeyler hakkında fazla bir şey bilmiyorum, bu yüzden onu taşıyan yardımınız takdir ediliyor.
Darragh Enright

Altıgen dizeleri doldurması gerekir, örneğin:("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);
Timin

2
Bir grup müzik türü etiketini arka plan renklerine dönüştürüyorum ve bu bana çok zaman kazandırdı.
Kyle Pennell

Keşke bu php dönüştürmek.
Nimitz

6
Benzer dizeler için hemen hemen aynı renklerle bazı sorunlar var, örneğin: intToRGB(hashCode('hello1')) -> "3A019F" intToRGB(hashCode('hello2')) -> "3A01A0" Ve son karma değeri için çarpma ekleyerek kodunuzu geliştirmek:return 100 * hash;
SirWojtek

185

İşte CD Sanchez'in cevabının 6 haneli renk kodunu sürekli olarak döndüren bir uyarlaması:

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

Kullanımı:

stringToColour("greenish");
// -> #9bc63b

Misal:

http://jsfiddle.net/sUK45/

(Alternatif / daha basit bir çözüm, 'rgb (...)' tarzı bir renk kodu döndürmeyi içerebilir.)


3
Bu kod, NoSQL otomatik olarak oluşturulan kimliklerle birlikte harika çalışır, renk aynı kullanıcı için her zaman aynı olacaktır.
deviavir

Ben de onaltılı kodlarım şeffaflık için alfa kanalı gerekiyordu. Bu yardımcı oldu (onaltılı kodumun
Husterknupp

@Tjorriemorrie Renk olduğunu ve renk olmadığını belirttiği için seçildi. Evet, evet, gerçekten konu değil ama benim için önemli bir şey (aslında yazarken her zaman 'renk' yazdım!). Teşekkür ederim.
Pryftan

Farklı tarayıcılarda / oss'de aynı dize için rengin farklı olması ilginçtir - ör. Chrome + Windows ve Chrome + Android - e-postam => renk biri mavi, diğeri yeşil. Neden olduğu hakkında bir fikrin var mı?
avenmore

43

HTML öğeleri için renklerde benzer zenginlik istedim, CSS'nin şimdi hsl () renklerini desteklediğini bulmak için şaşırdım, bu yüzden benim için tam bir çözüm aşağıda:

Ayrıca bkz . Otomatik olarak "farklı" renkler nasıl oluşturulur? buna daha fazla alternatif için.

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'de Ton, Doygunluk, Hafiflik. Böylece 0-359 arasındaki renk tonu tüm renkleri alacaktır, doygunluk rengi ne kadar zengin istediğinizdir,% 100 benim için çalışır. Açıklık derinliği belirler,% 50 normal,% 25 koyu renk,% 75 pasteltir. % 30'um var çünkü renk düzenime en iyi uyuyor.


3
Çok yönlü bir çözüm.
MastaBaba

2
Renklerin ne kadar renkli olması gerektiğine karar verebileceğiniz bir çözümü paylaşmak için teşekkürler!
Florian Bauer

@haykam Parçacık haline getirdiğiniz için teşekkürler!
Timin

Bu yaklaşım, uygulamamın ihtiyaç duyduğu istenen canlılığı / inceliği vermek için gerçekten yararlıdır. Rastgele Hex, doygunluk ve parlaklık bakımından çoğu durumda yararlı olmak için çok fazla değişir. Bunun için teşekkürler!
simey.me

Bu çözüm çok az renk döndürüyor, yapmayacak.
Mayıs 19'da katafetamin

9

Rastgele renkler üretmenin zevkime uygun kontrastı olmayan renkler yaratma eğiliminde olduğunu düşünüyorum. Bunu bulmanın en kolay yolu, çok farklı renklerin bir listesini önceden doldurmaktır. Her yeni dize için listedeki bir sonraki rengi atayın:

// 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");

Bunun sadece 64 renk için bir sınırı olsa da, çoğu insanın bundan sonra farkı gerçekten anlayamadığını görüyorum. Her zaman daha fazla renk ekleyebileceğinizi düşünüyorum.

Bu kod sabit kodlu renkler kullanırken, en azından geliştirme sırasında üretimdeki renkler arasında ne kadar kontrast göreceğinizi bilmeniz garanti edilir.

Bu SO cevabından renk listesi kaldırıldı, daha fazla renk içeren başka listeler var.


Fwiw, kontrastı belirlemek için bir algoritma var. Onunla yıllar önce bir şeyler yazdım (ama C'de). Çok endişelenmeye devam ediyor ve yine de eski bir cevap ama kontrastı belirlemenin bir yolu olduğuna dikkat çektim.
Pryftan

7

Bir karma renk oluşturmak için Please.js bir çekme isteği açtım .

Dizeyi aşağıdaki gibi bir renkle eşleyebilirsiniz:

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

Örneğin, "any string goes here"olarak döner "#47291b"
ve olarak "another!"döner"#1f0c3d"


Bunu eklediğiniz için gerçekten harika teşekkürler. Merhaba, Google gelen kutusu gibi bir ada dayalı harflerle daireler oluşturmak istiyor :)
marcus7777

Bu cevabı gördüğümde, düşündüm, mükemmel, şimdi renk şeması hakkında düşünmeliyim, bu yüzden çok rastgele renkler üretmiyor, lütfen Please.js make_color seçeneklerini okudum ve yüzüme güzel bir gülümseme koydu.
panchicore

6

Girişleriniz, basit bir karmanın tüm renk spektrumunu kullanması için yeterince farklı değilse, karma işlevi yerine tohumlanmış rasgele sayı üreteci kullanabilirsiniz.

Joe Freeman'ın cevabındaki renk kodlayıcısını ve David Bau'nun tohumlanmış rastgele sayı üretecini kullanıyorum .

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

Rastgele renkler için başka bir çözüm:

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

Benim için işi yapan şeylerin bir karışımı. Ben den (Bu konuya da bir cevap) JFreeman Hash fonksiyonu ve Asykäri sözde rastgele fonksiyon kullanılır burada ve kendimden bazı dolgu ve matematik.

Fonksiyonun eşit dağıtılmış renkler ürettiğinden şüpheliyim, ancak güzel görünüyor ve yapması gerekeni yapıyor.


'0'.repeat(...)geçerli değil javascript
kikito

@kikito yeterince adil, muhtemelen prototip bir şekilde uzatılmış (JQuery?). Her neyse, fonksiyonu düzenledim, bu yüzden sadece javascript ... bunu belirttiğin için teşekkürler.
estani

@kikito geçerli ES6 olsa da, tarayıcılar arası uyumluluğu ihmal eder.
Patrick Roberts

5

hashCodeCristian Sanchez'in yanıtı hslve modern javascript'teki gibi kullanarak, aşağıdaki gibi iyi kontrastlı bir renk seçici oluşturabilirsiniz:

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>

HS olduğundan, aradığınız kontrastı elde etmek için parlaklığı ölçeklendirebilirsiniz.

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

İşte bir giriş dizesine dayalı estetik açıdan hoş pastel renkler üretmek için bulduğum bir çözüm. İpin ilk iki karakterini rastgele bir tohum olarak kullanır, daha sonra bu tohuma göre R / G / B üretir.

Tohumun sadece ilk ikisi yerine dizideki tüm karakterlerin XOR olması için kolayca genişletilebilir.

David Crow'un cevabından esinlenerek: Rastgele estetik açıdan hoş bir renk paleti oluşturmak için algoritma

//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 burada: https://gist.github.com/ro-sharp/49fd46a071a267d9e5dd


Bunu yapmanın gerçekten garip bir yolu olduğunu söylemeliyim. Bu biraz işe yarıyor ama çok fazla renk mevcut değil. İlk iki rengin XOR'u sıra ayrımı yapmaz, bu yüzden sadece harf kombinasyonları vardır. Renk sayısını arttırmak için yaptığım basit bir ekleme var tohum = 0; for (input_str içindeki var i) {seed ^ = i; }
Gussoh

Evet, gerçekten kaç renk üretmek istediğinize bağlı. Bu örnekte bir kullanıcı arayüzünde farklı bölmeler oluşturduğumu ve gökkuşağı yerine sınırlı sayıda renk istediğimi hatırlıyorum :)
Robert Sharp

1

İşte başka bir deneme:

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

Gerçekten ihtiyacınız olan iyi bir karma işlevidir. Düğümde sadece kullanıyorum

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

0

Bunu Java için dönüştürüyorum.

Herkes için tanklar.

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

Bu işlev hile yapar. Bu, bu repo oldukça uzun bir uygulamanın bir uyarlaması ..

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

Bu çok fazla karanlık değer üretir.
Langdon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.