1
+ ; ( function ( root , factory ) {
2
+
3
+ // Support AMD
4
+ if ( typeof define === 'function' && define . amd ) {
5
+ define ( [ ] , factory ) ;
6
+
7
+ // Support CommonJS
8
+ } else if ( typeof exports === 'object' ) {
9
+ var randomColor = factory ( ) ;
10
+
11
+ // Support NodeJS & Component, which allow module.exports to be a function
12
+ if ( typeof module === 'object' && module && module . exports ) {
13
+ exports = module . exports = randomColor ;
14
+ }
15
+
16
+ // Support CommonJS 1.1.1 spec
17
+ exports . randomColor = randomColor ;
18
+
19
+ // Support vanilla script loading
20
+ } else {
21
+ root . randomColor = factory ( ) ;
22
+ } ;
23
+
24
+ } ( this , function ( ) {
25
+
26
+ // Shared color dictionary
27
+ var colorDictionary = { } ;
28
+
29
+ // Populate the color dictionary
30
+ loadColorBounds ( ) ;
31
+
32
+ var randomColor = function ( options ) {
33
+ options = options || { } ;
34
+
35
+ var H , S , B ;
36
+
37
+ // Check if we need to generate multiple colors
38
+ if ( options . count ) {
39
+
40
+ var totalColors = options . count ,
41
+ colors = [ ] ;
42
+
43
+ options . count = false ;
44
+
45
+ while ( totalColors > colors . length ) {
46
+ colors . push ( randomColor ( options ) ) ;
47
+ }
48
+
49
+ return colors ;
50
+ }
51
+
52
+ // First we pick a hue (H)
53
+ H = pickHue ( options ) ;
54
+
55
+ // Then use H to determine saturation (S)
56
+ S = pickSaturation ( H , options ) ;
57
+
58
+ // Then use S and H to determine brightness (B).
59
+ B = pickBrightness ( H , S , options ) ;
60
+
61
+ // Then we return the HSB color in the desired format
62
+ return setFormat ( [ H , S , B ] , options ) ;
63
+ } ;
64
+
65
+ function pickHue ( options ) {
66
+
67
+ var hueRange = getHueRange ( options . hue ) ,
68
+ hue = randomWithin ( hueRange ) ;
69
+
70
+ // Instead of storing red as two seperate ranges,
71
+ // we group them, using negative numbers
72
+ if ( hue < 0 ) { hue = 360 + hue }
73
+
74
+ return hue ;
75
+
76
+ }
77
+
78
+ function pickSaturation ( hue , options ) {
79
+
80
+ if ( options . luminosity === 'random' ) {
81
+ return randomWithin ( [ 0 , 100 ] ) ;
82
+ }
83
+
84
+ if ( options . hue === 'monochrome' ) {
85
+ return 0 ;
86
+ }
87
+
88
+ var saturationRange = getSaturationRange ( hue ) ;
89
+
90
+ var sMin = saturationRange [ 0 ] ,
91
+ sMax = saturationRange [ 1 ] ;
92
+
93
+ switch ( options . luminosity ) {
94
+
95
+ case 'bright' :
96
+ sMin = 55 ;
97
+ break ;
98
+
99
+ case 'dark' :
100
+ sMin = sMax - 10 ;
101
+ break ;
102
+
103
+ case 'light' :
104
+ sMax = 55 ;
105
+ break ;
106
+ }
107
+
108
+ return randomWithin ( [ sMin , sMax ] ) ;
109
+
110
+ }
111
+
112
+ function pickBrightness ( H , S , options ) {
113
+
114
+ var brightness ,
115
+ bMin = getMinimumBrightness ( H , S ) ,
116
+ bMax = 100 ;
117
+
118
+ switch ( options . luminosity ) {
119
+
120
+ case 'dark' :
121
+ bMax = bMin + 20 ;
122
+ break ;
123
+
124
+ case 'light' :
125
+ bMin = ( bMax + bMin ) / 2 ;
126
+ break ;
127
+
128
+ case 'random' :
129
+ bMin = 0 ;
130
+ bMax = 100 ;
131
+ break ;
132
+ }
133
+
134
+ return randomWithin ( [ bMin , bMax ] ) ;
135
+
136
+ }
137
+
138
+ function setFormat ( hsv , options ) {
139
+
140
+ switch ( options . format ) {
141
+
142
+ case 'hsvArray' :
143
+ return hsv ;
144
+
145
+ case 'hsv' :
146
+ return colorString ( 'hsv' , hsv ) ;
147
+
148
+ case 'rgbArray' :
149
+ return HSVtoRGB ( hsv ) ;
150
+
151
+ case 'rgb' :
152
+ return colorString ( 'rgb' , HSVtoRGB ( hsv ) ) ;
153
+
154
+ default :
155
+ return HSVtoHex ( hsv ) ;
156
+ }
157
+
158
+ }
159
+
160
+ function getMinimumBrightness ( H , S ) {
161
+
162
+ var lowerBounds = getColorInfo ( H ) . lowerBounds ;
163
+
164
+ for ( var i = 0 ; i < lowerBounds . length - 1 ; i ++ ) {
165
+
166
+ var s1 = lowerBounds [ i ] [ 0 ] ,
167
+ v1 = lowerBounds [ i ] [ 1 ] ;
168
+
169
+ var s2 = lowerBounds [ i + 1 ] [ 0 ] ,
170
+ v2 = lowerBounds [ i + 1 ] [ 1 ] ;
171
+
172
+ if ( S >= s1 && S <= s2 ) {
173
+
174
+ var m = ( v2 - v1 ) / ( s2 - s1 ) ,
175
+ b = v1 - m * s1 ;
176
+
177
+ return m * S + b ;
178
+ }
179
+
180
+ }
181
+
182
+ return 0 ;
183
+ }
184
+
185
+ function getHueRange ( colorInput ) {
186
+
187
+ if ( typeof parseInt ( colorInput ) === 'number' ) {
188
+
189
+ var number = parseInt ( colorInput ) ;
190
+
191
+ if ( number < 360 && number > 0 ) {
192
+ return [ number , number ] ;
193
+ }
194
+
195
+ }
196
+
197
+ if ( typeof colorInput === 'string' ) {
198
+
199
+ if ( colorDictionary [ colorInput ] ) {
200
+ var color = colorDictionary [ colorInput ] ;
201
+ if ( color . hueRange ) { return color . hueRange }
202
+ }
203
+ }
204
+
205
+ return [ 0 , 360 ] ;
206
+
207
+ }
208
+
209
+ function getSaturationRange ( hue ) {
210
+ return getColorInfo ( hue ) . saturationRange ;
211
+ }
212
+
213
+ function getColorInfo ( hue ) {
214
+
215
+ // Maps red colors to make picking hue easier
216
+ if ( hue >= 334 && hue <= 360 ) {
217
+ hue -= 360 ;
218
+ }
219
+
220
+ for ( var colorName in colorDictionary ) {
221
+ var color = colorDictionary [ colorName ] ;
222
+ if ( color . hueRange &&
223
+ hue >= color . hueRange [ 0 ] &&
224
+ hue <= color . hueRange [ 1 ] ) {
225
+ return colorDictionary [ colorName ] ;
226
+ }
227
+ } return 'Color not found' ;
228
+ }
229
+
230
+ function randomWithin ( range ) {
231
+ return Math . floor ( range [ 0 ] + Math . random ( ) * ( range [ 1 ] + 1 - range [ 0 ] ) ) ;
232
+ }
233
+
234
+ function shiftHue ( h , degrees ) {
235
+ return ( h + degrees ) % 360 ;
236
+ }
237
+
238
+ function HSVtoHex ( hsv ) {
239
+
240
+ var rgb = HSVtoRGB ( hsv ) ;
241
+
242
+ function componentToHex ( c ) {
243
+ var hex = c . toString ( 16 ) ;
244
+ return hex . length == 1 ? "0" + hex : hex ;
245
+ }
246
+
247
+ var hex = "#" + componentToHex ( rgb [ 0 ] ) + componentToHex ( rgb [ 1 ] ) + componentToHex ( rgb [ 2 ] ) ;
248
+
249
+ return hex ;
250
+
251
+ }
252
+
253
+ function defineColor ( name , hueRange , lowerBounds ) {
254
+
255
+ var sMin = lowerBounds [ 0 ] [ 0 ] ,
256
+ sMax = lowerBounds [ lowerBounds . length - 1 ] [ 0 ] ,
257
+
258
+ bMin = lowerBounds [ lowerBounds . length - 1 ] [ 1 ] ,
259
+ bMax = lowerBounds [ 0 ] [ 1 ] ;
260
+
261
+ colorDictionary [ name ] = {
262
+ hueRange : hueRange ,
263
+ lowerBounds : lowerBounds ,
264
+ saturationRange : [ sMin , sMax ] ,
265
+ brightnessRange : [ bMin , bMax ]
266
+ } ;
267
+
268
+ }
269
+
270
+ function loadColorBounds ( ) {
271
+
272
+ defineColor (
273
+ 'monochrome' ,
274
+ null ,
275
+ [ [ 0 , 0 ] , [ 100 , 0 ] ]
276
+ ) ;
277
+
278
+ defineColor (
279
+ 'red' ,
280
+ [ - 26 , 18 ] ,
281
+ [ [ 20 , 100 ] , [ 30 , 92 ] , [ 40 , 89 ] , [ 50 , 85 ] , [ 60 , 78 ] , [ 70 , 70 ] , [ 80 , 60 ] , [ 90 , 55 ] , [ 100 , 50 ] ]
282
+ ) ;
283
+
284
+ defineColor (
285
+ 'orange' ,
286
+ [ 19 , 46 ] ,
287
+ [ [ 20 , 100 ] , [ 30 , 93 ] , [ 40 , 88 ] , [ 50 , 86 ] , [ 60 , 85 ] , [ 70 , 70 ] , [ 100 , 70 ] ]
288
+ ) ;
289
+
290
+ defineColor (
291
+ 'yellow' ,
292
+ [ 47 , 62 ] ,
293
+ [ [ 25 , 100 ] , [ 40 , 94 ] , [ 50 , 89 ] , [ 60 , 86 ] , [ 70 , 84 ] , [ 80 , 82 ] , [ 90 , 80 ] , [ 100 , 75 ] ]
294
+ ) ;
295
+
296
+ defineColor (
297
+ 'green' ,
298
+ [ 63 , 178 ] ,
299
+ [ [ 30 , 100 ] , [ 40 , 90 ] , [ 50 , 85 ] , [ 60 , 81 ] , [ 70 , 74 ] , [ 80 , 64 ] , [ 90 , 50 ] , [ 100 , 40 ] ]
300
+ ) ;
301
+
302
+ defineColor (
303
+ 'blue' ,
304
+ [ 179 , 257 ] ,
305
+ [ [ 20 , 100 ] , [ 30 , 86 ] , [ 40 , 80 ] , [ 50 , 74 ] , [ 60 , 60 ] , [ 70 , 52 ] , [ 80 , 44 ] , [ 90 , 39 ] , [ 100 , 35 ] ]
306
+ ) ;
307
+
308
+ defineColor (
309
+ 'purple' ,
310
+ [ 258 , 282 ] ,
311
+ [ [ 20 , 100 ] , [ 30 , 87 ] , [ 40 , 79 ] , [ 50 , 70 ] , [ 60 , 65 ] , [ 70 , 59 ] , [ 80 , 52 ] , [ 90 , 45 ] , [ 100 , 42 ] ]
312
+ ) ;
313
+
314
+ defineColor (
315
+ 'pink' ,
316
+ [ 283 , 334 ] ,
317
+ [ [ 20 , 100 ] , [ 30 , 90 ] , [ 40 , 86 ] , [ 60 , 84 ] , [ 80 , 80 ] , [ 90 , 75 ] , [ 100 , 73 ] ]
318
+ ) ;
319
+
320
+ }
321
+
322
+ function HSVtoRGB ( hsv ) {
323
+
324
+ // this doesn't work for the values of 0 and 360
325
+ // here's the hacky fix
326
+ var h = hsv [ 0 ] ;
327
+ if ( h === 0 ) { h = 1 }
328
+ if ( h === 360 ) { h = 359 }
329
+
330
+ // Rebase the h,s,v values
331
+ h = h / 360 ;
332
+ var s = hsv [ 1 ] / 100 ,
333
+ v = hsv [ 2 ] / 100 ;
334
+
335
+ var h_i = Math . floor ( h * 6 ) ,
336
+ f = h * 6 - h_i ,
337
+ p = v * ( 1 - s ) ,
338
+ q = v * ( 1 - f * s ) ,
339
+ t = v * ( 1 - ( 1 - f ) * s ) ,
340
+ r = 256 ,
341
+ g = 256 ,
342
+ b = 256 ;
343
+
344
+ switch ( h_i ) {
345
+ case 0 : r = v , g = t , b = p ; break ;
346
+ case 1 : r = q , g = v , b = p ; break ;
347
+ case 2 : r = p , g = v , b = t ; break ;
348
+ case 3 : r = p , g = q , b = v ; break ;
349
+ case 4 : r = t , g = p , b = v ; break ;
350
+ case 5 : r = v , g = p , b = q ; break ;
351
+ }
352
+ var result = [ Math . floor ( r * 255 ) , Math . floor ( g * 255 ) , Math . floor ( b * 255 ) ] ;
353
+ return result ;
354
+ }
355
+
356
+ function colorString ( prefix , values ) {
357
+ return prefix + '(' + values . join ( ', ' ) + ')' ;
358
+ }
359
+
360
+ return randomColor ;
361
+ } ) ) ;
0 commit comments