Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Black text - white when on black background [closed]

I'm creating a game with world where player can move.

And there is some GUI (eq, stats..) which has elements with no background (background is game world).

These elements have black text color, and my question is:

Can this text change to white when background'll be black, or can this text'll be always opposite color than background?

like image 410
Brunon Blok Avatar asked Dec 08 '16 14:12

Brunon Blok


2 Answers

There is a css property that does exactly what you want, but support is a bit limited (no IE/Edge).

It is mix-blend-mode and using a value of difference yields very similar results to what you need. (many more modes supported).

The mix-blend-mode CSS property describes how an element's content should blend with the content of the element's direct parent and the element's background.

Relevant example:

html, body{height:100%}
.game {
  width: 100%;
  height: 100%;
  background:url('http://www.intrawallpaper.com/static/images/rainbow_texture679.jpg') 0% 50% no-repeat;
animation: moveBG 10s linear infinite;
}
.gui {
  color:grey;
  padding:25px;
  line-height:1.4;
  mix-blend-mode: difference;
}
@keyframes moveBG {
  0% {background-position: 0% 50%;}
 25% {background-position: 50% 0%;}
 50% {background-position: 100% 50%;}
 75% {background-position: 50% 100%;}
100% {background-position: 0% 50%;}
}
<div class="game">
  <div class="gui">
  Ellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis ornare metus sed justo pulvinar dapibus. Cras posuere leo quis semper lacinia. Pellentesque vitae ligula ut magna interdum tincidunt. Integer est velit, congue eget quam nec, feugiat malesuada nulla. Sed nisi lacus, pharetra mattis dapibus ac, hendrerit ac quam. Nulla facilisi.
  </div>
</div>

Alternatives to this (for wider support) would be the box-shadow trick that @Rourin posted (which could be combined with the mix-blend-mode for the best results), or repeating the CSS effect using a canvas element and applying the effect programmatically (but this is quite more involved and with heavier performance).

like image 143
Gabriele Petrioli Avatar answered Sep 20 '22 14:09

Gabriele Petrioli


Its best not to invert because inverted colors also can be very unreadable or just very straining for the eyes.

Here is a really cool algorithm that automatically chooses the most legible text color based on background.

You can use this example in your game loop when you draw the frames and texts.

var c = document.getElementById('container');

var colourIsLight = function (r, g, b) {
  
  // Counting the perceptive luminance
  // human eye favors green color... 
  var a = 1 - (0.299 * r + 0.587 * g + 0.114 * b) / 255;
  return (a < 0.5);
}

var randomRgb = function () {
  var r = /* 189; //*/ Math.floor(Math.random() * 256);
  var g = /*60; //*/ Math.floor(Math.random() * 256);
  var b = /*151; //*/ Math.floor(Math.random() * 256);
  return [r, g, b];
};

var colourFromRgb = function (r, g, b) {
  return 'rgb(' + r + ',' + g + ',' + b + ')';
};

for (var i = 0; i < 1000; i += 1) {
  var el = document.createElement('div');
  el.setAttribute('class', 'box');
  el.textContent = "Hello";
  
  var bgRgb = randomRgb();
  var bgColour = colourFromRgb(bgRgb[0], bgRgb[1], bgRgb[2]);
  var textColour = colourIsLight(bgRgb[0], bgRgb[1], bgRgb[2]) ? 'black' : 'white';
  
  el.setAttribute('style', 'background-color: ' + bgColour + '; color: ' + textColour);
  
  c.appendChild(el);
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#container {
  text-align: center;
}

.box {
  display: inline-block;
  vertical-align: top;
  text-align: center;
  width: 100px;
  height: 100px;
  line-height: 100px;
  font-size: 20px;
  font-family: sans-serif;
  font-weight: bold;
}
<div id="container"></div>

http://codepen.io/WebSeed/full/pvgqEq/

like image 38
Timmetje Avatar answered Sep 19 '22 14:09

Timmetje