aboutsummaryrefslogtreecommitdiffstats
path: root/src/Color.js
blob: de657505b621876a77538417a3633e45d6bc9fde (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* globals fullHex, compToHex */

/*

Color {
  constructor (a, b, c, space) {
    space: 'hsl'
    a: 30
    b: 20
    c: 10
  },

  toRgb () { return new Color in rgb space }
  toHsl () { return new Color in hsl space }
  toLab () { return new Color in lab space }

  toArray () { [space, a, b, c] }
  fromArray () { convert it back }
}

// Conversions aren't always exact because of monitor profiles etc...
new Color(h, s, l, 'hsl') !== new Color(r, g, b).hsl()
new Color(100, 100, 100, [space])
new Color('hsl(30, 20, 10)')

// Sugar
SVG.rgb(30, 20, 50).lab()
SVG.hsl()
SVG.lab('rgb(100, 100, 100)')
*/

import {isHex, isRgb, whitespace, rgb, hex} from './regex.js'
import {fullHex, compToHex} from './helpers.js'

export default class Color {
  constructor (...args) {
    this.init(...args)
  }

  init (color, g, b) {
    let match

    // initialize defaults
    this.r = 0
    this.g = 0
    this.b = 0

    if (!color) return

    // parse color
    if (typeof color === 'string') {
      if (isRgb.test(color)) {
        // get rgb values
        match = rgb.exec(color.replace(whitespace, ''))

        // parse numeric values
        this.r = parseInt(match[1])
        this.g = parseInt(match[2])
        this.b = parseInt(match[3])
      } else if (isHex.test(color)) {
        // get hex values
        match = hex.exec(fullHex(color))

        // parse numeric values
        this.r = parseInt(match[1], 16)
        this.g = parseInt(match[2], 16)
        this.b = parseInt(match[3], 16)
      }
    } else if (Array.isArray(color)) {
      this.r = color[0]
      this.g = color[1]
      this.b = color[2]
    } else if (typeof color === 'object') {
      this.r = color.r
      this.g = color.g
      this.b = color.b
    } else if (arguments.length === 3) {
      this.r = color
      this.g = g
      this.b = b
    }
  }

  // Default to hex conversion
  toString () {
    return this.toHex()
  }

  toArray () {
    return [this.r, this.g, this.b]
  }

  // Build hex value
  toHex () {
    return '#' +
      compToHex(Math.round(this.r)) +
      compToHex(Math.round(this.g)) +
      compToHex(Math.round(this.b))
  }

  // Build rgb value
  toRgb () {
    return 'rgb(' + [this.r, this.g, this.b].join() + ')'
  }

  // Calculate true brightness
  brightness () {
    return (this.r / 255 * 0.30) +
      (this.g / 255 * 0.59) +
      (this.b / 255 * 0.11)
  }

  // Testers

  // Test if given value is a color string
  static test (color) {
    color += ''
    return isHex.test(color) || isRgb.test(color)
  }

  // Test if given value is a rgb object
  static isRgb (color) {
    return color && typeof color.r === 'number' &&
      typeof color.g === 'number' &&
      typeof color.b === 'number'
  }

  // Test if given value is a color
  static isColor (color) {
    return this.isRgb(color) || this.test(color)
  }
}