const Color = require('../Color'); const {clip_rgb} = require('../utils'); const {pow, sqrt, PI, cos, sin, atan2} = Math; module.exports = (colors, mode='lrgb', weights=null) => { const l = colors.length; if (!weights) weights = Array.from(new Array(l)).map(() => 1); // normalize weights const k = l / weights.reduce(function(a, b) { return a + b; }); weights.forEach((w,i) => { weights[i] *= k }) // convert colors to Color objects colors = colors.map(c => new Color(c)); if (mode === 'lrgb') { return _average_lrgb(colors, weights) } const first = colors.shift(); const xyz = first.get(mode); const cnt = []; let dx = 0; let dy = 0; // initial color for (let i=0; i { const xyz2 = c.get(mode); alpha += c.alpha() * weights[ci+1]; for (let i=0; i= 360) A -= 360; xyz[i] = A; } else { xyz[i] = xyz[i]/cnt[i]; } } alpha /= l; return (new Color(xyz, mode)).alpha(alpha > 0.99999 ? 1 : alpha, true); }; const _average_lrgb = (colors, weights) => { const l = colors.length; const xyz = [0,0,0,0]; for (let i=0; i < colors.length; i++) { const col = colors[i]; const f = weights[i] / l; const rgb = col._rgb; xyz[0] += pow(rgb[0],2) * f; xyz[1] += pow(rgb[1],2) * f; xyz[2] += pow(rgb[2],2) * f; xyz[3] += rgb[3] * f; } xyz[0] = sqrt(xyz[0]); xyz[1] = sqrt(xyz[1]); xyz[2] = sqrt(xyz[2]); if (xyz[3] > 0.9999999) xyz[3] = 1; return new Color(clip_rgb(xyz)); }