Dynamically change the text color based on a background color

Asked

Viewed 2,102 times

1

Guys, I have this code where it generates me a kind of theme https://jsfiddle.net/jpcaja7t/18/ and I would like to apply this other code on it so that the text is in contrast to bg, how can I do that because my bg and the text color are randomized?

But I would like the code to give me several core contrast and not just one.

Code to contrast text

var rgb = $('#content').css('backgroundColor');
var colors = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
var brightness = 1;

var r = colors[1];
var g = colors[2];
var b = colors[3];

var ir = Math.floor((255-r)*brightness);
var ig = Math.floor((255-g)*brightness);
var ib = Math.floor((255-b)*brightness);

$('#content').css('color', 'rgb('+ir+','+ig+','+ib+')');

2 answers

2

You can determine the distance of colors to apply a different brightness according to the tolerance:

function isNeighborColor(color1, color2, tolerance) {
   // Função tirada da resposta:
   // https://stackoverflow.com/a/11506531/3497987
   // Se foi útil para você vá lá e de um voto a favor.
    if(tolerance == undefined) {
        tolerance = 32;
    }

    return Math.abs(color1.r - color2.r) <= tolerance
        && Math.abs(color1.g - color2.g) <= tolerance
        && Math.abs(color1.b - color2.b) <= tolerance;
}

var color = $('#test').css('backgroundColor');
var colors = color.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);

var rgb = {
    r: colors[1],
    g: colors[2],
    b: colors[3]
}

function GenerateRGB(rgb, brightness){
    var brightness = brightness == undefined ? 1 : brightness;
    var ir = Math.floor((255-rgb.r)*brightness);
    var ig = Math.floor((255-rgb.g)*brightness);
    var ib = Math.floor((255-rgb.b)*brightness);
    
    return {r: ir, g: ig, b: ib};
}

var nrgb = GenerateRGB(rgb, 1);
console.log(rgb, nrgb, isNeighborColor(rgb, nrgb, 165));

$('#test').css('color', 'rgb('+nrgb.r+','+nrgb.g+','+nrgb.b+')');

if (isNeighborColor(rgb, nrgb, 165))
    nrgb = GenerateRGB(rgb, 1.2);

$('#test2').css('color', 'rgb('+nrgb.r+','+nrgb.g+','+nrgb.b+')');
#test, #test2 {
 background-color: #422DAD;   
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="test">Some text</div>
<br>
<div id="test2">Some other text</div>


Obsolete

In accordance with this answer in English did the following example:

function CheckColor(c){
  // Código dessa função foi tirado da resposta
  // https://stackoverflow.com/a/12043228/3497987
    var c = c.replace('#', '');  // strip # 
    var rgb = parseInt(c, 16);   // convert rrggbb to decimal
    var r = (rgb >> 16) & 0xff;  // extract red
    var g = (rgb >>  8) & 0xff;  // extract green
    var b = (rgb >>  0) & 0xff;  // extract blue
    
    var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709
    
  // Fiz alguns testes e identifique que o fator 160 é uma boa referência
  // Altere como desejar
  return (luma < 160);
}

// Função aleatorio e CorAleatoria
// foram usados códigos desse link
// http://www.criarweb.com/artigos/gerar-cor-aleatoria-javascript.html

function aleatorio(inferior,superior){ 
   numPossibilidades = superior - inferior;
   aleat = Math.random() * numPossibilidades;
   aleat = Math.floor(aleat);
   return parseInt(inferior) + aleat;
} 

function CorAleatoria(){ 
   hexadecimal = new Array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F");
   cor_aleatoria = "#";
   for (i=0;i<6;i++){ 
      posarray = aleatorio(0,hexadecimal.length);
      cor_aleatoria += hexadecimal[posarray];
   } 
   return cor_aleatoria ;
} 

// Conversão para Hexadecimal
// https://stackoverflow.com/a/1740716/3497987
var hexDigits = new Array
        ("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"); 

//Function to convert hex format to a rgb color
function rgb2hex(rgb) {
 rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
 return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}

function hex(x) {
  return isNaN(x) ? "00" : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
 }

// Aplica cor aleatória
var cor = CorAleatoria();
document.body.style.backgroundColor = cor;


// Verifica a cor de fundo e aplica cor da fonte
var corAleatoria = rgb2hex( document.body.style.backgroundColor );

document.body.style.color = CheckColor(corAleatoria) ? '#fff' : '#000' ;
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis cupiditate adipisci reprehenderit ea iure laborum voluptate deserunt rerum ad placeat recusandae delectus nulla veritatis iste maxime ipsa odio sit vel.</p>

Run the code several times to test various colors.

  • So what I want is for the font color to change according to the background contrast, the bg of what I passed it works normal, just do not want a red bg to fall a pink font for example.

  • i based it on that code where the text is in contrast to bg http://jsfiddle.net/2VTnZ/2/

  • I don’t understand the update the answer, and how do I get to implement the code that passed me in my random theme? pq that is the big problem, in all models they work however in what I did that generates random theme does not work

  • In the color section where the second color is generated you compare the tolerance if (isNeighborColor(rgb, nrgb, 165)) and the tolerance is less than 165 you generate again nrgb = GenerateRGB(rgb, 1.2); this is the rule you need to implement in your color generator @Victorsaul

  • and with that code like I do for him to read the colors I put on and not just black and white?

2

Using a very good library for color treatment called Chroma.js you can easily manipulate the background color of the gift and apply it in the color style of the text.

Follows a function that returns in the pattern rgba the background color value

function GetBG(e) {
    var v = null;
    if (document.defaultView && document.defaultView.getComputedStyle) {
        var cs = document.defaultView.getComputedStyle(e, null);
        if (cs && cs.getPropertyValue) v = cs.getPropertyValue('background-color');
    }
    if (!v && e.currentStyle) v = e.currentStyle['backgroundColor'];
    return v;
};

With the background color die you can easily manipulate it:

function calculaBG(dom) {
    var $o = chroma(GetBG(dom));
    if ($o.luminance() < 0.5) return $o.brighten(2);
    else return $o.darken(2);
}

Function that calculates color, luminance varies between 0 for black and 1 for white, in the above case if the luminance is less than 50% apply a lighten (brighten) in relation to background color, if it is greater than 50% it applies darken (darken) the color of the background.

Here is an example from Jsfiddle

  • vlw face is almost that, just like the contrast is if the background is dark the font becomes clear and vice versa

  • But what color? if it is the background color or if ($o.luminance() < 0.5) return $o.brighten(2) else return $o.darken(2) you can increase from 2 to 3 ($o.brighten(3) and $o.darken(2)) to be brighter and darker.

  • Sorry my ignorance but I copied your code to my site and it’s not working, as I should put it, in a <script> tag or link his js?

  • Ah and one more thing @Leandro Amorim knows if it would be able to do this contrast result but with random colors as was my file?

  • 1

    Yes vc have to add the script that can be downloaded at the address here, about the second question, ask a new question detailing what you want, because answering here is very complicated.

  • I noticed that in the code of Chroma.js it has a variety of colors hexa, but it only returns one color for each background, it would return more than one color using its base?

  • @Victorsaul from the ideas you received in the answers you have to "play" with the code, test and adapt to do what you need. Remember, if you have new questions, it’s best to ask another question. The more you isolate the problem in each question the easier it will be to find the answer to the problem posed.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.