为什么CSS过滤器hue-rotate产生wierd结果? [英] Why does the CSS filter hue-rotate produce wierd results?

查看:593
本文介绍了为什么CSS过滤器hue-rotate产生wierd结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用CSS过滤器 模拟Photoshop的颜色叠加层,在这样做的时候,发现了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);}。精度过度{-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>  



应该是 #00FF00 #007100 ,应该是#0000FF #0132FF 通过使用 hue-rotate ,色调,饱和度和亮度已设置为无意义的级别,跨浏览器。



我需要赶上Cthulhu,找出他编码的逻辑,所以我可以解决它。



这是一个奇怪的颜色空间与 HSV或HSL 无关?是否可以将HSV,HSL或RGB坐标转换为这个异想天开的维度?它有名字吗?标准?以下是邪教?

解决方案

我还是不能相信这是跨浏览器。我的意思是,我一直在搜索颜色空间,找不到任何其中色调的定义是有意义的。



无论哪种方式,我已经阅读了铭文,仔细检查了魔法咒语后,我生成了一个javascript版本的可怕的破碎的 hue-rotate 算法浏览器目前正在遭受。



这里是 a jsfiddle version and here's it as a code snippet:



  function calculate(){//获取RGB和角度使用。 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; //保持你的呼吸,因为后面是不是花。 var matrix = [//记住这是单位矩阵为1,0,0,// Reds 0,1,0,// Greens 0,0,1 // Blues]; //亮度系数。 var lumR = 0.2126; var lumG = 0.7152; var lumB = 0.0722; //色调旋转系数。 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;函数钳(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); //输出结果var result ='当原始颜色rgb('+ [r,g,b] +'),'+'旋转'+ angle +'degrees'+'by devil\逻辑,给你'+'rgb('+ [R,G,B] +')。如果我是正确的。 document.getElementById('result')。innerText = result;} //听输入键按下['color','angle']。forEach(function(i){document.getElementById(i).onkeypress = function事件){var e = event || window.event,c = e.which || e.keyCode; if(c =='13')return calculate();}});  / pre> 

  body {font:14px sans-serif; padding:6px 8px;} input {width:64px;}  

 < p>该算法模拟了奇怪,无意义和完全愚蠢的< code> hue-rotate< / code> CSS过滤器。我想知道它是如何工作的,因为它与我看过的任何色相的定义脱节; < / p>< span>#< / span>< input type =< / span> textid =colorplaceholder =RRGGBB>< input type =textid =angleplaceholder =degrees>< button onclick =calculate()& < 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,
};


I'm trying to emulate Photoshop's "Color Overlay" using CSS filters, and while doing so, found out the CSS filters operate on colors as consistently as an epileptic seizure.

Consider the color #FF0000. If we rotate its hue by 120deg, we should get #00FF00, and by 240deg we should get #0000FF. This is the realm of sanity. Now let's enter CSS filters:

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>

What should be #00FF00 is #007100, and what should be #0000FF is #0132FF. By using hue-rotate, the hue, saturation and brightness have been set to nonsensical levels, cross-browser.

I need to catch up with Cthulhu and figure out what logic He coded so I can work around it.

Is this a wierd color space unrelated to HSV or HSL? Is it possible to translate HSV, HSL or RGB coordinates into this whimsical dimension? Does it have a name? A standard? A cult following?

解决方案

I still cannot believe this is cross-browser. I mean, I've been googling for color spaces and couldn't find any where their definition of "hue" makes sense. They pulled it completely out of their asses, as a big, spiky solid block of galvanized stupidity.

Either way, I have read the inscriptions, and after careful examination of the magic incantations, I've produced a javascript version of the horribly-broken hue-rotate algorithm browsers are currently suffering from.

Here's a jsfiddle version and here's it as a code snippet:

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>

Note that at some point they may find out that the algorithm was coded by an intern on April 1st that wanted to pull a prank on everyone. They may even find the dice used to choose coefficients.

One way or another, knowing the random logic employed helps me work around it, and that's why I did this. Hopefully someone will stuble upon it, and maybe some day we'll have fixed versions of hue-rotate and company shipped with browsers.


As a bonus, in case it helps anyone: this is how Sepia is calculated:

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,
};

这篇关于为什么CSS过滤器hue-rotate产生wierd结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆