إنشاء لون سداسي عشري بناءً على سلسلة باستخدام جافا سكريبت


أريد إنشاء دالة ستقبل أي سلسلة قديمة (عادة ستكون كلمة واحدة) ومن تلك بطريقة ما تولد قيمة سداسية عشرية بين #000000 و #FFFFFF، لكي أتمكن من استخدامها كلون لعنصر HTML.

ربما حتى قيمة ست عشرية مختصرة (مثل: #FFF) إذا كان ذلك أقل تعقيداً. في الواقع، سيكون لون من لوحة ألوان 'آمنة للويب' مثالياً.

الإجابة رقم 1

إليك تعديل على إجابة CD Sanchez الذي يُرجع باستمرار رمز لون مكون من 6 خانات:

const stringToColour = (str: string) => {
  let hash = 0;
  str.split('').forEach(char => {
    hash = char.charCodeAt(0) + ((hash << 5) - hash)
  })
  let colour = '#'
  for (let i = 0; i < 3; i++) {
    const value = (hash >> (i * 8)) & 0xff
    colour += value.toString(16).padStart(2, '0')
  }
  return colour
}

إذا كنت تستخدم Eslint، فأنت تريد تغليف هذه الدالة في

/* eslint-disable no-bitwise */
>> stringToColour func. definition here" <<
/* eslint-enable no-bitwise */

الاستخدام :

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

مثال :

http://jsfiddle.net/sUK45/

(قد تتضمن حلًا بديلاً/أبسط إرجاع رمز لون بأسلوب 'rgb(...)')

الإجابة رقم 2

فقط نقل الجافا من حساب رمز اللون السادس لسلسلة عشوائية إلى جافاسكريبت:

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

الإجابة رقم 3

كنت أريد ثراءً مماثلاً في الألوان لعناصر HTML، فوجئت عندما اكتشفت أن CSS الآن تدعم ألوان hsl()، لذا فإن الحل الكامل بالنسبة لي هو كما يلي:

انظر أيضًا كيف تولد تلقائيًا N من الألوان "المميزة"؟ لمزيد من البدائل الأكثر تشابهًا مع هذا.

تعديل: التحديث بناءً على نسخة @zei (بالتهجئة الأمريكية)

var stringToColor = (string, saturation = 100, lightness = 75) => {
  let hash = 0;
  for (let i = 0; i < string.length; i++) {
hash = string.charCodeAt(i) + ((hash << 5) - hash);
hash = hash & hash;
  }
  return `hsl(${(hash % 360)}, ${saturation}%, ${lightness}%)`;
}


// For the sample on stackoverflow
function colorByHashCode(value) {
return "<span style='color:" + stringToColor(value) + "'>" + value + "</span>";
}

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

إليك نسختي لعام 2021 مع دالة Reduce ولون HSL.

function getBackgroundColor(stringInput) {
    let stringUniqueHash = [...stringInput].reduce((acc, char) => {
        return char.charCodeAt(0) + ((acc << 5) - acc);
    }, 0);
    return `hsl(${stringUniqueHash % 360}, 95%, 35%)`;
}

الإجابة رقم 5

باستخدام hashCode كما في إجابة كريستيان سانشيز مع 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) {
  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>

الإجابة رقم 6

أجد أن توليد الألوان العشوائية يميل إلى إنشاء ألوان لا تحتوي على تباين كافٍ بحسب ذوقي. أسهل طريقة وجدت لتجاوز ذلك هي ملء قائمة بالألوان المختلفة مسبقًا. لكل سلسلة جديدة، قم بتعيين اللون التالي في القائمة:

// 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، هناك قوائم أخرى تحتوي على ألوان أكثر.