JSFiddle - React, Tailwind, and code Playground

by phloe

HTML

<input id="spreadInput" type="range" min="0" max="255" value="50" step="1" />
<div id="palette"></div>

JavaScript

function cancel (event) {
	event.preventDefault();
}

function getColorData(url, width, height) {
	return new Promise((resolve, reject) => {
		var image = new Image();
		image.addEventListener("load", function () {
			if (!width) {
				width = image.width;
			}
			if (!height) {
				height = image.height;
			}
			var canvas = document.createElement("canvas");
			canvas.setAttribute("width", width);
			canvas.setAttribute("height", height);
			var context = canvas.getContext("2d", { alpha: false });
			context.clearRect(0, 0, width, height);
			context.drawImage(image, 0, 0, width, height);
			var { data } = context.getImageData(0, 0, width, height);
			context = null;
			canvas = null;
			resolve(data);
		});
		image.addEventListener("error", reject);
		image.src = url;
	});
}

let colors;

function update() {
	console.log(colors);
  let spread = spreadInput.value;
  let max;
	const hueCounts = Object.keys(colors).map(
  	(hue) => {
    	if (hue !== "counts") {
      	return { hue, counts: colors[hue].counts };
      }
      return null;
    } 
  )
  .filter((item) => item)
  .sort((a, b) => b.counts - a.counts)
  .reduce(
  	(result, { hue, counts }) => {
    	if (max === undefined) {
      	max = hue;
				console.log("max", max);
      }
      let hueGroup = Math.round((hue - max) / spread) * spread + 360 % 360;
      if (!(hueGroup in result)) {
      	result[hueGroup] = 0;
      }
      result[hueGroup] += counts;
      return result;
    },
    {}
  );
	console.log(hueCounts);
}

window.addEventListener("dragover", cancel);
window.addEventListener("dragenter", cancel);
window.addEventListener("drop", async function (event) {
  event.preventDefault();
  var files = event.dataTransfer.files;
  var reader = new FileReader();
  reader.addEventListener("load", async function () {
    let data = await getColorData(this.result);
    colors = { counts: 0 };
    for (let i = 0; i < data.length; i += 4) {
    	let rgb = [data[i], data[i+1], data[i+2]];
      let [h,...