@makeen.io/material-ui-kit
Version:
Makeen UI components kit. Based on material-ui.
301 lines (293 loc) • 10.8 kB
JavaScript
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";import _createClass from "@babel/runtime/helpers/createClass"; /* eslint-disable default-case */var
Color = /*#__PURE__*/function () {
function Color(r, g, b) {_classCallCheck(this, Color);
this.set(r, g, b);
}_createClass(Color, [{ key: "toString", value: function toString()
{
return "rgb(".concat(Math.round(this.r), ", ").concat(Math.round(this.g), ", ").concat(Math.round(this.b), ")");
} }, { key: "set", value: function set(
r, g, b) {
this.r = this.clamp(r);
this.g = this.clamp(g);
this.b = this.clamp(b);
} }, { key: "hueRotate", value: function hueRotate()
{var angle = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
angle = angle / 180 * Math.PI;
var sin = Math.sin(angle);
var cos = Math.cos(angle);
this.multiply([
0.213 + cos * 0.787 - sin * 0.213,
0.715 - cos * 0.715 - sin * 0.715,
0.072 - cos * 0.072 + sin * 0.928,
0.213 - cos * 0.213 + sin * 0.143,
0.715 + cos * 0.285 + sin * 0.14,
0.072 - cos * 0.072 - sin * 0.283,
0.213 - cos * 0.213 - sin * 0.787,
0.715 - cos * 0.715 + sin * 0.715,
0.072 + cos * 0.928 + sin * 0.072]);
} }, { key: "grayscale", value: function grayscale()
{var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
this.multiply([
0.2126 + 0.7874 * (1 - value),
0.7152 - 0.7152 * (1 - value),
0.0722 - 0.0722 * (1 - value),
0.2126 - 0.2126 * (1 - value),
0.7152 + 0.2848 * (1 - value),
0.0722 - 0.0722 * (1 - value),
0.2126 - 0.2126 * (1 - value),
0.7152 - 0.7152 * (1 - value),
0.0722 + 0.9278 * (1 - value)]);
} }, { key: "sepia", value: function sepia()
{var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
this.multiply([
0.393 + 0.607 * (1 - value),
0.769 - 0.769 * (1 - value),
0.189 - 0.189 * (1 - value),
0.349 - 0.349 * (1 - value),
0.686 + 0.314 * (1 - value),
0.168 - 0.168 * (1 - value),
0.272 - 0.272 * (1 - value),
0.534 - 0.534 * (1 - value),
0.131 + 0.869 * (1 - value)]);
} }, { key: "saturate", value: function saturate()
{var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
this.multiply([
0.213 + 0.787 * value,
0.715 - 0.715 * value,
0.072 - 0.072 * value,
0.213 - 0.213 * value,
0.715 + 0.285 * value,
0.072 - 0.072 * value,
0.213 - 0.213 * value,
0.715 - 0.715 * value,
0.072 + 0.928 * value]);
} }, { key: "multiply", value: function multiply(
matrix) {
var newR = this.clamp(this.r * matrix[0] + this.g * matrix[1] + this.b * matrix[2]);
var newG = this.clamp(this.r * matrix[3] + this.g * matrix[4] + this.b * matrix[5]);
var newB = this.clamp(this.r * matrix[6] + this.g * matrix[7] + this.b * matrix[8]);
this.r = newR;
this.g = newG;
this.b = newB;
} }, { key: "brightness", value: function brightness()
{var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
this.linear(value);
} }, { key: "contrast", value: function contrast()
{var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
this.linear(value, -(0.5 * value) + 0.5);
} }, { key: "linear", value: function linear()
{var slope = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;var intercept = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
this.r = this.clamp(this.r * slope + intercept * 255);
this.g = this.clamp(this.g * slope + intercept * 255);
this.b = this.clamp(this.b * slope + intercept * 255);
} }, { key: "invert", value: function invert()
{var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
this.r = this.clamp((value + this.r / 255 * (1 - 2 * value)) * 255);
this.g = this.clamp((value + this.g / 255 * (1 - 2 * value)) * 255);
this.b = this.clamp((value + this.b / 255 * (1 - 2 * value)) * 255);
} }, { key: "hsl", value: function hsl()
{
// Code taken from https://stackoverflow.com/a/9493060/2688027, licensed under CC BY-SA.
var r = this.r / 255;
var g = this.g / 255;
var b = this.b / 255;
var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var h,s,l = (max + min) / 2;
if (max === min) {
h = s = 0;
} else
{
var d = max - min;
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;
}
return {
h: h * 100,
s: s * 100,
l: l * 100
};
} }, { key: "clamp", value: function clamp(
value) {
if (value > 255) {
value = 255;
} else
if (value < 0) {
value = 0;
}
return value;
} }]);return Color;}();var
Solver = /*#__PURE__*/function () {
function Solver(target, baseColor) {_classCallCheck(this, Solver);
this.target = target;
this.targetHSL = target.hsl();
this.reusedColor = new Color(0, 0, 0);
}_createClass(Solver, [{ key: "solve", value: function solve()
{
var result = this.solveNarrow(this.solveWide());
return {
values: result.values,
loss: result.loss,
filter: this.css(result.values)
};
} }, { key: "solveWide", value: function solveWide()
{
var A = 5;
var c = 15;
var a = [60, 180, 18000, 600, 1.2, 1.2];
var best = { loss: Infinity };
for (var i = 0; best.loss > 25 && i < 3; i++) {
var initial = [50, 20, 3750, 50, 100, 100];
var result = this.spsa(A, a, c, initial, 1000);
if (result.loss < best.loss) {
best = result;
}
}
return best;
} }, { key: "solveNarrow", value: function solveNarrow(
wide) {
var A = wide.loss;
var c = 2;
var A1 = A + 1;
var a = [0.25 * A1, 0.25 * A1, A1, 0.25 * A1, 0.2 * A1, 0.2 * A1];
return this.spsa(A, a, c, wide.values, 500);
} }, { key: "spsa", value: function spsa(
A, a, c, values, iters) {
var alpha = 1;
var gamma = 0.16666666666666666;
var best = null;
var bestLoss = Infinity;
var deltas = new Array(6);
var highArgs = new Array(6);
var lowArgs = new Array(6);
for (var k = 0; k < iters; k++) {
var ck = c / Math.pow(k + 1, gamma);
for (var i = 0; i < 6; i++) {
deltas[i] = Math.random() > 0.5 ? 1 : -1;
highArgs[i] = values[i] + ck * deltas[i];
lowArgs[i] = values[i] - ck * deltas[i];
}
var lossDiff = this.loss(highArgs) - this.loss(lowArgs);
for (var _i = 0; _i < 6; _i++) {
var g = lossDiff / (2 * ck) * deltas[_i];
var ak = a[_i] / Math.pow(A + k + 1, alpha);
values[_i] = fix(values[_i] - ak * g, _i);
}
var loss = this.loss(values);
if (loss < bestLoss) {
best = values.slice(0);
bestLoss = loss;
}
}
return { values: best, loss: bestLoss };
function fix(value, idx) {
var max = 100;
if (idx === 2 /* saturate */) {
max = 7500;
} else
if (idx === 4 /* brightness */ || idx === 5 /* contrast */) {
max = 200;
}
if (idx === 3 /* hue-rotate */) {
if (value > max) {
value %= max;
} else
if (value < 0) {
value = max + value % max;
}
} else
if (value < 0) {
value = 0;
} else
if (value > max) {
value = max;
}
return value;
}
} }, { key: "loss", value: function loss(
filters) {
// Argument is array of percentages.
var color = this.reusedColor;
color.set(0, 0, 0);
color.invert(filters[0] / 100);
color.sepia(filters[1] / 100);
color.saturate(filters[2] / 100);
color.hueRotate(filters[3] * 3.6);
color.brightness(filters[4] / 100);
color.contrast(filters[5] / 100);
var colorHSL = color.hsl();
return Math.abs(color.r - this.target.r) +
Math.abs(color.g - this.target.g) +
Math.abs(color.b - this.target.b) +
Math.abs(colorHSL.h - this.targetHSL.h) +
Math.abs(colorHSL.s - this.targetHSL.s) +
Math.abs(colorHSL.l - this.targetHSL.l);
} }, { key: "css", value: function css(
filters) {
function fmt(idx) {var multiplier = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
return Math.round(filters[idx] * multiplier);
}
return "filter: invert(".concat(fmt(0), "%) sepia(").concat(fmt(1), "%) saturate(").concat(fmt(2), "%) hue-rotate(").concat(fmt(3, 3.6), "deg) brightness(").concat(fmt(4), "%) contrast(").concat(fmt(5), "%);");
} }]);return Solver;}();
function hexToRgb(hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function (m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ?
[
parseInt(result[1], 16),
parseInt(result[2], 16),
parseInt(result[3], 16)] :
null;
}
/**
*
* @param {*} hexCode The color code
* For this code to work well the starting color needs to be black.
* If your icon set isn't black you can prepend "brightness(0) saturate(100%)" to your filter property
* which will first turn the icon set to black.
*/
var getFilterForBlackSvg = function getFilterForBlackSvg(hexCode) {
var rgb = hexToRgb(hexCode);
if (!rgb || rgb.length !== 3) {
console.log("Invalid format!");
return;
}
var color = new Color(rgb[0], rgb[1], rgb[2]);
var solver = new Solver(color);
var result = solver.solve();
var lossMsg;
if (result.loss <= 0.05) {
lossMsg = "This is a perfect result.";
console.log(lossMsg);
return result.filter;
} else
{
if (result.loss < 5) {
lossMsg = "The is close enough.";
} else
if (result.loss < 15) {
lossMsg = "The color is somewhat off. Consider running it again.";
} else
{
lossMsg = "The color is extremely off. Run it again!";
}
console.log(lossMsg);
return getFilterForBlackSvg(hexCode);
}
};
export { getFilterForBlackSvg };
//# sourceMappingURL=color.js.map