【问题标题】:Blend the transparent colour backgrounds of two elements stacked on eachother混合堆叠在彼此上的两个元素的透明颜色背景
【发布时间】:2016-04-08 19:02:05
【问题描述】:

我想知道是否有一种方法可以将两种透明的颜色混合在一起,以获得预定的颜色。

我有一个菜单栏。栏的背景颜色为rgb(0, 0, 0, 0.75)。左上角的标志有#9B0506 的纯红色背景。您可以在http://www.phoenixwebdev.com.au/about-our-services/ecommerce/ 现场查看。该网站正在进行中。

我想让这个红色部分透明,但是当菜单栏后面有白色时,在视觉上实现完全相同的红色。透明的黑色在红色的后面,会影响颜色。

有没有办法计算红色的十六进制值来实现这一点?我什至不知道如何在纯色背景下使用单个透明项目来实现这一点,更不用说黑色复杂的东西了。因为我是色盲,我看不出来。即使我能找到一个数学解决方案也会对我唠叨不休。

所以对于我的情况,我正在寻找一种方法来解决 mystery transparent red colour 堆叠在 rgb(0, 0, 0, 0.75) 堆叠在 white = #9B0506

我在https://css-tricks.com/basics-css-blend-modes/ 阅读了有关 CSS 混合的信息。但是,这并不能满足我的要求。

【问题讨论】:

标签: css colors


【解决方案1】:

首先,在 rgba 中使用颜色比在 hexa 中更容易。

所以,您请求的结果是 9b0506 -> rgb(155, 5, 6)

接下来,任何渠道的公式都是

(f * a) + (b * (1-a))

其中 f 是前景值,b 是通道的背景值

将这个公式应用于前 2 层,白色和黑色,不透明度为 0.75,得到

0 * 0.75 + (255 * 0.25) = 63

因此基数是 rgb (63, 63, 63)

现在,上层可以有任何你想要的 alpha ... 但是对于绿色通道,预期结果是 5,仅基础层的贡献将是 63 * ( 1 - a)。因此,大于 0.08 的 (1 -a ) 值将有助于绿色通道超过 5,超过总结果。

由于值不能为负,结果的最小 alpha 为 (1 - 0.08) = 0.92。

现在,我们可以计算 r g b 值:

r = (155 - (63 * 0.08)) / 0.92 = 163

b = (6 - (63 * 0.08)) / 0.92 = 1

(绿色通道,如前所述,为 0)

所以结果是 rgba (163, 0, 1, 0.92)。

如果你想要更高的透明度,你需要降低绿色通道限制(或者绿色通道结果变高,或者基色变低..这将实现使黑色层具有更高的不透明度)

【讨论】:

  • 你从哪里学来的这个哈哈?惊人的答案:D 比在 js 中尝试每一个 rgba 值直到找到匹配项要好得多。lol
  • 太棒了。 @seahorsepip 在阅读了这个答案后,我用谷歌搜索了这个公式,发现了这个:en.wikipedia.org/wiki/Alpha_compositing.
  • @JamesJones 感谢您的链接,我以前在 Photoshop 中使用过合成,但从不知道它可以像这样使用,也从未真正读入过。所以我会读一读:D
  • 如果我没记错的话,结果应该是rgba (163, 0, 1, 0.92) 而不是0.08
  • @DJDavid98 是的,你是对的......“最大”应该是“最小”......我们发现了!
【解决方案2】:

根据实验,我设法使用rgba(163,0,2,.92) 获得了准确的颜色。下面的演示呈现了一个填充了相互堆叠的颜色的框,将#9B0506 作为整体颜色。

此外,您无需依靠您的视力来测试理论值,ColorPic 等免费应用程序允许您实时检查屏幕上的像素,并直接获取其 HEX/RGB 颜色值.

我知道这不提供任何以编程方式计算它的方法,但如果有人试图为此测试算法,它可以作为参考点。

.a { z-index: 1; background: white }
.b { z-index: 2; background: rgba(0,0,0,.75) }
.c { z-index: 3; background: rgba(163,0,2,.92) }

.a, .b, .c {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>

根据您的要求,我尝试使用较低的不透明度值再现颜色。我发现rgba(171,0,0,.85) 非常接近目标颜色,而且它的不透明度也略高一些。在这一点上,我相当确定在前面提到的任何其他值下都无法获得确切的颜色,但这应该是一个足够接近的近似值,不会有太大差异。下面的演示将旧颜色和新颜色并排放置,它们产生的颜色代码写在每一半上。

.a { z-index: 1; background: white }
.b { z-index: 2; background: rgba(0,0,0,.75) }
.c { z-index: 3; background: rgba(163,0,2,.92) }
.d { z-index: 3; background: rgba(171,0,0,.85) }

.a, .b, .c, .d {
  position: absolute;
  top: 0;
  height: 100%;
}
.a, .b {
  left: 0;
  width: 100%;
}
.c, .d {
  color: #fff;
  font-size: 3em;
  font-family: "Consolas", monospace;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 50%;
}
.c { left: 0 }
.d { right: 0 }
<div class="a"></div>
<div class="b"></div>
<div class="c"><span>#9B0506</span></div>
<div class="d"><span>#9B0A0A</span></div>

【讨论】:

  • 这当然给了我相同的颜色。非常感谢!迄今为止最好的答案。不幸的是,透明效果几乎看不到,你认为有可能用更深的红色和更高的透明度来实现吗?也就是说,我知道我们在这里使用深色。
【解决方案3】:

你尝试过背景渐变

background: linear-gradient(direction, color-stop1, color- stop2, ...); 

【讨论】:

  • 这不是我想要的。你说的是在渐变中混合两种颜色对吧?我说的是混合堆叠在一起的两个元素的颜色。
  • 对不起,我误会了
【解决方案4】:

不确定是否可以计算。虽然我们可以暴力破解它:D

考虑一个画布元素 A 和一个画布元素 B。 用户可以输入颜色 A(#9B0506) 和颜色 B(rgb(0, 0, 0, 0.75)),然后一个 js 循环将尝试颜色 B 上的每一种颜色(rgba),并输出与颜色 A 最接近的匹配.

我会尝试在 jsfiddle 中制作一个程序。

【讨论】:

  • 循环必须手动迭代,对吗?我不反对你的想法,只是澄清一下。
  • 循环将用js完成,目前正在开发一个程序来完成这项工作。请记住,它会在完成之前将浏览器挂起一段时间(可以在浏览器控制台中看到进度)。
  • 我担心你会稍微误解这个问题。我进行了编辑以尝试使其更清晰
猜你喜欢
  • 2014-11-10
  • 1970-01-01
  • 2014-10-23
  • 2014-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
  • 2017-09-23
相关资源
最近更新 更多