11class 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+ }
358
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+ }
4257
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" ) ;
5668 }
5769}
5870
5971class 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 ) ) ;
153112 }
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 ;
156142 }
157143}
158144
159- module . exports = Gradient ;
145+ module . exports = Gradient ;
0 commit comments