【发布时间】:2015-06-10 02:33:24
【问题描述】:
我有一个图标,我想使用 CSS 更改它的颜色。它位于 CSS 中内联的数据 uri 优化的 SVG 中。
通常,这是不可能的。这就是发明图标字体的原因。与 SVG 相比,它们的主要优势是能够从 CSS 接收 color 和 text-shadow 规则。好吧,CSS filters 现在能够对任意图像执行这两种操作,they now work in all Blink, Webkit and Gecko browsers 和 can be expected for future IE/Spartan。
text-shadow 替换很容易;只需使用drop-shadow filter。
然而,尽管所有必要的过滤器都在这里,但事实证明,将图像着色为特定颜色非常棘手。到目前为止,我的理论如下:
- 使用
contrast(0)将整个图像变成纯灰色,同时保留 Alpha 通道(Mozilla wiki 说它会变成黑色,但在所有浏览器中它都会变成灰色,一定是错字)。 - 使用
sepia(1),因为我们无法对灰度图像的色相/饱和度进行操作。这确保了整个图像由我们可以进行数学运算的参考颜色组成;具体来说,#AC9977。
此时,我们应该能够使用hue-rotate、saturate 和brightness 将整个图像从现在的纯色#AC9977 转换为我们想要的任何颜色。
首先,浏览器使用什么颜色坐标?我无法确定 the spec 是否有意义,以确定它是否使用 HSL (Lightness) or HSV (Value),但由于 HSB(Brightness)是 HSV 的另一个名称,我想它正在使用 HSV。此外,使用 brightness(999) 之类的东西会使颜色饱和(而不是使它们变成白色),这会在 HSV 中发生,但不会在 HSL 中发生。
基于这个假设,我们将进行如下操作:
- 计算
#AC9977与我们想要的颜色之间的色相差异,并使用hue-rotate。 - 计算两者之间的饱和度差异,并使用
saturate。 - 计算两者之间的亮度差,并使用
brightness。
由于这不是手工完成的工作,我们将使用LESS preprocessor:
.colorize(@color) {
@sepiaGrey: #AC9977;
@hOffset: (hsvhue(@color) - hsvhue(@sepiaGrey)) * 1deg;
@sRatio: unit(hsvsaturation(@color) / hsvsaturation(@sepiaGrey));
@vRatio: unit(hsvvalue(@color) / hsvvalue(@sepiaGrey));
-webkit-filter: contrast(0) sepia(1) hue-rotate(@hOffset) saturate(@sRatio) brightness(@vRatio);
filter: contrast(0) sepia(1) hue-rotate(@hOffset) saturate(@sRatio) brightness(@vRatio);
}
据我了解,这应该可行。 But it isn't。 为什么,以及如何让它发挥作用?
我想要实现的示例
将图标视为图像或元素(背景图像、基于 CSS 的形状等),具有任何颜色,并具有由透明度定义的形状(非 em> 一个可以简单叠加的矩形图像)。我想让它完全由带有 CSS 的特定颜色组成(大概是使用filters)。
我计划将其实现为带有颜色参数的LESS mixin,但仅指导 HSB 函数背后的逻辑就足够了。
【问题讨论】:
-
我不完全确定您要达到的目标。 用纯色填充到底是什么意思?你能在 Photoshop 或类似工具中制作一个模型,看看结果应该是什么样子吗?
-
PS 忽略亮度似乎提供了纯色,我也不知道为什么,但它似乎更朝着你想要的方向发展。
-
@BramVanroy 考虑example 中的图像。我想要的是它们仅由特定颜色组成(在示例中为
#729FCF),同时保持 alpha 通道。例如,考虑一个以 SVG 表示的图标,它最初是白色的,您希望它在不同情况下变成某种红色或绿色。在某种程度上,我或多或少可以“观察”颜色,但我正在尝试制作可以重复使用且不需要猜测的东西,并且在我对颜色的基本理解中,我制作了一种算法似乎不起作用。 -
@BramVanroy 示例已添加。
标签: css image-manipulation hsv color-space css-filters