Permalink
143 lines (118 sloc)
2.9 KB
| let ParsedColor = null; | |
| // Essential: A simple color class returned from {Config::get} when the value | |
| // at the key path is of type 'color'. | |
| module.exports = class Color { | |
| // Essential: Parse a {String} or {Object} into a {Color}. | |
| // | |
| // * `value` A {String} such as `'white'`, `#ff00ff`, or | |
| // `'rgba(255, 15, 60, .75)'` or an {Object} with `red`, `green`, `blue`, | |
| // and `alpha` properties. | |
| // | |
| // Returns a {Color} or `null` if it cannot be parsed. | |
| static parse(value) { | |
| switch (typeof value) { | |
| case 'string': | |
| break; | |
| case 'object': | |
| if (Array.isArray(value)) { | |
| return null; | |
| } | |
| value = Object.values(value); | |
| break; | |
| default: | |
| return null; | |
| } | |
| if (!ParsedColor) { | |
| ParsedColor = require('color'); | |
| } | |
| try { | |
| var parsedColor = ParsedColor(value); | |
| } catch (error) { | |
| return null; | |
| } | |
| return new Color( | |
| parsedColor.red(), | |
| parsedColor.green(), | |
| parsedColor.blue(), | |
| parsedColor.alpha() | |
| ); | |
| } | |
| constructor(red, green, blue, alpha) { | |
| this.red = red; | |
| this.green = green; | |
| this.blue = blue; | |
| this.alpha = alpha; | |
| } | |
| set red(red) { | |
| this._red = parseColor(red); | |
| } | |
| set green(green) { | |
| this._green = parseColor(green); | |
| } | |
| set blue(blue) { | |
| this._blue = parseColor(blue); | |
| } | |
| set alpha(alpha) { | |
| this._alpha = parseAlpha(alpha); | |
| } | |
| get red() { | |
| return this._red; | |
| } | |
| get green() { | |
| return this._green; | |
| } | |
| get blue() { | |
| return this._blue; | |
| } | |
| get alpha() { | |
| return this._alpha; | |
| } | |
| // Essential: Returns a {String} in the form `'#abcdef'`. | |
| toHexString() { | |
| return `#${numberToHexString(this.red)}${numberToHexString( | |
| this.green | |
| )}${numberToHexString(this.blue)}`; | |
| } | |
| // Essential: Returns a {String} in the form `'rgba(25, 50, 75, .9)'`. | |
| toRGBAString() { | |
| return `rgba(${this.red}, ${this.green}, ${this.blue}, ${this.alpha})`; | |
| } | |
| toJSON() { | |
| return this.alpha === 1 ? this.toHexString() : this.toRGBAString(); | |
| } | |
| toString() { | |
| return this.toRGBAString(); | |
| } | |
| isEqual(color) { | |
| if (this === color) { | |
| return true; | |
| } | |
| if (!(color instanceof Color)) { | |
| color = Color.parse(color); | |
| } | |
| if (color == null) { | |
| return false; | |
| } | |
| return ( | |
| color.red === this.red && | |
| color.blue === this.blue && | |
| color.green === this.green && | |
| color.alpha === this.alpha | |
| ); | |
| } | |
| clone() { | |
| return new Color(this.red, this.green, this.blue, this.alpha); | |
| } | |
| }; | |
| function parseColor(colorString) { | |
| const color = parseInt(colorString, 10); | |
| return isNaN(color) ? 0 : Math.min(Math.max(color, 0), 255); | |
| } | |
| function parseAlpha(alphaString) { | |
| const alpha = parseFloat(alphaString); | |
| return isNaN(alpha) ? 1 : Math.min(Math.max(alpha, 0), 1); | |
| } | |
| function numberToHexString(number) { | |
| const hex = number.toString(16); | |
| return number < 16 ? `0${hex}` : hex; | |
| } |

