Acabei de construir uma funçãozinha muito útil em Javascript para inverter uma determinada cor, que pode ser enviada em rgb ou hexadecimal. Resolvi compartilhar com vocês.
Minha situação era a seguinte: eu precisava marcar, sobressaltar partes de um texto, mas não sabia qual seria a cor desse texto. Bem, para isso existe o valor ‘highlight’, mas ele não é aconselhado pela W3C… e nem sempre o resultado é ir para a cor oposta a do texto, embora resolva os problemas de baixo contraste. Mas o W3C falou, tá falado. Usei, a princípio, cores fixas (fundo azul marinho e fonte branca). Não ficava mal, mas seria mais elegante usar a cor oposta… e fiquei com isso na cabeça: como inverter uma cor?
Bem, tanto o sistema hexadecimal quanto o rgb trabalham com as cores básicas - vermelho, verde e azul - com um valor mínimo (hex:00, rgb:0) e um máximo (hex:FF, rgb:255) para cada uma. Tendo o início e o final do ‘espectro’, poderíamos subtrair o valor enviado do valor máximo, obtendo um valor ‘oposto’… naturalmente, optamos por usar o sistema RGB, que trabalha apenas com valores numéricos (0-255).
A primeira coisa que precisava eram funções para traduzir rgb para hexadecimal e vice-versa. Achei aqui umas funções que usei a um tempo atrás, provavelmente retiradas do HTMLArea (atual Xinha), para o qual construí alguns plugins. Lá vão elas:
// r -> vermelho (0-255)
// g -> verde (0-255)
// b -> azul (0-255)
// retorno: retorna a cor em hexadecimal
var rgb2hex = function(r,g,b) {
return ‘#’+hex(r)+hex(g)+hex(b);
function hex(dec) {
if(typeof(dec) != ‘number’ || dec < 0 || dec > 255) return("–");
var chars = "0123456789ABCDEF", md = dec % 16;
return chars.charAt((dec - md) / 16) + chars.charAt(md);
}
}
// hex2rgb -> traduz uma cor definida em Hexadecimal para o sistema RGB
// str -> cor em hexadecimal
// cssret -> se definido como true, ao invés de retornar um objeto, a função
// retornará uma string assim: ‘rgb(120, 120, 120)’
var hex2rgb = function(str, cssret) {
var ret = {}, hexStr = str.replace(/^#?/,"");
if(!/^([\dA-Fa-f]{2})([\dA-Fa-f]{2})([\dA-Fa-f]{2})$/.test(hexStr)) return str;
ret.r = parseInt("0x" + RegExp.$1);
ret.g = parseInt("0x" + RegExp.$2);
ret.b = parseInt("0x" + RegExp.$3);
return cssret ? ‘rgb(’+ret.r+’, ‘+ret.g+’, ‘+ret.b+’)’ : ret;
}
Agora basta fazer a função para inverter. Trata-se de uma ação simples, mas a função acabou ficando grande pois trabalha com valores em Hex e RGB, retornando um tipo semelhante ao que foi enviado, mas sempre na forma de uma string.
O valor enviado à função invertColor pode ser como os exemplos a seguir:
- invertColor("#CC0000") -> retornaria algo como "#0000CC"
- invertColor("FFFF00") -> retornaria algo como "#0000FF"
- invertColor("#FF0") -> retornaria algo como "#0000FF"
- invertColor("FF0") -> retornaria algo como "#0000FF"
- invertColor(120, 120, 0) -> retornaria algo como "rgb(135, 135, 255)"
- invertColor("rgb(120, 120, 0)") -> retornaria algo como "rgb(135, 135, 255)"
Lá vai a função:
var args = invertColor.arguments; //alert(’"’+args[0]+’"’);
var regs = {’hex’: /^#?[A-Fa-f0-9]{6}/, ‘hex3′: /^#?([A-Fa-f0-9])([A-Fa-f0-9])([A-Fa-f0-9])/,
’rgbstr’: /rgb\(([\d\s,]+)\)/};
var r = 0, g = 0, b = 0, typ = ‘’;
if(args.length == 1) { //alert(1);
if(regs.hex.test(args[0])) {
typ = ‘hex’;
var rgb = hex2rgb(args[0]);
r = rgb.r; g = rgb.g; b = rgb.b;
} else if(regs.hex3.test(args[0])) {
typ = ‘hex’;
var str = RegExp.$1+RegExp.$1+RegExp.$2+RegExp.$2+RegExp.$3+RegExp.$3;
var rgb = hex2rgb(str);
r = rgb.r; g = rgb.g; b = rgb.b;
} else if(regs.rgbstr.test(args[0])) {
typ = ‘rgb’;
var arr = RegExp.$1.split(/\s*,\s*/);
r = Number(arr[0]), g = Number(arr[1]), b = Number(arr[2]);
}
} else if(args.length == 3) { //alert(2);
typ = ‘rgb’;
r = Number(args[0]), g = Number(args[1]), b = Number(args[2]);
}
return typ == ‘hex’ ? rgb2hex(255 - r, 255 - g, 255 - b)
: ‘rgb(’+(255 - r)+’, ‘+(255 - g)+’, ‘+(255 - b)+’)';
}
Segue um exemplo para testar a função:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
<script type="text/javascript" src="colors.js"></script>
<script type="text/javascript">
function ini() {
var divs = document.getElementsByTagName(’div’);
for(var i = 0; i < divs.length; i++) {
alert(divs[i].style.backgroundColor+’ <=> ‘+invertColor(divs[i].style.backgroundColor));
divs[i].style.color = invertColor(divs[i].style.backgroundColor);
}
}
</script>
<style type="text/css">
.box {
width:300px;
margin:2px auto;
font-weight:bold;
font-size:40px;
text-align:center;
padding:5px;
}
</style>
</head>
<body onload="ini()">
<div style="background-color:#333;" class="box">texto na cor oposta</div>
<div style="background-color:#FFFF00;" class="box">texto na cor oposta</div>
<div style="background-color:rgb(0,200,0);" class="box">texto na cor oposta</div>
</body>
</html>
É isso aí. Espero que seja útil para você.









