1
1
class GradientColor {
2
- constructor ( startColor = "" , endColor = "" , minNum = 0 , maxNum = 10 ) {
3
- this . setColorGradient = ( colorStart , colorEnd ) => {
4
- startColor = getHexColor ( colorStart ) ;
5
- endColor = getHexColor ( colorEnd ) ;
6
- } ;
7
-
8
- this . setMidpoint = ( minNumber , maxNumber ) => {
9
- minNum = minNumber ;
10
- maxNum = maxNumber ;
11
- } ;
12
-
13
- this . getColor = ( numberValue ) => {
14
- if ( numberValue ) {
15
- return (
16
- "#" +
17
- generateHex (
18
- numberValue ,
19
- startColor . substring ( 0 , 2 ) ,
20
- endColor . substring ( 0 , 2 )
21
- ) +
22
- generateHex (
23
- numberValue ,
24
- startColor . substring ( 2 , 4 ) ,
25
- endColor . substring ( 2 , 4 )
26
- ) +
27
- generateHex (
28
- numberValue ,
29
- startColor . substring ( 4 , 6 ) ,
30
- endColor . substring ( 4 , 6 )
31
- )
32
- ) ;
33
- }
34
- } ;
2
+ constructor ( ) {
3
+ this . minNum = 0 ;
4
+ this . maxNum = 10 ;
5
+ this . startHex = "" ;
6
+ this . endHex = "" ;
7
+ }
35
8
36
- const generateHex = ( number , start , end ) => {
37
- if ( number < minNum ) {
38
- number = minNum ;
39
- } else if ( number > maxNum ) {
40
- number = maxNum ;
41
- }
9
+ setColorGradient ( colorStart , colorEnd ) {
10
+ if ( ! colorStart . startsWith ( "#" ) || ! colorEnd . startsWith ( "#" ) ) {
11
+ throw new Error ( 'Colors must be in hexadecimal format starting with "#"' ) ;
12
+ }
13
+
14
+ this . startHex = this . validateAndExpandHex ( colorStart ) ;
15
+ this . endHex = this . validateAndExpandHex ( colorEnd ) ;
16
+ }
17
+
18
+ validateAndExpandHex ( hex ) {
19
+ if ( hex . length === 4 ) {
20
+ return "#" + hex [ 1 ] + hex [ 1 ] + hex [ 2 ] + hex [ 2 ] + hex [ 3 ] + hex [ 3 ] ;
21
+ } else if ( hex . length === 7 ) {
22
+ return hex ;
23
+ } else {
24
+ throw new Error (
25
+ "Invalid color format. Please use full hex color values (e.g., #3f2caf) instead of abbreviated formats" ,
26
+ ) ;
27
+ }
28
+ }
29
+
30
+ setMidpoint ( minNumber = 0 , maxNumber = 10 ) {
31
+ this . minNum = minNumber ;
32
+ this . maxNum = maxNumber ;
33
+ }
34
+
35
+ getColor ( numberValue ) {
36
+ if ( numberValue === undefined ) return ;
37
+
38
+ return (
39
+ "#" +
40
+ this . generateHex (
41
+ numberValue ,
42
+ this . startHex . substring ( 1 , 3 ) ,
43
+ this . endHex . substring ( 1 , 3 ) ,
44
+ ) +
45
+ this . generateHex (
46
+ numberValue ,
47
+ this . startHex . substring ( 3 , 5 ) ,
48
+ this . endHex . substring ( 3 , 5 ) ,
49
+ ) +
50
+ this . generateHex (
51
+ numberValue ,
52
+ this . startHex . substring ( 5 , 7 ) ,
53
+ this . endHex . substring ( 5 , 7 ) ,
54
+ )
55
+ ) ;
56
+ }
42
57
43
- const midPoint = maxNum - minNum ;
44
- const startBase = parseInt ( start , 16 ) ;
45
- const endBase = parseInt ( end , 16 ) ;
46
- const average = ( endBase - startBase ) / midPoint ;
47
- const finalBase = Math . round ( average * ( number - minNum ) + startBase ) ;
48
- const balancedFinalBase =
49
- finalBase < 16 ? "0" + finalBase . toString ( 16 ) : finalBase . toString ( 16 ) ;
50
- return balancedFinalBase ;
51
- } ;
52
-
53
- const getHexColor = ( color ) => {
54
- return color . substring ( color . length - 6 , color . length ) ;
55
- } ;
58
+ generateHex ( number , start , end ) {
59
+ if ( number < this . minNum ) number = this . minNum ;
60
+ else if ( number > this . maxNum ) number = this . maxNum ;
61
+
62
+ const midPoint = this . maxNum - this . minNum ;
63
+ const startBase = parseInt ( start , 16 ) ;
64
+ const endBase = parseInt ( end , 16 ) ;
65
+ const average = ( endBase - startBase ) / midPoint ;
66
+ const finalBase = Math . round ( average * ( number - this . minNum ) + startBase ) ;
67
+ return finalBase . toString ( 16 ) . padStart ( 2 , "0" ) ;
56
68
}
57
69
}
58
70
59
71
class Gradient {
60
- constructor (
61
- colorGradients = "" ,
62
- maxNum = 10 ,
63
- colors = [ "" , "" ] ,
64
- intervals = [ ]
65
- ) {
66
- const setColorGradient = ( gradientColors ) => {
67
- if ( gradientColors . length < 2 ) {
68
- throw new Error (
69
- `setColorGradient should have more than ${ gradientColors . length } color`
70
- ) ;
71
- } else {
72
- const increment = maxNum / ( gradientColors . length - 1 ) ;
73
- const firstColorGradient = new GradientColor ( ) ;
74
- const lower = 0 ;
75
- const upper = 0 + increment ;
76
- firstColorGradient . setColorGradient (
77
- gradientColors [ 0 ] ,
78
- gradientColors [ 1 ]
79
- ) ;
80
- firstColorGradient . setMidpoint ( lower , upper ) ;
81
- colorGradients = [ firstColorGradient ] ;
82
- intervals = [
83
- {
84
- lower,
85
- upper,
86
- } ,
87
- ] ;
88
-
89
- for ( let i = 1 ; i < gradientColors . length - 1 ; i ++ ) {
90
- const gradientColor = new GradientColor ( ) ;
91
- const lower = 0 + increment * i ;
92
- const upper = 0 + increment * ( i + 1 ) ;
93
- gradientColor . setColorGradient (
94
- gradientColors [ i ] ,
95
- gradientColors [ i + 1 ]
96
- ) ;
97
- gradientColor . setMidpoint ( lower , upper ) ;
98
- colorGradients [ i ] = gradientColor ;
99
- intervals [ i ] = {
100
- lower,
101
- upper,
102
- } ;
103
- }
104
- colors = gradientColors ;
105
- }
106
- } ;
107
-
108
- this . setColorGradient = ( ...gradientColors ) => {
109
- setColorGradient ( gradientColors ) ;
110
- return this ;
111
- } ;
112
-
113
- this . getColors = ( ) => {
114
- const gradientColorsArray = [ ] ;
115
- for ( let j = 0 ; j < intervals . length ; j ++ ) {
116
- const interval = intervals [ j ] ;
117
- const start = interval . lower === 0 ? 1 : Math . ceil ( interval . lower ) ;
118
- const end =
119
- interval . upper === maxNum
120
- ? interval . upper + 1
121
- : Math . ceil ( interval . upper ) ;
122
- for ( let i = start ; i < end ; i ++ ) {
123
- gradientColorsArray . push ( colorGradients [ j ] . getColor ( i ) ) ;
124
- }
125
- }
126
- return gradientColorsArray ;
127
- } ;
128
-
129
- this . getColor = ( numberValue ) => {
130
- if ( isNaN ( numberValue ) ) {
131
- throw new TypeError ( `getColor should be a number` ) ;
132
- } else if ( numberValue <= 0 ) {
133
- throw new TypeError ( `getColor should be greater than ${ numberValue } ` ) ;
134
- } else {
135
- const toInsert = numberValue + 1 ;
136
- const segment = ( maxNum - 0 ) / colorGradients . length ;
137
- const index = Math . min (
138
- Math . floor ( ( Math . max ( numberValue , 0 ) - 0 ) / segment ) ,
139
- colorGradients . length - 1
140
- ) ;
141
- return colorGradients [ index ] . getColor ( toInsert ) ;
142
- }
143
- } ;
144
-
145
- this . setMidpoint = ( maxNumber ) => {
146
- if ( ! isNaN ( maxNumber ) && maxNumber >= 0 ) {
147
- maxNum = maxNumber ;
148
- setColorGradient ( colors ) ;
149
- } else if ( maxNumber <= 0 ) {
150
- throw new RangeError ( `midPoint should be greater than ${ maxNumber } ` ) ;
151
- } else {
152
- throw new RangeError ( "midPoint should be a number" ) ;
72
+ constructor ( ) {
73
+ this . maxNum = 10 ;
74
+ this . colors = [ ] ;
75
+ this . colorGradients = [ ] ;
76
+ this . intervals = [ ] ;
77
+ }
78
+
79
+ setColorGradient ( ...gradientColors ) {
80
+ if ( gradientColors . length < 2 ) {
81
+ throw new RangeError ( `setColorGradient requires at least 2 colors` ) ;
82
+ }
83
+
84
+ const increment = ( this . maxNum - 1 ) / ( gradientColors . length - 1 ) ;
85
+ this . colorGradients = [ ] ;
86
+ this . intervals = [ ] ;
87
+
88
+ for ( let i = 0 ; i < gradientColors . length - 1 ; i ++ ) {
89
+ const gradientColor = new GradientColor ( ) ;
90
+ const lower = increment * i ;
91
+ const upper = increment * ( i + 1 ) ;
92
+ gradientColor . setColorGradient ( gradientColors [ i ] , gradientColors [ i + 1 ] ) ;
93
+ gradientColor . setMidpoint ( lower , upper ) ;
94
+ this . colorGradients . push ( gradientColor ) ;
95
+ this . intervals . push ( { lower, upper } ) ;
96
+ }
97
+ this . colors = gradientColors ;
98
+ return this ;
99
+ }
100
+
101
+ getColors ( ) {
102
+ const gradientColorsArray = [ ] ;
103
+ const numColors = this . maxNum + 1 ;
104
+
105
+ for ( let j = 0 ; j < this . intervals . length ; j ++ ) {
106
+ const { lower, upper } = this . intervals [ j ] ;
107
+ const start = j === 0 ? 0 : Math . ceil ( lower ) ;
108
+ const end = j === this . intervals . length - 1 ? Math . ceil ( upper ) : Math . floor ( upper ) ;
109
+
110
+ for ( let i = start ; i < end ; i ++ ) {
111
+ gradientColorsArray . push ( this . colorGradients [ j ] . getColor ( i ) ) ;
153
112
}
154
- return this ;
155
- } ;
113
+ }
114
+
115
+ gradientColorsArray . push ( this . colors [ this . colors . length - 1 ] ) ;
116
+ return gradientColorsArray . slice ( 0 , numColors ) ;
117
+ }
118
+
119
+ getColor ( numberValue ) {
120
+ if ( isNaN ( numberValue ) ) {
121
+ throw new TypeError ( `getColor requires a numeric value` ) ;
122
+ }
123
+ if ( numberValue <= 0 ) {
124
+ throw new RangeError ( `getColor value should be greater than 0` ) ;
125
+ }
126
+
127
+ const segment = ( this . maxNum + 1 ) / this . colorGradients . length ;
128
+ const index = Math . min ( Math . floor ( numberValue / segment ) , this . colorGradients . length - 1 ) ;
129
+ return this . colorGradients [ index ] . getColor ( numberValue ) ;
130
+ }
131
+
132
+ setMidpoint ( maxNumber = 10 ) {
133
+ if ( isNaN ( maxNumber ) || maxNumber < this . colors . length ) {
134
+ throw new RangeError (
135
+ `setMidpoint should be a number greater than or equal to the number of colors` ,
136
+ ) ;
137
+ }
138
+
139
+ this . maxNum = maxNumber ;
140
+ this . setColorGradient ( ...this . colors ) ;
141
+ return this ;
156
142
}
157
143
}
158
144
159
- module . exports = Gradient ;
145
+ module . exports = Gradient ;
0 commit comments