@bobfrankston/colorlib 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/convert.d.ts +26 -0
- package/convert.d.ts.map +1 -0
- package/convert.js +96 -0
- package/convert.js.map +1 -0
- package/convert.ts +111 -0
- package/index.d.ts +4 -0
- package/index.d.ts.map +1 -0
- package/index.js +4 -0
- package/index.js.map +1 -0
- package/index.ts +3 -0
- package/package.json +31 -0
- package/parse.d.ts +13 -0
- package/parse.d.ts.map +1 -0
- package/parse.js +94 -0
- package/parse.js.map +1 -0
- package/parse.ts +95 -0
- package/tsconfig.json +20 -0
- package/types.d.ts +74 -0
- package/types.d.ts.map +1 -0
- package/types.js +17 -0
- package/types.js.map +1 -0
- package/types.ts +90 -0
package/convert.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { RGB, HSL, HSB, HSBK, HSBK16 } from './types.js';
|
|
2
|
+
/** RGB to HSL */
|
|
3
|
+
export declare function rgbToHsl(rgb: RGB): HSL;
|
|
4
|
+
/** HSL to RGB */
|
|
5
|
+
export declare function hslToRgb(hsl: HSL): RGB;
|
|
6
|
+
/** RGB to HSB (HSV) */
|
|
7
|
+
export declare function rgbToHsb(rgb: RGB): HSB;
|
|
8
|
+
/** HSB (HSV) to RGB */
|
|
9
|
+
export declare function hsbToRgb(hsb: HSB): RGB;
|
|
10
|
+
/** HSL to HSB */
|
|
11
|
+
export declare function hslToHsb(hsl: HSL): HSB;
|
|
12
|
+
/** HSB to HSL */
|
|
13
|
+
export declare function hsbToHsl(hsb: HSB): HSL;
|
|
14
|
+
/** HSB to HSBK with optional kelvin */
|
|
15
|
+
export declare function hsbToHsbk(hsb: HSB, kelvin?: number): HSBK;
|
|
16
|
+
/** RGB to HSBK */
|
|
17
|
+
export declare function rgbToHsbk(rgb: RGB, kelvin?: number): HSBK;
|
|
18
|
+
/** HSL to HSBK */
|
|
19
|
+
export declare function hslToHsbk(hsl: HSL, kelvin?: number): HSBK;
|
|
20
|
+
/** Approximate RGB for a color temperature (for white light preview) */
|
|
21
|
+
export declare function kelvinToRgb(kelvin: number): RGB;
|
|
22
|
+
/** HSBK to 16-bit scaled format */
|
|
23
|
+
export declare function hsbkTo16(hsbk: HSBK): HSBK16;
|
|
24
|
+
/** 16-bit scaled format to HSBK */
|
|
25
|
+
export declare function hsbk16ToHsbk(hsbk16: HSBK16): HSBK;
|
|
26
|
+
//# sourceMappingURL=convert.d.ts.map
|
package/convert.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["convert.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAWzD,iBAAiB;AACjB,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAGtC;AAED,iBAAiB;AACjB,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAGtC;AAED,uBAAuB;AACvB,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAGtC;AAED,uBAAuB;AACvB,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAGtC;AAED,iBAAiB;AACjB,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAGtC;AAED,iBAAiB;AACjB,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAGtC;AAED,uCAAuC;AACvC,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,GAAE,MAAuB,GAAG,IAAI,CAOzE;AAED,kBAAkB;AAClB,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,GAAE,MAAuB,GAAG,IAAI,CAGzE;AAED,kBAAkB;AAClB,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,GAAE,MAAuB,GAAG,IAAI,CAGzE;AAED,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAmB/C;AAED,mCAAmC;AACnC,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAO3C;AAED,mCAAmC;AACnC,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAOjD"}
|
package/convert.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import convert from 'color-convert';
|
|
2
|
+
const DEFAULT_KELVIN = 3500;
|
|
3
|
+
const MIN_KELVIN = 1500;
|
|
4
|
+
const MAX_KELVIN = 9000;
|
|
5
|
+
/** Clamp value to range */
|
|
6
|
+
function clamp(v, min, max) {
|
|
7
|
+
return Math.max(min, Math.min(max, v));
|
|
8
|
+
}
|
|
9
|
+
/** RGB to HSL */
|
|
10
|
+
export function rgbToHsl(rgb) {
|
|
11
|
+
const [h, s, l] = convert.rgb.hsl([rgb.r, rgb.g, rgb.b]);
|
|
12
|
+
return { h, s, l };
|
|
13
|
+
}
|
|
14
|
+
/** HSL to RGB */
|
|
15
|
+
export function hslToRgb(hsl) {
|
|
16
|
+
const [r, g, b] = convert.hsl.rgb([hsl.h, hsl.s, hsl.l]);
|
|
17
|
+
return { r, g, b };
|
|
18
|
+
}
|
|
19
|
+
/** RGB to HSB (HSV) */
|
|
20
|
+
export function rgbToHsb(rgb) {
|
|
21
|
+
const [h, s, v] = convert.rgb.hsv([rgb.r, rgb.g, rgb.b]);
|
|
22
|
+
return { h, s, b: v };
|
|
23
|
+
}
|
|
24
|
+
/** HSB (HSV) to RGB */
|
|
25
|
+
export function hsbToRgb(hsb) {
|
|
26
|
+
const [r, g, b] = convert.hsv.rgb([hsb.h, hsb.s, hsb.b]);
|
|
27
|
+
return { r, g, b };
|
|
28
|
+
}
|
|
29
|
+
/** HSL to HSB */
|
|
30
|
+
export function hslToHsb(hsl) {
|
|
31
|
+
const rgb = hslToRgb(hsl);
|
|
32
|
+
return rgbToHsb(rgb);
|
|
33
|
+
}
|
|
34
|
+
/** HSB to HSL */
|
|
35
|
+
export function hsbToHsl(hsb) {
|
|
36
|
+
const rgb = hsbToRgb(hsb);
|
|
37
|
+
return rgbToHsl(rgb);
|
|
38
|
+
}
|
|
39
|
+
/** HSB to HSBK with optional kelvin */
|
|
40
|
+
export function hsbToHsbk(hsb, kelvin = DEFAULT_KELVIN) {
|
|
41
|
+
return {
|
|
42
|
+
h: hsb.h,
|
|
43
|
+
s: hsb.s,
|
|
44
|
+
b: hsb.b,
|
|
45
|
+
k: clamp(kelvin, MIN_KELVIN, MAX_KELVIN)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** RGB to HSBK */
|
|
49
|
+
export function rgbToHsbk(rgb, kelvin = DEFAULT_KELVIN) {
|
|
50
|
+
const hsb = rgbToHsb(rgb);
|
|
51
|
+
return hsbToHsbk(hsb, kelvin);
|
|
52
|
+
}
|
|
53
|
+
/** HSL to HSBK */
|
|
54
|
+
export function hslToHsbk(hsl, kelvin = DEFAULT_KELVIN) {
|
|
55
|
+
const hsb = hslToHsb(hsl);
|
|
56
|
+
return hsbToHsbk(hsb, kelvin);
|
|
57
|
+
}
|
|
58
|
+
/** Approximate RGB for a color temperature (for white light preview) */
|
|
59
|
+
export function kelvinToRgb(kelvin) {
|
|
60
|
+
const k = clamp(kelvin, 1000, 40000) / 100;
|
|
61
|
+
let r, g, b;
|
|
62
|
+
if (k <= 66) {
|
|
63
|
+
r = 255;
|
|
64
|
+
g = 99.4708025861 * Math.log(k) - 161.1195681661;
|
|
65
|
+
b = k <= 19 ? 0 : 138.5177312231 * Math.log(k - 10) - 305.0447927307;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
r = 329.698727446 * Math.pow(k - 60, -0.1332047592);
|
|
69
|
+
g = 288.1221695283 * Math.pow(k - 60, -0.0755148492);
|
|
70
|
+
b = 255;
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
r: Math.round(clamp(r, 0, 255)),
|
|
74
|
+
g: Math.round(clamp(g, 0, 255)),
|
|
75
|
+
b: Math.round(clamp(b, 0, 255))
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/** HSBK to 16-bit scaled format */
|
|
79
|
+
export function hsbkTo16(hsbk) {
|
|
80
|
+
return {
|
|
81
|
+
h: Math.round((hsbk.h / 360) * 0xFFFF),
|
|
82
|
+
s: Math.round((hsbk.s / 100) * 0xFFFF),
|
|
83
|
+
b: Math.round((hsbk.b / 100) * 0xFFFF),
|
|
84
|
+
k: clamp(Math.round(hsbk.k), MIN_KELVIN, MAX_KELVIN)
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/** 16-bit scaled format to HSBK */
|
|
88
|
+
export function hsbk16ToHsbk(hsbk16) {
|
|
89
|
+
return {
|
|
90
|
+
h: (hsbk16.h / 0xFFFF) * 360,
|
|
91
|
+
s: (hsbk16.s / 0xFFFF) * 100,
|
|
92
|
+
b: (hsbk16.b / 0xFFFF) * 100,
|
|
93
|
+
k: hsbk16.k
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=convert.js.map
|
package/convert.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.js","sourceRoot":"","sources":["convert.ts"],"names":[],"mappings":"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"}
|
package/convert.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import convert from 'color-convert';
|
|
2
|
+
import { RGB, HSL, HSB, HSBK, HSBK16 } from './types.js';
|
|
3
|
+
|
|
4
|
+
const DEFAULT_KELVIN = 3500;
|
|
5
|
+
const MIN_KELVIN = 1500;
|
|
6
|
+
const MAX_KELVIN = 9000;
|
|
7
|
+
|
|
8
|
+
/** Clamp value to range */
|
|
9
|
+
function clamp(v: number, min: number, max: number): number {
|
|
10
|
+
return Math.max(min, Math.min(max, v));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** RGB to HSL */
|
|
14
|
+
export function rgbToHsl(rgb: RGB): HSL {
|
|
15
|
+
const [h, s, l] = convert.rgb.hsl([rgb.r, rgb.g, rgb.b]);
|
|
16
|
+
return { h, s, l };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** HSL to RGB */
|
|
20
|
+
export function hslToRgb(hsl: HSL): RGB {
|
|
21
|
+
const [r, g, b] = convert.hsl.rgb([hsl.h, hsl.s, hsl.l]);
|
|
22
|
+
return { r, g, b };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** RGB to HSB (HSV) */
|
|
26
|
+
export function rgbToHsb(rgb: RGB): HSB {
|
|
27
|
+
const [h, s, v] = convert.rgb.hsv([rgb.r, rgb.g, rgb.b]);
|
|
28
|
+
return { h, s, b: v };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** HSB (HSV) to RGB */
|
|
32
|
+
export function hsbToRgb(hsb: HSB): RGB {
|
|
33
|
+
const [r, g, b] = convert.hsv.rgb([hsb.h, hsb.s, hsb.b]);
|
|
34
|
+
return { r, g, b };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** HSL to HSB */
|
|
38
|
+
export function hslToHsb(hsl: HSL): HSB {
|
|
39
|
+
const rgb = hslToRgb(hsl);
|
|
40
|
+
return rgbToHsb(rgb);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** HSB to HSL */
|
|
44
|
+
export function hsbToHsl(hsb: HSB): HSL {
|
|
45
|
+
const rgb = hsbToRgb(hsb);
|
|
46
|
+
return rgbToHsl(rgb);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** HSB to HSBK with optional kelvin */
|
|
50
|
+
export function hsbToHsbk(hsb: HSB, kelvin: number = DEFAULT_KELVIN): HSBK {
|
|
51
|
+
return {
|
|
52
|
+
h: hsb.h,
|
|
53
|
+
s: hsb.s,
|
|
54
|
+
b: hsb.b,
|
|
55
|
+
k: clamp(kelvin, MIN_KELVIN, MAX_KELVIN)
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** RGB to HSBK */
|
|
60
|
+
export function rgbToHsbk(rgb: RGB, kelvin: number = DEFAULT_KELVIN): HSBK {
|
|
61
|
+
const hsb = rgbToHsb(rgb);
|
|
62
|
+
return hsbToHsbk(hsb, kelvin);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** HSL to HSBK */
|
|
66
|
+
export function hslToHsbk(hsl: HSL, kelvin: number = DEFAULT_KELVIN): HSBK {
|
|
67
|
+
const hsb = hslToHsb(hsl);
|
|
68
|
+
return hsbToHsbk(hsb, kelvin);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Approximate RGB for a color temperature (for white light preview) */
|
|
72
|
+
export function kelvinToRgb(kelvin: number): RGB {
|
|
73
|
+
const k = clamp(kelvin, 1000, 40000) / 100;
|
|
74
|
+
let r: number, g: number, b: number;
|
|
75
|
+
|
|
76
|
+
if (k <= 66) {
|
|
77
|
+
r = 255;
|
|
78
|
+
g = 99.4708025861 * Math.log(k) - 161.1195681661;
|
|
79
|
+
b = k <= 19 ? 0 : 138.5177312231 * Math.log(k - 10) - 305.0447927307;
|
|
80
|
+
} else {
|
|
81
|
+
r = 329.698727446 * Math.pow(k - 60, -0.1332047592);
|
|
82
|
+
g = 288.1221695283 * Math.pow(k - 60, -0.0755148492);
|
|
83
|
+
b = 255;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
r: Math.round(clamp(r, 0, 255)),
|
|
88
|
+
g: Math.round(clamp(g, 0, 255)),
|
|
89
|
+
b: Math.round(clamp(b, 0, 255))
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** HSBK to 16-bit scaled format */
|
|
94
|
+
export function hsbkTo16(hsbk: HSBK): HSBK16 {
|
|
95
|
+
return {
|
|
96
|
+
h: Math.round((hsbk.h / 360) * 0xFFFF),
|
|
97
|
+
s: Math.round((hsbk.s / 100) * 0xFFFF),
|
|
98
|
+
b: Math.round((hsbk.b / 100) * 0xFFFF),
|
|
99
|
+
k: clamp(Math.round(hsbk.k), MIN_KELVIN, MAX_KELVIN)
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** 16-bit scaled format to HSBK */
|
|
104
|
+
export function hsbk16ToHsbk(hsbk16: HSBK16): HSBK {
|
|
105
|
+
return {
|
|
106
|
+
h: (hsbk16.h / 0xFFFF) * 360,
|
|
107
|
+
s: (hsbk16.s / 0xFFFF) * 100,
|
|
108
|
+
b: (hsbk16.b / 0xFFFF) * 100,
|
|
109
|
+
k: hsbk16.k
|
|
110
|
+
};
|
|
111
|
+
}
|
package/index.d.ts
ADDED
package/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
package/index.js
ADDED
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
package/index.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bobfrankston/colorlib",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Color conversion library for RGB, HSL, HSB, HSBK and Kelvin",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./index.d.ts",
|
|
11
|
+
"import": "./index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"watch": "tsc -w"
|
|
17
|
+
},
|
|
18
|
+
"keywords": ["color", "hsl", "hsb", "rgb", "kelvin"],
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/BobFrankston/colorlib.git"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"color-convert": "^2.0.1"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/color-convert": "^2.0.4",
|
|
29
|
+
"@types/node": "latest"
|
|
30
|
+
}
|
|
31
|
+
}
|
package/parse.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HSBK, ColorInput } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse flexible color input to HSBK
|
|
4
|
+
* Auto-detects type from input:
|
|
5
|
+
* - string: "#ff0000", "rgb(255,0,0)", "hsl(0,100%,50%)", "red"
|
|
6
|
+
* - number: Kelvin temperature (1500-9000) -> white at that temp
|
|
7
|
+
* - {r,g,b}: RGB object
|
|
8
|
+
* - {h,s,l}: HSL object
|
|
9
|
+
* - {h,s,b}: HSB object
|
|
10
|
+
* - {h,s,b,k}: HSBK object (passthrough)
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseColor(input: ColorInput, defaultKelvin?: number): HSBK;
|
|
13
|
+
//# sourceMappingURL=parse.d.ts.map
|
package/parse.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["parse.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,IAAI,EAAE,UAAU,EAA+B,MAAM,YAAY,CAAC;AAoD1F;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,aAAa,GAAE,MAAuB,GAAG,IAAI,CA+B1F"}
|
package/parse.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import convert from 'color-convert';
|
|
2
|
+
import { isRGB, isHSL, isHSB, isHSBK } from './types.js';
|
|
3
|
+
import { rgbToHsbk, hslToHsbk, hsbToHsbk } from './convert.js';
|
|
4
|
+
const DEFAULT_KELVIN = 3500;
|
|
5
|
+
const MIN_KELVIN = 1500;
|
|
6
|
+
const MAX_KELVIN = 9000;
|
|
7
|
+
/** Parse hex color string */
|
|
8
|
+
function parseHex(hex) {
|
|
9
|
+
const clean = hex.replace(/^#/, '');
|
|
10
|
+
const expanded = clean.length === 3
|
|
11
|
+
? clean.split('').map(c => c + c).join('')
|
|
12
|
+
: clean;
|
|
13
|
+
const num = parseInt(expanded, 16);
|
|
14
|
+
return {
|
|
15
|
+
r: (num >> 16) & 255,
|
|
16
|
+
g: (num >> 8) & 255,
|
|
17
|
+
b: num & 255
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** Parse rgb(r, g, b) string */
|
|
21
|
+
function parseRgbString(str) {
|
|
22
|
+
const match = str.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i);
|
|
23
|
+
if (!match)
|
|
24
|
+
throw new Error(`Invalid rgb string: ${str}`);
|
|
25
|
+
return {
|
|
26
|
+
r: parseInt(match[1], 10),
|
|
27
|
+
g: parseInt(match[2], 10),
|
|
28
|
+
b: parseInt(match[3], 10)
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** Parse hsl(h, s%, l%) string */
|
|
32
|
+
function parseHslString(str) {
|
|
33
|
+
const match = str.match(/hsl\s*\(\s*(\d+)\s*,\s*(\d+)%?\s*,\s*(\d+)%?\s*\)/i);
|
|
34
|
+
if (!match)
|
|
35
|
+
throw new Error(`Invalid hsl string: ${str}`);
|
|
36
|
+
return {
|
|
37
|
+
h: parseInt(match[1], 10),
|
|
38
|
+
s: parseInt(match[2], 10),
|
|
39
|
+
l: parseInt(match[3], 10)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Parse named color using color-convert */
|
|
43
|
+
function parseNamed(name) {
|
|
44
|
+
try {
|
|
45
|
+
const rgb = convert.keyword.rgb(name);
|
|
46
|
+
if (rgb)
|
|
47
|
+
return { r: rgb[0], g: rgb[1], b: rgb[2] };
|
|
48
|
+
}
|
|
49
|
+
catch (e) { }
|
|
50
|
+
throw new Error(`Unknown color name: ${name}`);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Parse flexible color input to HSBK
|
|
54
|
+
* Auto-detects type from input:
|
|
55
|
+
* - string: "#ff0000", "rgb(255,0,0)", "hsl(0,100%,50%)", "red"
|
|
56
|
+
* - number: Kelvin temperature (1500-9000) -> white at that temp
|
|
57
|
+
* - {r,g,b}: RGB object
|
|
58
|
+
* - {h,s,l}: HSL object
|
|
59
|
+
* - {h,s,b}: HSB object
|
|
60
|
+
* - {h,s,b,k}: HSBK object (passthrough)
|
|
61
|
+
*/
|
|
62
|
+
export function parseColor(input, defaultKelvin = DEFAULT_KELVIN) {
|
|
63
|
+
if (typeof input === 'number') {
|
|
64
|
+
if (input >= MIN_KELVIN && input <= MAX_KELVIN) {
|
|
65
|
+
return { h: 0, s: 0, b: 100, k: input }; /** white at kelvin */
|
|
66
|
+
}
|
|
67
|
+
throw new Error(`Kelvin must be ${MIN_KELVIN}-${MAX_KELVIN}, got ${input}`);
|
|
68
|
+
}
|
|
69
|
+
if (typeof input === 'string') {
|
|
70
|
+
const str = input.trim().toLowerCase();
|
|
71
|
+
if (str.startsWith('#') || /^[0-9a-f]{3,6}$/i.test(str)) {
|
|
72
|
+
return rgbToHsbk(parseHex(str), defaultKelvin);
|
|
73
|
+
}
|
|
74
|
+
if (str.startsWith('rgb(')) {
|
|
75
|
+
return rgbToHsbk(parseRgbString(str), defaultKelvin);
|
|
76
|
+
}
|
|
77
|
+
if (str.startsWith('hsl(')) {
|
|
78
|
+
return hslToHsbk(parseHslString(str), defaultKelvin);
|
|
79
|
+
}
|
|
80
|
+
return rgbToHsbk(parseNamed(str), defaultKelvin);
|
|
81
|
+
}
|
|
82
|
+
if (typeof input === 'object') {
|
|
83
|
+
if (isHSBK(input))
|
|
84
|
+
return input;
|
|
85
|
+
if (isHSB(input))
|
|
86
|
+
return hsbToHsbk(input, defaultKelvin);
|
|
87
|
+
if (isHSL(input))
|
|
88
|
+
return hslToHsbk(input, defaultKelvin);
|
|
89
|
+
if (isRGB(input))
|
|
90
|
+
return rgbToHsbk(input, defaultKelvin);
|
|
91
|
+
}
|
|
92
|
+
throw new Error(`Cannot parse color: ${JSON.stringify(input)}`);
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=parse.js.map
|
package/parse.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["parse.ts"],"names":[],"mappings":"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"}
|
package/parse.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import convert from 'color-convert';
|
|
2
|
+
import { RGB, HSL, HSB, HSBK, ColorInput, isRGB, isHSL, isHSB, isHSBK } from './types.js';
|
|
3
|
+
import { rgbToHsbk, hslToHsbk, hsbToHsbk } from './convert.js';
|
|
4
|
+
|
|
5
|
+
const DEFAULT_KELVIN = 3500;
|
|
6
|
+
const MIN_KELVIN = 1500;
|
|
7
|
+
const MAX_KELVIN = 9000;
|
|
8
|
+
|
|
9
|
+
/** Parse hex color string */
|
|
10
|
+
function parseHex(hex: string): RGB {
|
|
11
|
+
const clean = hex.replace(/^#/, '');
|
|
12
|
+
const expanded = clean.length === 3
|
|
13
|
+
? clean.split('').map(c => c + c).join('')
|
|
14
|
+
: clean;
|
|
15
|
+
const num = parseInt(expanded, 16);
|
|
16
|
+
return {
|
|
17
|
+
r: (num >> 16) & 255,
|
|
18
|
+
g: (num >> 8) & 255,
|
|
19
|
+
b: num & 255
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Parse rgb(r, g, b) string */
|
|
24
|
+
function parseRgbString(str: string): RGB {
|
|
25
|
+
const match = str.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i);
|
|
26
|
+
if (!match) throw new Error(`Invalid rgb string: ${str}`);
|
|
27
|
+
return {
|
|
28
|
+
r: parseInt(match[1], 10),
|
|
29
|
+
g: parseInt(match[2], 10),
|
|
30
|
+
b: parseInt(match[3], 10)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Parse hsl(h, s%, l%) string */
|
|
35
|
+
function parseHslString(str: string): HSL {
|
|
36
|
+
const match = str.match(/hsl\s*\(\s*(\d+)\s*,\s*(\d+)%?\s*,\s*(\d+)%?\s*\)/i);
|
|
37
|
+
if (!match) throw new Error(`Invalid hsl string: ${str}`);
|
|
38
|
+
return {
|
|
39
|
+
h: parseInt(match[1], 10),
|
|
40
|
+
s: parseInt(match[2], 10),
|
|
41
|
+
l: parseInt(match[3], 10)
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Parse named color using color-convert */
|
|
46
|
+
function parseNamed(name: string): RGB {
|
|
47
|
+
try {
|
|
48
|
+
const rgb = convert.keyword.rgb(name as any);
|
|
49
|
+
if (rgb) return { r: rgb[0], g: rgb[1], b: rgb[2] };
|
|
50
|
+
} catch (e: any) { }
|
|
51
|
+
throw new Error(`Unknown color name: ${name}`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Parse flexible color input to HSBK
|
|
56
|
+
* Auto-detects type from input:
|
|
57
|
+
* - string: "#ff0000", "rgb(255,0,0)", "hsl(0,100%,50%)", "red"
|
|
58
|
+
* - number: Kelvin temperature (1500-9000) -> white at that temp
|
|
59
|
+
* - {r,g,b}: RGB object
|
|
60
|
+
* - {h,s,l}: HSL object
|
|
61
|
+
* - {h,s,b}: HSB object
|
|
62
|
+
* - {h,s,b,k}: HSBK object (passthrough)
|
|
63
|
+
*/
|
|
64
|
+
export function parseColor(input: ColorInput, defaultKelvin: number = DEFAULT_KELVIN): HSBK {
|
|
65
|
+
if (typeof input === 'number') {
|
|
66
|
+
if (input >= MIN_KELVIN && input <= MAX_KELVIN) {
|
|
67
|
+
return { h: 0, s: 0, b: 100, k: input }; /** white at kelvin */
|
|
68
|
+
}
|
|
69
|
+
throw new Error(`Kelvin must be ${MIN_KELVIN}-${MAX_KELVIN}, got ${input}`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (typeof input === 'string') {
|
|
73
|
+
const str = input.trim().toLowerCase();
|
|
74
|
+
|
|
75
|
+
if (str.startsWith('#') || /^[0-9a-f]{3,6}$/i.test(str)) {
|
|
76
|
+
return rgbToHsbk(parseHex(str), defaultKelvin);
|
|
77
|
+
}
|
|
78
|
+
if (str.startsWith('rgb(')) {
|
|
79
|
+
return rgbToHsbk(parseRgbString(str), defaultKelvin);
|
|
80
|
+
}
|
|
81
|
+
if (str.startsWith('hsl(')) {
|
|
82
|
+
return hslToHsbk(parseHslString(str), defaultKelvin);
|
|
83
|
+
}
|
|
84
|
+
return rgbToHsbk(parseNamed(str), defaultKelvin);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (typeof input === 'object') {
|
|
88
|
+
if (isHSBK(input)) return input;
|
|
89
|
+
if (isHSB(input)) return hsbToHsbk(input, defaultKelvin);
|
|
90
|
+
if (isHSL(input)) return hslToHsbk(input, defaultKelvin);
|
|
91
|
+
if (isRGB(input)) return rgbToHsbk(input, defaultKelvin);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
throw new Error(`Cannot parse color: ${JSON.stringify(input)}`);
|
|
95
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "esnext",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"allowSyntheticDefaultImports": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"strict": true,
|
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"declarationMap": true,
|
|
13
|
+
"sourceMap": true,
|
|
14
|
+
"strictNullChecks": false,
|
|
15
|
+
"noImplicitAny": true,
|
|
16
|
+
"noImplicitThis": true,
|
|
17
|
+
"newLine": "lf"
|
|
18
|
+
},
|
|
19
|
+
"exclude": ["node_modules", "cruft", ".git", "tests", "prev"]
|
|
20
|
+
}
|
package/types.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RGB color (0-255 per channel)
|
|
3
|
+
*/
|
|
4
|
+
export interface RGB {
|
|
5
|
+
/** Red channel (0-255) */
|
|
6
|
+
r: number;
|
|
7
|
+
/** Green channel (0-255) */
|
|
8
|
+
g: number;
|
|
9
|
+
/** Blue channel (0-255) */
|
|
10
|
+
b: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* HSL color (Hue, Saturation, Lightness)
|
|
14
|
+
*/
|
|
15
|
+
export interface HSL {
|
|
16
|
+
/** Hue (0-360 degrees) */
|
|
17
|
+
h: number;
|
|
18
|
+
/** Saturation (0-100%) */
|
|
19
|
+
s: number;
|
|
20
|
+
/** Lightness (0-100%) */
|
|
21
|
+
l: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* HSB/HSV color (Hue, Saturation, Brightness/Value)
|
|
25
|
+
*/
|
|
26
|
+
export interface HSB {
|
|
27
|
+
/** Hue (0-360 degrees) */
|
|
28
|
+
h: number;
|
|
29
|
+
/** Saturation (0-100%) */
|
|
30
|
+
s: number;
|
|
31
|
+
/** Brightness/Value (0-100%) */
|
|
32
|
+
b: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* HSBK color with Kelvin temperature (used by LIFX and similar)
|
|
36
|
+
*/
|
|
37
|
+
export interface HSBK {
|
|
38
|
+
/** Hue (0-360 degrees) */
|
|
39
|
+
h: number;
|
|
40
|
+
/** Saturation (0-100%) */
|
|
41
|
+
s: number;
|
|
42
|
+
/** Brightness (0-100%) */
|
|
43
|
+
b: number;
|
|
44
|
+
/** Color temperature in Kelvin (1500-9000, warm to cool) */
|
|
45
|
+
k: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 16-bit scaled HSBK for wire protocols.
|
|
49
|
+
* h/s/b are 0-0xFFFF, k remains 1500-9000.
|
|
50
|
+
*/
|
|
51
|
+
export interface HSBK16 {
|
|
52
|
+
/** Hue (0-0xFFFF maps to 0-360°) */
|
|
53
|
+
h: number;
|
|
54
|
+
/** Saturation (0-0xFFFF maps to 0-100%) */
|
|
55
|
+
s: number;
|
|
56
|
+
/** Brightness (0-0xFFFF maps to 0-100%) */
|
|
57
|
+
b: number;
|
|
58
|
+
/** Color temperature in Kelvin (1500-9000) */
|
|
59
|
+
k: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Flexible color input for parseColor().
|
|
63
|
+
* Accepts: "#ff0000", "rgb(255,0,0)", "red", {r,g,b}, {h,s,l}, {h,s,b}, {h,s,b,k}, or Kelvin number
|
|
64
|
+
*/
|
|
65
|
+
export type ColorInput = string | number | RGB | HSL | HSB | HSBK;
|
|
66
|
+
/** Type guard: check if object is RGB */
|
|
67
|
+
export declare function isRGB(c: object): c is RGB;
|
|
68
|
+
/** Type guard: check if object is HSL */
|
|
69
|
+
export declare function isHSL(c: object): c is HSL;
|
|
70
|
+
/** Type guard: check if object is HSB (without kelvin) */
|
|
71
|
+
export declare function isHSB(c: object): c is HSB;
|
|
72
|
+
/** Type guard: check if object is HSBK (with kelvin) */
|
|
73
|
+
export declare function isHSBK(c: object): c is HSBK;
|
|
74
|
+
//# sourceMappingURL=types.d.ts.map
|
package/types.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,GAAG;IAChB,0BAA0B;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,4BAA4B;IAC5B,CAAC,EAAE,MAAM,CAAC;IACV,2BAA2B;IAC3B,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,GAAG;IAChB,0BAA0B;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,0BAA0B;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,yBAAyB;IACzB,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,GAAG;IAChB,0BAA0B;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,0BAA0B;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,gCAAgC;IAChC,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,IAAI;IACjB,0BAA0B;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,0BAA0B;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,0BAA0B;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,4DAA4D;IAC5D,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,MAAM,WAAW,MAAM;IACnB,oCAAoC;IACpC,CAAC,EAAE,MAAM,CAAC;IACV,2CAA2C;IAC3C,CAAC,EAAE,MAAM,CAAC;IACV,2CAA2C;IAC3C,CAAC,EAAE,MAAM,CAAC;IACV,8CAA8C;IAC9C,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC;AAElE,yCAAyC;AACzC,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,GAAG,CAEzC;AAED,yCAAyC;AACzC,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,GAAG,CAEzC;AAED,0DAA0D;AAC1D,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,GAAG,CAEzC;AAED,wDAAwD;AACxD,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,IAAI,CAE3C"}
|
package/types.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Type guard: check if object is RGB */
|
|
2
|
+
export function isRGB(c) {
|
|
3
|
+
return 'r' in c && 'g' in c && 'b' in c && !('h' in c);
|
|
4
|
+
}
|
|
5
|
+
/** Type guard: check if object is HSL */
|
|
6
|
+
export function isHSL(c) {
|
|
7
|
+
return 'h' in c && 's' in c && 'l' in c;
|
|
8
|
+
}
|
|
9
|
+
/** Type guard: check if object is HSB (without kelvin) */
|
|
10
|
+
export function isHSB(c) {
|
|
11
|
+
return 'h' in c && 's' in c && 'b' in c && !('k' in c);
|
|
12
|
+
}
|
|
13
|
+
/** Type guard: check if object is HSBK (with kelvin) */
|
|
14
|
+
export function isHSBK(c) {
|
|
15
|
+
return 'h' in c && 's' in c && 'b' in c && 'k' in c;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
package/types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAuEA,yCAAyC;AACzC,MAAM,UAAU,KAAK,CAAC,CAAS;IAC3B,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,KAAK,CAAC,CAAS;IAC3B,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,KAAK,CAAC,CAAS;IAC3B,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,MAAM,CAAC,CAAS;IAC5B,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AACxD,CAAC"}
|
package/types.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RGB color (0-255 per channel)
|
|
3
|
+
*/
|
|
4
|
+
export interface RGB {
|
|
5
|
+
/** Red channel (0-255) */
|
|
6
|
+
r: number;
|
|
7
|
+
/** Green channel (0-255) */
|
|
8
|
+
g: number;
|
|
9
|
+
/** Blue channel (0-255) */
|
|
10
|
+
b: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* HSL color (Hue, Saturation, Lightness)
|
|
15
|
+
*/
|
|
16
|
+
export interface HSL {
|
|
17
|
+
/** Hue (0-360 degrees) */
|
|
18
|
+
h: number;
|
|
19
|
+
/** Saturation (0-100%) */
|
|
20
|
+
s: number;
|
|
21
|
+
/** Lightness (0-100%) */
|
|
22
|
+
l: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* HSB/HSV color (Hue, Saturation, Brightness/Value)
|
|
27
|
+
*/
|
|
28
|
+
export interface HSB {
|
|
29
|
+
/** Hue (0-360 degrees) */
|
|
30
|
+
h: number;
|
|
31
|
+
/** Saturation (0-100%) */
|
|
32
|
+
s: number;
|
|
33
|
+
/** Brightness/Value (0-100%) */
|
|
34
|
+
b: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* HSBK color with Kelvin temperature (used by LIFX and similar)
|
|
39
|
+
*/
|
|
40
|
+
export interface HSBK {
|
|
41
|
+
/** Hue (0-360 degrees) */
|
|
42
|
+
h: number;
|
|
43
|
+
/** Saturation (0-100%) */
|
|
44
|
+
s: number;
|
|
45
|
+
/** Brightness (0-100%) */
|
|
46
|
+
b: number;
|
|
47
|
+
/** Color temperature in Kelvin (1500-9000, warm to cool) */
|
|
48
|
+
k: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 16-bit scaled HSBK for wire protocols.
|
|
53
|
+
* h/s/b are 0-0xFFFF, k remains 1500-9000.
|
|
54
|
+
*/
|
|
55
|
+
export interface HSBK16 {
|
|
56
|
+
/** Hue (0-0xFFFF maps to 0-360°) */
|
|
57
|
+
h: number;
|
|
58
|
+
/** Saturation (0-0xFFFF maps to 0-100%) */
|
|
59
|
+
s: number;
|
|
60
|
+
/** Brightness (0-0xFFFF maps to 0-100%) */
|
|
61
|
+
b: number;
|
|
62
|
+
/** Color temperature in Kelvin (1500-9000) */
|
|
63
|
+
k: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Flexible color input for parseColor().
|
|
68
|
+
* Accepts: "#ff0000", "rgb(255,0,0)", "red", {r,g,b}, {h,s,l}, {h,s,b}, {h,s,b,k}, or Kelvin number
|
|
69
|
+
*/
|
|
70
|
+
export type ColorInput = string | number | RGB | HSL | HSB | HSBK;
|
|
71
|
+
|
|
72
|
+
/** Type guard: check if object is RGB */
|
|
73
|
+
export function isRGB(c: object): c is RGB {
|
|
74
|
+
return 'r' in c && 'g' in c && 'b' in c && !('h' in c);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Type guard: check if object is HSL */
|
|
78
|
+
export function isHSL(c: object): c is HSL {
|
|
79
|
+
return 'h' in c && 's' in c && 'l' in c;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Type guard: check if object is HSB (without kelvin) */
|
|
83
|
+
export function isHSB(c: object): c is HSB {
|
|
84
|
+
return 'h' in c && 's' in c && 'b' in c && !('k' in c);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Type guard: check if object is HSBK (with kelvin) */
|
|
88
|
+
export function isHSBK(c: object): c is HSBK {
|
|
89
|
+
return 'h' in c && 's' in c && 'b' in c && 'k' in c;
|
|
90
|
+
}
|