1- function hexToHSL ( hex : string ) {
2- if ( hex . startsWith ( '#' ) )
3- hex = hex . substring ( 1 ) ;
4- let r = parseInt ( hex . substr ( 1 , 2 ) , 16 ) / 255 ;
5- let g = parseInt ( hex . substr ( 3 , 2 ) , 16 ) / 255 ;
6- let b = parseInt ( hex . substr ( 5 , 2 ) , 16 ) / 255 ;
1+ type ParsedHmiColor = {
2+ alpha : string ;
3+ red : string ;
4+ green : string ;
5+ blue : string ;
6+ format : "hmi" | "css" ;
7+ } ;
8+
9+ export class HmiColorValue extends String {
10+ }
11+
12+ type HmiColorInput = string | String ;
13+
14+ function parseHmiColor ( col : HmiColorInput ) : ParsedHmiColor | undefined {
15+ const value = col . toString ( ) . trim ( ) ;
16+ const hmiMatch = / ^ 0 x ( [ 0 - 9 a - f ] { 2 } ) ( [ 0 - 9 a - f ] { 2 } ) ( [ 0 - 9 a - f ] { 2 } ) ( [ 0 - 9 a - f ] { 2 } ) $ / i. exec ( value ) ;
17+ if ( hmiMatch != null ) {
18+ return {
19+ alpha : hmiMatch [ 1 ] ,
20+ red : hmiMatch [ 2 ] ,
21+ green : hmiMatch [ 3 ] ,
22+ blue : hmiMatch [ 4 ] ,
23+ format : "hmi"
24+ } ;
25+ }
26+
27+ const cssMatch = / ^ # ( [ 0 - 9 a - f ] { 2 } ) ( [ 0 - 9 a - f ] { 2 } ) ( [ 0 - 9 a - f ] { 2 } ) ( [ 0 - 9 a - f ] { 2 } ) ? $ / i. exec ( value ) ;
28+ if ( cssMatch != null ) {
29+ return {
30+ alpha : cssMatch [ 4 ] ?? "FF" ,
31+ red : cssMatch [ 1 ] ,
32+ green : cssMatch [ 2 ] ,
33+ blue : cssMatch [ 3 ] ,
34+ format : "css"
35+ } ;
36+ }
37+
38+ return undefined ;
39+ }
40+
41+ function hmiColorToCssColor ( col : HmiColorInput ) {
42+ const parsedColor = parseHmiColor ( col ) ;
43+ if ( parsedColor == null )
44+ return col ;
45+ return `#${ parsedColor . red } ${ parsedColor . green } ${ parsedColor . blue } ${ parsedColor . alpha } ` ;
46+ }
47+
48+ function hmiColorToRgbColor ( col : HmiColorInput ) {
49+ const parsedColor = parseHmiColor ( col ) ;
50+ if ( parsedColor == null )
51+ return col ;
52+ return `#${ parsedColor . red } ${ parsedColor . green } ${ parsedColor . blue } ` ;
53+ }
54+
55+ function hmiColorToAlpha ( col : HmiColorInput ) {
56+ const parsedColor = parseHmiColor ( col ) ;
57+ if ( parsedColor == null )
58+ return "" ;
59+ return parsedColor . alpha ;
60+ }
61+
62+ function colorToHSL ( hex : HmiColorInput ) {
63+ const parsedColor = parseHmiColor ( hex ) ;
64+ const value = hex . toString ( ) . replace ( / ^ # / , "" ) ;
65+ const r = parseInt ( parsedColor ?. red ?? value . substring ( 0 , 2 ) , 16 ) / 255 ;
66+ const g = parseInt ( parsedColor ?. green ?? value . substring ( 2 , 4 ) , 16 ) / 255 ;
67+ const b = parseInt ( parsedColor ?. blue ?? value . substring ( 4 , 6 ) , 16 ) / 255 ;
768
869 let max = Math . max ( r , g , b ) , min = Math . min ( r , g , b ) ;
970 let h = 0 ;
@@ -25,7 +86,7 @@ function hexToHSL(hex: string) {
2586 return { h, s, l } ;
2687}
2788
28- function hslToHex ( h : number , s : number , l : number ) {
89+ function hslToRgbHex ( h : number , s : number , l : number ) {
2990 function f ( p : number , q : number , t : number ) {
3091 if ( t < 0 ) t += 1 ;
3192 if ( t > 1 ) t -= 1 ;
@@ -44,6 +105,18 @@ function hslToHex(h: number, s: number, l: number) {
44105 return `#${ r . toString ( 16 ) . padStart ( 2 , '0' ) } ${ g . toString ( 16 ) . padStart ( 2 , '0' ) } ${ b . toString ( 16 ) . padStart ( 2 , '0' ) } ` ;
45106}
46107
108+ function formatIlluminatedColor ( input : HmiColorInput , rgbHex : string ) {
109+ const parsedColor = parseHmiColor ( input ) ;
110+ if ( parsedColor == null )
111+ return rgbHex ;
112+
113+ const rgb = rgbHex . substring ( 1 ) ;
114+ if ( parsedColor . format == "hmi" )
115+ return new HmiColorValue ( `0x${ parsedColor . alpha } ${ rgb } ` ) ;
116+
117+ return `#${ rgb } ${ parsedColor . alpha } ` ;
118+ }
119+
47120export class Converter {
48121 static IsString ( txt : unknown ) {
49122 return typeof txt == "string" ;
@@ -61,31 +134,24 @@ export class Converter {
61134 return arr . length ;
62135 }
63136
64- static RGB ( col : string ) {
65- if ( col . startsWith ( '#' ) )
66- return col ;
67- return '#' + col . substring ( 4 ) ;
68- }
69-
70- static RGBA ( col : string ) {
71- if ( col . startsWith ( '#' ) )
72- return col ;
73- return '#' + col . substring ( 4 ) + col . substring ( 2 , 4 ) ;
74- }
75-
76- static Alpha ( col : string ) {
77- return col . substring ( 2 , 4 ) ;
78- }
79-
80- static Iluminate ( input : string , deviation : number , low = '#FFFFFF' , high = '#000000' ) {
137+ static RGB ( col : HmiColorInput ) {
138+ return hmiColorToRgbColor ( col ) ;
139+ }
140+
141+ static RGBA ( col : HmiColorInput ) {
142+ return hmiColorToCssColor ( col ) ;
143+ }
144+
145+ static Alpha ( col : HmiColorInput ) {
146+ return hmiColorToAlpha ( col ) ;
147+ }
148+
149+ static Iluminate ( input : HmiColorInput , deviation : number , low : HmiColorInput = '#FFFFFF' , high : HmiColorInput = '#000000' ) {
81150 deviation = Math . max ( - 1 , Math . min ( 1 , deviation ) ) ; // Clamp deviation to [-1, 1]
82151
83- let hex = input ;
84- if ( hex . startsWith ( "0x" ) )
85- hex = hex . substring ( 4 ) ;
86- let inputHSL = hexToHSL ( hex ) ;
87- let lowHSL = hexToHSL ( low ) ;
88- let highHSL = hexToHSL ( high ) ;
152+ let inputHSL = colorToHSL ( input ) ;
153+ let lowHSL = colorToHSL ( low ) ;
154+ let highHSL = colorToHSL ( high ) ;
89155
90156 let lowFactor = lowHSL . l ;
91157 let highFactor = highHSL . l ;
@@ -98,16 +164,16 @@ export class Converter {
98164 let adjustedL = inputHSL . l + deviation * ( highFactor - lowFactor ) ;
99165 adjustedL = Math . max ( 0 , Math . min ( 1 , adjustedL ) ) ; // Clamp L between 0 and 1
100166
101- return hslToHex ( inputHSL . h , inputHSL . s , adjustedL ) ;
102- }
103-
104- static Darker ( input : string , deviation : number ) {
105- return this . Iluminate ( input , deviation ) ;
167+ return formatIlluminatedColor ( input , hslToRgbHex ( inputHSL . h , inputHSL . s , adjustedL ) ) ;
106168 }
107169
108- static Lighter ( input : string , deviation : number ) {
109- return this . Iluminate ( input , - 1 * deviation ) ;
110- }
170+ static Darker ( input : HmiColorInput , deviation : number ) {
171+ return this . Iluminate ( input , deviation ) ;
172+ }
173+
174+ static Lighter ( input : HmiColorInput , deviation : number ) {
175+ return this . Iluminate ( input , - 1 * deviation ) ;
176+ }
111177
112178 static Bounds ( input : number , min : number , max : number ) {
113179 return Math . min ( Math . max ( input , min ) , max ) ;
0 commit comments