newbie question here: I have a code that find the average color of an image and apply that color to a sibling DIV's background color. The code works only for the first image of the page, but I want it to loop through all the images of the page that has the .project-thumbnail class, and apply the color to their respective sibling DIV.
I know I could do a jQuery's .each()
function but I'm new to JavaScript and can't figure it out how to achieve the desired - without using jQuery
const img = document.querySelector('.project-thumbnail');
const rect = img.nextElementSibling;
img.crossOrigin = "Anonymous";
img.onload = function () {
getAverageColor(img)
}
function getAverageColor(img) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
let width = canvas.width || img.naturalWidth;
let height = canvas.height || img.naturalHeight;
let draw = ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, width, height);
const data = imageData.data;
let r = 0;
let g = 0;
let b = 0;
for (let i = 0, l = data.length; i < l; i = 4) {
r = data[i];
g = data[i 1];
b = data[i 2];
}
r = Math.floor(r / (data.length / 4));
g = Math.floor(g / (data.length / 4));
b = Math.floor(b / (data.length / 4));
console.log("R:",r,"G:",g,"B:",b)
//return { r: r, g: g, b: b };
rect.style.background = `rgb(${r},${g},${b})`;
}
getAverageColor(img)
CodePudding user response:
Pass a function (i.e: setBgFromAverage
) to NodeList.prototype.forEach (NodeList being the result nodes of document.querySelectorAll('.project-thumbnail')
)
Fix also your canvas size!
const getAverageColor = (img) => {
const rect = img.nextElementSibling;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const width = canvas.width = img.naturalWidth;
const height = canvas.height = img.naturalHeight;
ctx.drawImage(img, 0, 0, width, height);
const imageData = ctx.getImageData(0, 0, width, height);
const data = imageData.data;
let r = 0;
let g = 0;
let b = 0;
for (let i = 0, l = data.length; i < l; i = 4) {
r = data[i];
g = data[i 1];
b = data[i 2];
}
r = Math.floor(r / (data.length / 4));
g = Math.floor(g / (data.length / 4));
b = Math.floor(b / (data.length / 4));
rect.style.backgroundColor = `rgb(${r},${g},${b})`;
};
const setBgFromAverage = (img) => {
img.crossOrigin = "Anonymous";
img.addEventListener("load", () => getAverageColor(img));
};
document.querySelectorAll('.project-thumbnail').forEach(setBgFromAverage);
.projects {
display: flex;
}
.project-thumbnail {
height: 100px;
}
.project-thumbnail * {
color: #fff;
padding: 1rem;
}
<div >
<img alt="thumb 1" src="https://graph.facebook.com/10217909169392394/picture?type=large">
<div>Samuel Charpentier</div>
<img alt="thumb 2" src="https://i.imgur.com/shlgPmb.jpeg">
<div>Catty cat</div>
</div>
For an improved code to retrieve the average color of an image see this answer: Get average color of image via Javascript