我尝试emulate Photoshop's "Color Overlay" using CSS filters,同时这样做,发现CSS过滤器对颜色的操作与癫痫发作一致。
考虑颜色#FF0000
。如果我们按120deg
调整其色调,我们应该获得#00FF00
,而240deg
我们应该获得#0000FF
。这是理智的领域。现在让我们进入CSS过滤器:
body { font: bold 99px Arial }
span { color: #F00; }
.daltonics-wont-notice {
-webkit-filter: hue-rotate(120deg);
filter: hue-rotate(120deg);
}
.precision-is-overrated {
-webkit-filter: hue-rotate(240deg);
filter: hue-rotate(240deg);
}

<span class="red">☺</span>
<span class="daltonics-wont-notice">☹</span>
<span class="precision-is-overrated">☹</span>
&#13;
#00FF00
应该 #007100
,#0000FF
应该是什么 #0132FF
即可。 使用hue-rotate
,色调,饱和度和亮度已设置为无意义级别,跨浏览器。
我需要赶上Cthulhu并找出他编码的逻辑,以便我可以解决它。
这是一个与HSV or HSL无关的奇怪色彩空间吗?是否有可能将HSV,HSL或RGB坐标转换为这种异想天开的维度?它有名字吗?一个标准?邪教跟随?
答案 0 :(得分:11)
我仍然无法相信这是跨浏览器。我的意思是,我一直在谷歌搜索色彩空间,找不到任何,他们的“色调”的定义是有道理的。他们将它完全从屁股中拉出来,作为镀锌愚蠢的一个巨大,尖刻的固体块。
无论哪种方式,我都阅读了inscriptions,在仔细检查了神奇的咒语之后,我已经制作了浏览器目前遭受的可怕破坏hue-rotate
算法的javascript版本。< / p>
以下是a jsfiddle version,此处为代码段:
function calculate() {
// Get the RGB and angle to work with.
var color = document.getElementById('color').value;
if (! /^[0-9A-F]{6}$/i.test(color)) return alert('Bad color!');
var angle = document.getElementById('angle').value;
if (! /^-?[0-9]+$/i.test(angle)) return alert('Bad angle!');
var r = parseInt(color.substr(0, 2), 16);
var g = parseInt(color.substr(2, 2), 16);
var b = parseInt(color.substr(4, 2), 16);
var angle = (parseInt(angle) % 360 + 360) % 360;
// Hold your breath because what follows isn't flowers.
var matrix = [ // Just remember this is the identity matrix for
1, 0, 0, // Reds
0, 1, 0, // Greens
0, 0, 1 // Blues
];
// Luminance coefficients.
var lumR = 0.2126;
var lumG = 0.7152;
var lumB = 0.0722;
// Hue rotate coefficients.
var hueRotateR = 0.143;
var hueRotateG = 0.140;
var hueRotateB = 0.283;
var cos = Math.cos(angle * Math.PI / 180);
var sin = Math.sin(angle * Math.PI / 180);
matrix[0] = lumR + (1 - lumR) * cos - lumR * sin;
matrix[1] = lumG - lumG * cos - lumG * sin;
matrix[2] = lumB - lumB * cos + (1 - lumB) * sin;
matrix[3] = lumR - lumR * cos + hueRotateR * sin;
matrix[4] = lumG + (1 - lumG) * cos + hueRotateG * sin;
matrix[5] = lumB - lumB * cos - hueRotateB * sin;
matrix[6] = lumR - lumR * cos - (1 - lumR) * sin;
matrix[7] = lumG - lumG * cos + lumG * sin;
matrix[8] = lumB + (1 - lumB) * cos + lumB * sin;
function clamp(num) {
return Math.round(Math.max(0, Math.min(255, num)));
}
var R = clamp(matrix[0] * r + matrix[1] * g + matrix[2] * b);
var G = clamp(matrix[3] * r + matrix[4] * g + matrix[5] * b);
var B = clamp(matrix[6] * r + matrix[7] * g + matrix[8] * b);
// Output the result
var result = 'The original color, rgb(' + [r,g,b] + '), '
+ 'when rotated by ' + angle + ' degrees '
+ 'by the devil\'s logic, gives you '
+ 'rgb(' + [R,G,B] + '). If I got it right.';
document.getElementById('result').innerText = result;
}
// Listen for Enter key press.
['color', 'angle'].forEach(function(i) {
document.getElementById(i).onkeypress = function(event) {
var e = event || window.event, c = e.which || e.keyCode;
if (c == '13') return calculate();
}
});
body {
font: 14px sans-serif;
padding: 6px 8px;
}
input {
width: 64px;
}
<p>
This algorithm emulates the wierd, nonsensical and completely
idiotic <code>hue-rotate</code> CSS filter. I wanted to know
how it worked, because it is out of touch with any definition
of "hue" I've ever seen; the results it produces are stupid
and I believe it was coded under extreme influence of meth,
alcohol and caffeine, by a scientologist listening to Death Metal.
</p>
<span>#</span>
<input type="text" id="color" placeholder="RRGGBB">
<input type="text" id="angle" placeholder="degrees">
<button onclick="calculate()">Calculate</button>
<p id="result"></p>
请注意,在某些时候,他们可能会发现该算法是由一名实习生在4月1日编写的,他想对所有人进行恶作剧。他们甚至可能会发现用于选择系数的骰子。
这种或那种方式,知道所使用的随机逻辑有助于我解决它,这就是我这样做的原因。希望有人会对它进行调查,也许有一天我们会有固定版本的hue-rotate
和浏览器附带的公司。
作为奖励,万一它可以帮助任何人:这就是棕褐色的计算方法:
var newPixel = {
newRed: oldRed * 0.393 + oldGreen * 0.769 + oldBlue * 0.189,
newGreen: oldRed * 0.349 + oldGreen * 0.686 + oldBlue * 0.168,
newBlue: oldRed * 0.272 + oldGreen * 0.534 + oldBlue * 0.131,
};
答案 1 :(得分:0)
我发现不仅 CSS 和 other implementation 都使用相同的算法。
这是一个合理的 explanation。
<块引用>旋转 120.0 度将准确地将红色映射为绿色,将绿色映射为蓝色,将蓝色映射为红色。这种转换有一个问题,但是输入颜色的亮度没有保留。
因此该算法在保持亮度的同时进行色调旋转,而不是仅旋转色调通道。