Home > database >  Set average image color to multiple elements background
Set average image color to multiple elements background

Time:08-24

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

  • Related