UNPKG

@makeen.io/material-ui-kit

Version:
301 lines (293 loc) 10.8 kB
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