11import colorConvert from "color-convert" ;
2- import { HSL , KEYWORD as NamedColor } from "color-convert/conversions" ;
3-
4- import ColorName from "color-name" ;
52// Note, we use these because they are already used by MapLibre
63// Saving us an additional dep.
4+ // Although treeshaking should remove the unused parts anyway.
75
86export type WebGLContext = WebGLRenderingContext | WebGL2RenderingContext ;
97
@@ -155,24 +153,21 @@ export function parseColorStringToVec4(color?: string): Vec4 {
155153 }
156154
157155 try {
158- // If the color is a named color eg 'rebeccapurple'
159- if ( ( color as string ) in ColorName ) {
160- return [ ...colorConvert . keyword . rgb ( color as NamedColor ) . map ( ( c ) => c / 255 ) , 1.0 ] as Vec4 ;
161- }
156+ const parsedColor = colorToRgbOrHex ( color ) ;
162157
163- const isHexColor = / ^ # ? ( [ a - f \d ] { 2 } ) ( [ a - f \d ] { 2 } ) ( [ a - f \d ] { 2 } ) ( [ a - f \d ] { 2 } ) ? $ / i. exec ( color ) ;
158+ const isHexColor = / ^ # ? ( [ a - f \d ] { 2 } ) ( [ a - f \d ] { 2 } ) ( [ a - f \d ] { 2 } ) ( [ a - f \d ] { 2 } ) ? $ / i. exec ( parsedColor ) ;
164159 // if the color is a hex color eg #ff00ff or #ff00ff00
165160 if ( isHexColor ?. length ) {
166161 const hasAlphaChannel = Boolean ( isHexColor [ 4 ] ) ;
167162
168- return [ ...colorConvert . hex . rgb ( color ) . map ( ( c ) => c / 255 ) , hasAlphaChannel ? parseInt ( isHexColor [ 4 ] , 16 ) / 255 : 1.0 ] as Vec4 ;
163+ return [ ...colorConvert . hex . rgb ( parsedColor ) . map ( ( c ) => c / 255 ) , hasAlphaChannel ? parseInt ( isHexColor [ 4 ] , 16 ) / 255 : 1.0 ] as Vec4 ;
169164 }
170165
171166 // extracts the numbers from an RGB(A) or HSL(A) color string
172- const colorAsArray = color . match ( / ( \d \. \d ( \d + ) ? | \d { 3 } | \d { 2 } | \d { 1 } ) / gi) ?? [ "0" , "0" , "0" ] ;
167+ const colorAsArray = parsedColor . match ( / ( \d \. \d ( \d + ) ? | \d { 3 } | \d { 2 } | \d { 1 } ) / gi) ?? [ "0" , "0" , "0" ] ;
173168 // If the color is an RGB(A) color eg rgb(255, 0, 255) or rgba(255, 0, 255, 0.5)
174- if ( color . includes ( "rgb" ) ) {
175- const hasAlphaChannel = color . includes ( "rgba" ) ;
169+ if ( parsedColor . includes ( "rgb" ) ) {
170+ const hasAlphaChannel = parsedColor . includes ( "rgba" ) ;
176171 const rgbArray = [
177172 ...colorAsArray . map ( ( c ) => parseFloat ( c ) ) . map ( ( c , i ) => ( i < 3 ? c / 255 : c ) ) , // because alpha is in the range 0 - 1, not 0 - 255
178173 ] ;
@@ -183,31 +178,6 @@ export function parseColorStringToVec4(color?: string): Vec4 {
183178
184179 return rgbArray as Vec4 ;
185180 }
186-
187- // If the color is an HSL(A) color eg hsl(300deg, 100%, 50%) or hsla(1.4rad, 100%, 50%, 0.5)
188- if ( color . includes ( "hsl" ) ) {
189- const hasAlphaChannel = color . includes ( "hsla" ) ;
190-
191- const usesRadians = color . includes ( "rad" ) ;
192-
193- const RGBArray = [
194- ...colorConvert . hsl . rgb (
195- colorAsArray . map ( ( c , i ) => {
196- const number = parseFloat ( c ) ;
197- if ( usesRadians && i === 0 ) {
198- // because not everyone uses degrees,
199- // but color convert expects degrees.
200- // The first entry is the hue angle
201- return ( number * 180 ) / Math . PI ;
202- }
203- return number ;
204- } ) as HSL ,
205- ) ,
206- hasAlphaChannel ? parseFloat ( colorAsArray [ 3 ] ) : 1.0 ,
207- ] ;
208-
209- return RGBArray as Vec4 ;
210- }
211181 } catch ( e ) { }
212182
213183 // Because we are not supporting HWB, HSV or CMYK at the moment.
@@ -218,3 +188,20 @@ export function parseColorStringToVec4(color?: string): Vec4 {
218188export function degreesToRadians ( degrees : number ) {
219189 return ( degrees * Math . PI ) / 180 ;
220190}
191+
192+ // to avoid recreating the ctx each time
193+ const colorConvertCtx = document . createElement ( "canvas" ) . getContext ( "2d" ) ;
194+
195+ function colorToRgbOrHex ( color : string ) : string {
196+ // because cavnas 2D context automagically converts
197+ // any valid css color to a hex string
198+ // or an RGBA string
199+ const ctx = colorConvertCtx ;
200+ if ( ! ctx ) {
201+ return "#000000" ;
202+ }
203+
204+ ctx . fillStyle = color ;
205+
206+ return ctx . fillStyle ;
207+ }
0 commit comments