Atom/src/color.js

130 lines
2.8 KiB
JavaScript

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 }
break
default:
return null
}
if (!ParsedColor) {
ParsedColor = require('color')
}
try {
var parsedColor = new 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
}