I'm using Javascript to filter/shift a red icon image to another color specified in RGB. More specifically, I'm using CSS filters hue-rotate, brightness and saturate to shift colors from pure red to my target color. My result works well for many colors, but a few colors do not come out correctly. Any suggestions?
You can see in my code that I tried both HSL and HSB calculations, with essentially the same results. The current code runs with HSB, which I think fits CSS filter properties better.
<!DOCTYPE html>
<html>
<head>
<style>
#myDIV2 {
position: absolute;
width: 200px;
height: 200px;
}
</style>
<script>
function rgbToHsl(r, g, b){
r /= 256, g /= 255, b /= 256;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = d == 0 ? 0 : d / (1 - Math.abs(2 * l - 1)) ;
if (d == 0) {
h = 0
} else {
switch(max){
case r: h = ((g - b) / d) % 6; break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
}
/* testing out HSB instead of HSL = H is the same */
var br_hsb = max;
var s_hsb = (max-min)/br_hsb;
return [h, s_hsb, br_hsb]; // [h, s, l];
}
function setHue(r, g, b){
hsl = rgbToHsl(r, g, b);
h_str = Math.round(hsl[0]*360).toString();
s_str = (Math.round(hsl[1]*1000)/10).toString();
l_str = (Math.round((hsl[2]+.5)*1000*1)/10).toString(); /* *2 SEEMS TO WORK BETTER FOR HSL */
styleString = "hue-rotate(" + h_str + "deg) saturate(" + s_str + "%) brightness(" + l_str + "%)";
document.getElementById("myDIV2").style.filter = styleString;
document.getElementById('hue').value = h_str;
document.getElementById('hsl_str').value = styleString;
}
</script></head>
<body>
<p>Set the RGB for the icon:</p>
R: <input type=text size=3 name=r id=r value=0>
G: <input type=text size=3 name=g id=g value=255>
B: <input type=text size=3 name=b id=b value=13>
<button onclick="setHue(document.getElementById('r').value, document.getElementById('g').value, document.getElementById('b').value)">
set color
</button>
Hue: <input type=text size=5 name=hue id=hue value="">
HSL: <input type=text size=40 name=hsl_str id=hsl_str value="">
<p><hr><p>
<div id="myDIV2" >
<img src=http://www.clker.com/cliparts/T/m/K/p/d/W/man-icon.svg.med.png
width=200 height=200>
</div>
</script>
</body>
</html>
Colors that work include: Red: 255,0,0 Lime: 0,255,0 Blue: 0,0,255 Purple: 128,0,128 Silver: 192,192,192 Grey: 128,128,128
but colors that don't work include: Yellow: 255,255,0 White: 255,255,255 Black: 0,0,0
All suggestions welcome.