@onesy/utils
Version:
42 lines (36 loc) • 1.49 kB
JavaScript
const colorRange = value => {
const min = new Array(3).fill(Number.MAX_VALUE);
const max = new Array(3).fill(Number.MIN_VALUE);
value.forEach(item => {
item.forEach((value_, index) => {
min[index] = Math.min(min[index], value_);
max[index] = Math.max(max[index], value_);
});
});
const ranges = min.map((item, index) => max[index] - item);
const maxRange = Math.max(...ranges);
if (maxRange === ranges[0]) return 0;else if (maxRange === ranges[1]) return 1;
return 2;
};
const quantizeMethod = function (value) {
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
const MAX_DEPTH = 7;
if (!value.length) return [];
if (MAX_DEPTH === depth) {
const color = value.reduce((result, item) => {
item.forEach((value_, index) => result[index] += value_);
return result;
}, [0, 0, 0]);
return [color.map(item => Math.round(item / value.length))];
}
const sortIndex = colorRange(value);
value.sort((a, b) => a[sortIndex] - b[sortIndex]);
const mid = value.length / 2; // Reverse so primary is a first value
return [...quantizeMethod(value.slice(0, mid), depth + 1), ...quantizeMethod(value.slice(mid + 1), depth + 1)].reverse();
};
const quantize = function (value) {
let amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4;
const depth = 7 - Math.ceil(Math.log2(amount));
return quantizeMethod(value, depth).slice(0, amount);
};
export default quantize;