2017-01-31 07:50:28 +01:00
|
|
|
const Colors = require('../const/colors');
|
2015-10-17 23:49:24 +02:00
|
|
|
|
2017-01-31 07:50:28 +01:00
|
|
|
const KnownColors = {};
|
2015-10-17 23:49:24 +02:00
|
|
|
|
2017-01-31 07:50:28 +01:00
|
|
|
const Color = function(str) {
|
|
|
|
const start = str[0] === '#' ? 1 : 0;
|
|
|
|
const len = str.length === 3 ? 1 : 2;
|
2015-10-17 23:49:24 +02:00
|
|
|
this.r = parseInt(str.substr(start, len), 16);
|
|
|
|
this.g = parseInt(str.substr(start + len, len), 16);
|
|
|
|
this.b = parseInt(str.substr(start + len * 2, len), 16);
|
|
|
|
this.setHsl();
|
|
|
|
};
|
|
|
|
|
|
|
|
Color.prototype.setHsl = function() {
|
2017-01-31 07:50:28 +01:00
|
|
|
const r = this.r / 255;
|
|
|
|
const g = this.g / 255;
|
|
|
|
const b = this.b / 255;
|
2015-10-17 23:49:24 +02:00
|
|
|
|
2017-01-31 07:50:28 +01:00
|
|
|
const max = Math.max(r, g, b);
|
|
|
|
const min = Math.min(r, g, b);
|
|
|
|
let h;
|
|
|
|
let s;
|
|
|
|
const l = (max + min) / 2;
|
2015-10-17 23:49:24 +02:00
|
|
|
|
|
|
|
if (max === min) {
|
|
|
|
h = s = 0; // achromatic
|
|
|
|
} else {
|
2017-01-31 07:50:28 +01:00
|
|
|
const d = max - min;
|
2015-10-17 23:49:24 +02:00
|
|
|
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
|
|
switch (max) {
|
|
|
|
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
|
|
|
case g: h = (b - r) / d + 2; break;
|
|
|
|
case b: h = (r - g) / d + 4; break;
|
|
|
|
}
|
|
|
|
h /= 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.h = h;
|
|
|
|
this.s = s;
|
|
|
|
this.l = l;
|
|
|
|
};
|
|
|
|
|
|
|
|
Color.prototype.toHex = function() {
|
2015-10-23 22:11:28 +02:00
|
|
|
return '#' + hex(this.r) + hex(this.g) + hex(this.b);
|
2015-10-17 23:49:24 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
Color.prototype.distanceTo = function(color) {
|
|
|
|
return Math.abs(this.h - color.h);
|
|
|
|
};
|
|
|
|
|
|
|
|
Color.getNearest = function(colorStr) {
|
2017-01-31 07:50:28 +01:00
|
|
|
const color = new Color(colorStr);
|
2015-10-17 23:49:24 +02:00
|
|
|
if (!color.s) {
|
|
|
|
return null;
|
|
|
|
}
|
2017-01-31 07:50:28 +01:00
|
|
|
let selected = null,
|
|
|
|
minDistance = Number.MAX_VALUE;
|
2016-07-17 13:30:38 +02:00
|
|
|
_.forEach(KnownColors, (col, name) => {
|
2017-01-31 07:50:28 +01:00
|
|
|
const distance = color.distanceTo(col);
|
2015-10-17 23:49:24 +02:00
|
|
|
if (distance < minDistance) {
|
|
|
|
minDistance = distance;
|
|
|
|
selected = name;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return selected;
|
|
|
|
};
|
|
|
|
|
|
|
|
Color.getKnownBgColor = function(knownColor) {
|
2015-10-23 22:11:28 +02:00
|
|
|
return Colors.BgColors[knownColor] ? '#' + Colors.BgColors[knownColor] : undefined;
|
2015-10-17 23:49:24 +02:00
|
|
|
};
|
|
|
|
|
2016-07-17 13:30:38 +02:00
|
|
|
_.forEach(Colors.ColorsValues, (val, name) => {
|
2015-10-17 23:49:24 +02:00
|
|
|
KnownColors[name] = new Color(val);
|
|
|
|
});
|
|
|
|
|
|
|
|
function hex(num) {
|
2017-01-31 07:50:28 +01:00
|
|
|
const str = (num || 0).toString(16);
|
2015-10-17 23:49:24 +02:00
|
|
|
return str.length < 2 ? '0' + str : str;
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = Color;
|