Procurar

Categorias

Posts recentes

Arquivo

Blog feeds

Bookmarks


Achando a cor oposta
sexta, 19 de janeiro de 2007

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:

// rgb2hex -> traduz uma cor definida em RGB para o sistema Hexadecimal
// 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:

function invertColor() {
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:

<html xmlns="http://www.w3.org/1999/xhtml">
<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ê.

0 Comentários »

Feeds para os comentários nesse post:
TrackBack: http://cauguanabara.blogsome.com/2007/01/19/achando-a-cor-oposta/trackback/

Nenhum comentário

Say something! »















Por favor digite o texto da imagem acima.

lamp! Mapa do site
Achando a cor oposta