summaryrefslogtreecommitdiffstats
path: root/src/Color.js
blob: 1e2befbe0550d20ed4dc6473e6c02a18d5e8fd25 (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
/* 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} from './regex.js'

export default class Color {
  constructor (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)
  }
}