【问题标题】:How can we find out if two colors are similar or not?如何判断两种颜色是否相似?
【发布时间】:2020-08-29 17:08:57
【问题描述】:

所以我正在尝试更改文本的背景以及正文。我正在生成 4 种不同的颜色,其中两种用于主体的背景渐变,而另外两种用于文本。

我使用以下代码计算随机 HEX 值:

  newbg1 = "#" + (Math.random()*0xFFFFFF<<0).toString(16);
  newbg2 = "#" + (Math.random()*0xFFFFFF<<0).toString(16);
  newbgtext1 = "#" + (Math.random()*0xFFFFFF<<0).toString(16);
  newbgtext2 = "#" + (Math.random()*0xFFFFFF<<0).toString(16);

(对于此处缺少合理的变量名,我深表歉意)

在此之后,我执行以下检查以确保这些确实是完整的 6 位 HEX 代码,前面带有“#”。

if(newbg1.length<7 || newbg2.length<7||newbgtext1.length<7||newbgtext2.length<7)
    onclick();

如果任何生成的代码不是这些长度,我会调用函数本身来生成新的十六进制代码。

但是,这是我遇到问题的地方。虽然代码是随机生成的,但很多时候看起来渐变不存在,而且是纯色。 我认为这是因为选择了相同的颜色(极不可能,但并非不可能)。

因此我添加了另一个 if 语句来检查颜色是否相同。

if(newbg1 == newbg2 || newbgtext2==newbgtext1 || newbg1 == newbgtext1 || newbg1 == newbgtext2 || newbg2 += newbgtext1 || newbg2 == newbgtext2)
     onclick();

但这仍然无法解决问题。经过一番跟踪和错误后,我得出结论,颜色是相似,而不是相同

我需要一种方法来确定 2 个给定的十六进制值是否彼此相似,以及它们的相似程度。我还想知道 2 种十六进制颜色的最小差异必须是多少才能获得可辨别的渐变。

下面我还要加上完整的JS代码:

var bg = document.getElementById("bg");
var inv = document.getElementById("inv");
var textbg = document.getElementById("textbg");

inv.style.opacity="0";
document.body.addEventListener("click", onclick);

function onclick() {
  newbg1 = "#" + (Math.random()*0xFFFFFF<<0).toString(16);
  newbg2 = "#" + (Math.random()*0xFFFFFF<<0).toString(16);
  newbgtext1 = "#" + (Math.random()*0xFFFFFF<<0).toString(16);
  newbgtext2 = "#" + (Math.random()*0xFFFFFF<<0).toString(16);

  if(newbg1.length<7 || newbg2.length<7||newbgtext1.length<7||newbgtext2.length<7)
    onclick();
  if(newbg1 == newbg2 || newbgtext2==newbgtext1 || newbg1 == newbgtext1 || newbg1 == newbgtext2 || newbg2 == newbgtext1 || newbg2 == newbgtext2)
    onclick();

  inv.style.opacity="1";
  setTimeout(function() {
    bg.style.background = "linear-gradient(-45deg," + newbg1 +"," + newbg2 + ")";
    inv.style.opacity="0";
    bg.style.backgroundSize = "200% 200%";
    bg.style.backgroundRepeat = "no-repeat";
    textbg.style.background = "linear-gradient(-45deg," + newbgtext1 +"," + newbgtext2 + "," + newbgtext1 + ")";
    textbg.style.backgroundSize = "200% 200%";
    textbg.style.backgroundRepeat = "no-repeat";
    textbg.style.webkitBackgroundClip = "text";
    textbg.style.webkitTextFillColor= "transparent";
  }, 500);

}

【问题讨论】:

  • 我不确定已经存在什么可以帮助您解决此问题,但由于“相似”是非常相对的,您很可能必须制作自定义函数。您需要确定一个十六进制与另一个十六进制的值有多接近才能算作“相似”,然后进行检查。如果是我,我可能会将十六进制分成代表每种颜色的三个十六进制,然后从那里进行测试。
  • @Ashley 好的,我会处理的,如果我找到解决方案,请告诉你。
  • 为什么不检查十六进制数之间的差异并确保最小差异大于X
  • @DCR 您的建议是正确的。但问题是十六进制值有多大差异会产生可辨别的渐变?
  • 有点旁观者的眼光。尝试一些并选择适合您的方法

标签: javascript html css colors linear-gradients


【解决方案1】:

首先,您应该使用.padStart 函数,对于给定数字较小的情况(用前导零填充它)。像这样:

 newbg1 = "#"  + (Math.random()*0xFFFFFF<<0).toString(16).padStart(6, '0');

关于相似度检查 - 您可以获得颜色的RGB,并计算每个颜色之间的总距离。如果它大于某个定义的值 - 它不相似。否则 - 它是相似的。

类似这样的:

(在下面的示例中,要收集的总颜色变化是 50,但可以玩一下)

function getRGB(color) {
  color = parseInt(color.substring(1), 16);
  r = color >> 16;
  g = (color - (r<<16)) >> 8;
  b = color - (r<<16) - (g<<8);
  return [r, g, b];
}
function isSimilar([r1, g1, b1], [r2, g2, b2]) {
  return Math.abs(r1-r2)+Math.abs(g1-g2)+Math.abs(b1-b2) < 50;
}

console.log(isSimilar(getRGB('#ffffff'), getRGB('#000000'))) // white and black
console.log(isSimilar(getRGB('#f10103'), getRGB('#fa1012'))) // to kinds of red

【讨论】:

    猜你喜欢
    • 2021-05-15
    • 2021-08-01
    • 2014-03-22
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多