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>
Example 2:
This example directly answers the question by retrieving the background image of the current div and running the function using said image.
/*
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);
}
}
/* The element we wish to work on */
const header = document.getElementById("header");
/* To get the background image. Get style and then background image with a slice to remove quotes */
var imageElement = document.getElementById('header'),
style = imageElement.currentStyle || window.getComputedStyle(imageElement, false),
backgroundImage = style.backgroundImage.slice(4, -1).replace(/"/g, "");
getImageBrightness(backgroundImage, function(brightness) {
/* Remove dark and light classes from the element */
header.classList.remove("dark");
header.classList.remove("light");
/* check brightness and apply correct style */
/* Please modify the below brightness comparison statement to adjust to your needs */
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;
background-image: url('https://images.unsplash.com/photo-1530128118208-89f6ce02b37b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80')
}
<div id="header">
<h1>
Header
</h1>
</div>