self.addEventListener('message', function (e) { const { data: { i, pixels, correctDistortion = true, width, height } } = e; // This is the old method just by counting pixels const oldStore = {}; //This method applies some weight to the pixels const store = {}; let totalPixelValue = 0; let total = pixels.length / 4; const threshold = 200; for (let i = 0; i < total; i++) { const r = pixels[i * 4 + 0] > threshold ? 1 : 0; const g = pixels[i * 4 + 1] > threshold ? 1 : 0; const b = pixels[i * 4 + 2] > threshold ? 1 : 0; const id = r + "-" + g + "-" + b; //Caclulate y position of pixel const y = Math.floor(i / width); // KarlKilian Formel const pixelValue = Math.cos(360 / (Math.pow(height, 2)) * Math.pow(y, 2) + (-360 / height) * y + 90); oldStore[id] = oldStore[id] + 1 || 1; if (id in store) { store[id] += pixelValue; } else { store[id] = pixelValue; } totalPixelValue += pixelValue; } const finalResult = {}; // Normalize stores Object.keys(oldStore).forEach(k => { finalResult[k] = { distortedValue: oldStore[k] / total } }); Object.keys(store).forEach(k => { finalResult[k].value = store[k] / totalPixelValue; }); // Conver to array for easier const result = Object.keys(finalResult).map(key => { const [r, g, b] = key.split("-").map((n) => parseInt(n) * 255); return { id: key, color: `rgb(${r},${g},${b})`, value: finalResult[key].value, distortedValue: finalResult[key].distortedValue } }).sort((a, b) => a.value > b.value ? -1 : 1) self.postMessage({ result, i }); }, false);