Text Color Based on Background Image

Change font color based on background image

I felt I should post an answer to explain what is going on with OPs example.

Simply settings a fill: white on an SVG does not fully reproduce the desired result. OP's example also requires a parent div with mix-blend-mode: difference set as well.

You can actually reproduce this without any SVGs at all. You simply need an element with a color/fill of white, and a parent element with mix-blend-mode: difference. This has to do with how the blending mode of difference works with the color white over a background.

function _Swap() {
document.querySelector(".backgroundDiv").style.background = (document.querySelector(".backgroundDiv").style.background == "rgb(0, 0, 0)") ? "rgb(255, 255, 255)" : "rgb(0, 0, 0)";
}
.backgroundDiv {
background: #FFF;
padding: 4em;
}

.test {
mix-blend-mode: difference;
}

p {
color: #FFF;
}
<div class="backgroundDiv">
<div class="test">
<p>This is a test</p>
</div>
</div>
<input type="button" value="Swap Background Color" onclick="_Swap()">

Dynamically adjust text color based on background image

I finally found something to do precisely what I want it to do! Enter Brian Gonzalez's
jquery.adaptive-backgrounds.js. Check this out:

$parent.css({
// backgroundColor: data.color
color: data.color
});

I just commented out the backgroundColor rule and made a new one for color. For white text, a text-shadow like:

text-shadow: 0 0 1px rgba($black, 0.3); // using Sass

should be enough. Thank you to everyone for your answers!

change text color depending on background image / color

<div id="home_wrapper">
<div id="home_top_t_wrap"> <!-- DARK BACKGROUND -->
<h1 class="top_text_h1"> Shop New York Like Never Before </h1> <!-- TEXT THAT NEEDS TO GO FROM LIGHT TO DARK --> </div>
<div id="the_market_container"> <!-- LIGHT BACKGROUND --></div>
</div>

<script>

$(document).ready(function() {
$("#home_top_t_wrap").hover(function() {
$("body").css("background-color","light"); //change light to your color
});
$("#the_market_container").hover(function() {
$("body").css("background-color","dark"); //change dark to your color
});

});
</script>

I tried on div hover. Hope this helps

How to change font color based on background image with javascript?

Explanation


Here is an example showing how to get the average using a canvas rendered to a 1x1-px scale. From there we set the header background and then apply a light or dark class based on the luminance of the aforementioned average.

Notes


Note 1:
There is some extra code to allow for easier visualization, this is commented and can be removed.

Note 2: The below code is not guaranteed to run on all browsers. Please see this thread for more specifics.

Note 3: This code only works with local images and CORS-enabled image URLs due to it's reliance on canvas.drawImage. Please see this for more information.

Example 1:

this example shows the functionality. It uses two image URLs in the JS to toggle between.

/* 

THE TOGGLE ACTION

*/

/* The urls for toggling between */
const urlLight = 'https://images.unsplash.com/photo-1484503793037-5c9644d6a80a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=930&q=80';
const urlDark = 'https://images.unsplash.com/photo-1517999144091-3d9dca6d1e43?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=627&q=80';
let currentUrl = urlLight;

const toggle = document.getElementById('toggle');

toggle.addEventListener("click", function() {
if (currentUrl === urlLight) {
currentUrl = urlDark;
} else {
currentUrl = urlLight;
}

getImageBrightness(currentUrl, function(brightness) {

const header = document.getElementById("header");
header.style.backgroundImage = `url(${currentUrl}`;

header.classList.remove("dark");
header.classList.remove("light");

console.log(brightness);

if (brightness > 225 / 2) {
header.classList.toggle("dark");

} else {
header.classList.toggle("light");
}
});

});

/*

Important get brightness code

*/

function getImageBrightness(imageSrc, callback) {
var img = document.createElement("img");
img.src = imageSrc;
img.style.display = "none";
img.crossOrigin = "anonymous";
document.body.appendChild(img);

var colorSum = 0;

img.onload = function() {
// create canvas
var canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;

var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);

var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var data = imageData.data;
var r, g, b, avg;

for (var x = 0, len = data.length; x < len; x += 4) {
r = data[x];
g = data[x + 1];
b = data[x + 2];

avg = Math.floor((r + g + b) / 3);
colorSum += avg;
}

var brightness = Math.floor(colorSum / (this.width * this.height));
callback(brightness);
}
}

getImageBrightness(currentUrl, function(brightness) {

const header = document.getElementById("header");
header.style.backgroundImage = `url(${currentUrl}`;

header.classList.remove("dark");
header.classList.remove("light");

if (brightness > 225 / 2) {
header.classList.toggle("dark");

} else {
header.classList.toggle("light");
}
});
.dark {
color: black;
}

.light {
color: white;
}

* {
text-align: center;
}

#header {
padding: 2rem 0;
font-size: 4rem;
background-size: cover;
margin-bottom: 1rem;
background-position: center center;
}
<div id="header">
Header
</div>

<button id='toggle'>
Toggle Background
</button>

invert text color based on background in css

You could also apply this styling to the element you'd like to invert the colors of:

filter: invert(1);
mix-blend-mode: difference;

It especially works if you need to base the difference on a child or a element further away, not a parent or a close element.

I used it with a custom cursor (the black circle), which made it contrast nicely with the elements behind. Sample pen here: https://codepen.io/m3t4lch7/pen/VwwOKNd

Cursor with inverted colors

CSS Custom text color based on background

You can try using inverted colors and re-inverting the whole thing with a CSS filter like so:

body {
margin: 0;
}

#sf-coming-up {
filter: invert(1);
height: 100vh;
}

.blob {
position: absolute;
top: 15%;
right: 15%;
z-index: -1;
width: 70%;
height: 70%;
border-radius: 25% 75% 25% 50% / 75% 25% 50% 25%;
background: springgreen;
}

.title {
padding: 25vh 0 0 12.5vh;
color: springgreen;
mix-blend-mode: difference;
}
<div id="sf-coming-up">
<div class="title">Binnenkort in ons theater</div>
<div class="blob"></div>
</div>

Display text color based on background they are on

You can study mix-blend-mode CSS property. Here I've shared just an example. You should dive deep for understanding the blending.

.container {
position: relative;
width: 400px;
}
.wrapper {
display: flex;

}

.left {
background: #463c84;
height: 100vh;
width: 50%;
}
.right {
background: white;
width: 50%;
}

.header {
flex: 1;
position: absolute;
top: 20%;
left: 21%;
background: inherit;
}

.header h1 {
color: #fff;
mix-blend-mode: difference;
}
<div class="container">
<div class="wrapper">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="header">
<h1 class="blend">TEXT WITH INPIRATION</h1>
</div>
</div>


Related Topics



Leave a reply



Submit