@csstools/convert-colors 1.3.0 → 1.4.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/index.js CHANGED
@@ -5,9 +5,10 @@ import { rgb2xyz, xyz2rgb } from './lib/rgb-xyz';
5
5
  import { hsl2hsv, hsv2hsl } from './lib/hsl-hsv';
6
6
  import { hwb2hsv, hsv2hwb } from './lib/hwb-hsv';
7
7
  import { lab2xyz, xyz2lab } from './lib/lab-xyz';
8
+ import { lab2lch, lch2lab } from './lib/lab-lch';
8
9
  import { rgb2hue } from './lib/util';
9
10
 
10
- /* Convert between RGB and LAB
11
+ /* Convert between RGB and Lab
11
12
  /* ========================================================================== */
12
13
 
13
14
  function rgb2lab(rgbR, rgbG, rgbB) {
@@ -24,7 +25,26 @@ function lab2rgb(labL, labA, labB) {
24
25
  return [ rgbR, rgbG, rgbB ];
25
26
  }
26
27
 
27
- /* Convert between HWB and HSL
28
+ /* Convert between RGB and LCH
29
+ /* ========================================================================== */
30
+
31
+ function rgb2lch(rgbR, rgbG, rgbB) {
32
+ const [ xyzX, xyzY, xyzZ ] = rgb2xyz(rgbR, rgbG, rgbB);
33
+ const [ labL, labA, labB ] = xyz2lab(xyzX, xyzY, xyzZ);
34
+ const [ lchL, lchC, lchH ] = lab2lch(labL, labA, labB);
35
+
36
+ return [ lchL, lchC, lchH ];
37
+ }
38
+
39
+ function lch2rgb(lchL, lchC, lchH) {
40
+ const [ labL, labA, labB ] = lch2lab(lchL, lchC, lchH);
41
+ const [ xyzX, xyzY, xyzZ ] = lab2xyz(labL, labA, labB);
42
+ const [ rgbR, rgbG, rgbB ] = xyz2rgb(xyzX, xyzY, xyzZ);
43
+
44
+ return [ rgbR, rgbG, rgbB ];
45
+ }
46
+
47
+ /* Convert between HSL and HWB
28
48
  /* ========================================================================== */
29
49
 
30
50
  function hwb2hsl(hwbH, hwbW, hwbB) {
@@ -41,7 +61,7 @@ function hsl2hwb(hslH, hslS, hslL) {
41
61
  return [ hslH, hwbW, hwbB ];
42
62
  }
43
63
 
44
- /* Convert between HSL and LAB
64
+ /* Convert between HSL and Lab
45
65
  /* ========================================================================== */
46
66
 
47
67
  function hsl2lab(hslH, hslS, hslL) {
@@ -52,10 +72,31 @@ function hsl2lab(hslH, hslS, hslL) {
52
72
  return [ labL, labA, labB ];
53
73
  }
54
74
 
55
- function lab2hsl(labL, labA, labB) {
75
+ function lab2hsl(labL, labA, labB, fallbackhue) {
76
+ const [ xyzX, xyzY, xyzZ ] = lab2xyz(labL, labA, labB);
77
+ const [ rgbR, rgbG, rgbB ] = xyz2rgb(xyzX, xyzY, xyzZ);
78
+ const [ hslH, hslS, hslL ] = rgb2hsl(rgbR, rgbG, rgbB, fallbackhue);
79
+
80
+ return [ hslH, hslS, hslL ];
81
+ }
82
+
83
+ /* Convert between HSL and LCH
84
+ /* ========================================================================== */
85
+
86
+ function hsl2lch(hslH, hslS, hslL) {
87
+ const [ rgbR, rgbG, rgbB ] = hsl2rgb(hslH, hslS, hslL);
88
+ const [ xyzX, xyzY, xyzZ ] = rgb2xyz(rgbR, rgbG, rgbB);
89
+ const [ labL, labA, labB ] = xyz2lab(xyzX, xyzY, xyzZ);
90
+ const [ lchL, lchC, lchH ] = lab2lch(labL, labA, labB);
91
+
92
+ return [ lchL, lchC, lchH ];
93
+ }
94
+
95
+ function lch2hsl(lchL, lchC, lchH, fallbackhue) {
96
+ const [ labL, labA, labB ] = lch2lab(lchL, lchC, lchH);
56
97
  const [ xyzX, xyzY, xyzZ ] = lab2xyz(labL, labA, labB);
57
98
  const [ rgbR, rgbG, rgbB ] = xyz2rgb(xyzX, xyzY, xyzZ);
58
- const [ hslH, hslS, hslL ] = rgb2hsl(rgbR, rgbG, rgbB);
99
+ const [ hslH, hslS, hslL ] = rgb2hsl(rgbR, rgbG, rgbB, fallbackhue);
59
100
 
60
101
  return [ hslH, hslS, hslL ];
61
102
  }
@@ -70,14 +111,14 @@ function hsl2xyz(hslH, hslS, hslL) {
70
111
  return [ xyzX, xyzY, xyzZ ];
71
112
  }
72
113
 
73
- function xyz2hsl(xyzX, xyzY, xyzZ) {
114
+ function xyz2hsl(xyzX, xyzY, xyzZ, fallbackhue) {
74
115
  const [ rgbR, rgbG, rgbB ] = xyz2rgb(xyzX, xyzY, xyzZ);
75
- const [ hslH, hslS, hslL ] = rgb2hsl(rgbR, rgbG, rgbB);
116
+ const [ hslH, hslS, hslL ] = rgb2hsl(rgbR, rgbG, rgbB, fallbackhue);
76
117
 
77
118
  return [ hslH, hslS, hslL ];
78
119
  }
79
120
 
80
- /* Convert between HWB and LAB
121
+ /* Convert between HWB and Lab
81
122
  /* ========================================================================== */
82
123
 
83
124
  function hwb2lab(hwbH, hwbW, hwbB) {
@@ -88,10 +129,31 @@ function hwb2lab(hwbH, hwbW, hwbB) {
88
129
  return [ labL, labA, labB ];
89
130
  }
90
131
 
91
- function lab2hwb(labL, labA, labB) {
132
+ function lab2hwb(labL, labA, labB, fallbackhue) {
92
133
  const [ xyzX, xyzY, xyzZ ] = lab2xyz(labL, labA, labB);
93
134
  const [ rgbR, rgbG, rgbB ] = xyz2rgb(xyzX, xyzY, xyzZ);
94
- const [ hwbH, hwbW, hwbB ] = rgb2hwb(rgbR, rgbG, rgbB);
135
+ const [ hwbH, hwbW, hwbB ] = rgb2hwb(rgbR, rgbG, rgbB, fallbackhue);
136
+
137
+ return [ hwbH, hwbW, hwbB ];
138
+ }
139
+
140
+ /* Convert between HWB and LCH
141
+ /* ========================================================================== */
142
+
143
+ function hwb2lch(hwbH, hwbW, hwbB) {
144
+ const [ rgbR, rgbG, rgbB ] = hwb2rgb(hwbH, hwbW, hwbB);
145
+ const [ xyzX, xyzY, xyzZ ] = rgb2xyz(rgbR, rgbG, rgbB);
146
+ const [ labL, labA, labB ] = xyz2lab(xyzX, xyzY, xyzZ);
147
+ const [ lchL, lchC, lchH ] = lab2lch(labL, labA, labB);
148
+
149
+ return [ lchL, lchC, lchH ];
150
+ }
151
+
152
+ function lch2hwb(lchL, lchC, lchH, fallbackhue) {
153
+ const [ labL, labA, labB ] = lch2lab(lchL, lchC, lchH);
154
+ const [ xyzX, xyzY, xyzZ ] = lab2xyz(labL, labA, labB);
155
+ const [ rgbR, rgbG, rgbB ] = xyz2rgb(xyzX, xyzY, xyzZ);
156
+ const [ hwbH, hwbW, hwbB ] = rgb2hwb(rgbR, rgbG, rgbB, fallbackhue);
95
157
 
96
158
  return [ hwbH, hwbW, hwbB ];
97
159
  }
@@ -106,14 +168,14 @@ function hwb2xyz(hwbH, hwbW, hwbB) {
106
168
  return [ xyzX, xyzY, xyzZ ];
107
169
  }
108
170
 
109
- function xyz2hwb(xyzX, xyzY, xyzZ) {
171
+ function xyz2hwb(xyzX, xyzY, xyzZ, fallbackhue) {
110
172
  const [ rgbR, rgbG, rgbB ] = xyz2rgb(xyzX, xyzY, xyzZ);
111
- const [ hwbH, hwbW, hwbB ] = rgb2hwb(rgbR, rgbG, rgbB);
173
+ const [ hwbH, hwbW, hwbB ] = rgb2hwb(rgbR, rgbG, rgbB, fallbackhue);
112
174
 
113
175
  return [ hwbH, hwbW, hwbB ];
114
176
  }
115
177
 
116
- /* Convert between HSV and LAB
178
+ /* Convert between HSV and Lab
117
179
  /* ========================================================================== */
118
180
 
119
181
  function hsv2lab(hsvH, hsvS, hsvV) {
@@ -124,10 +186,31 @@ function hsv2lab(hsvH, hsvS, hsvV) {
124
186
  return [ labL, labA, labB ];
125
187
  }
126
188
 
127
- function lab2hsv(labL, labA, labB) {
189
+ function lab2hsv(labL, labA, labB, fallbackhue) {
128
190
  const [ xyzX, xyzY, xyzZ ] = lab2xyz(labL, labA, labB);
129
191
  const [ rgbR, rgbG, rgbB ] = xyz2rgb(xyzX, xyzY, xyzZ);
130
- const [ hsvH, hsvS, hsvV ] = rgb2hsv(rgbR, rgbG, rgbB);
192
+ const [ hsvH, hsvS, hsvV ] = rgb2hsv(rgbR, rgbG, rgbB, fallbackhue);
193
+
194
+ return [ hsvH, hsvS, hsvV ];
195
+ }
196
+
197
+ /* Convert between HSV and LCH
198
+ /* ========================================================================== */
199
+
200
+ function hsv2lch(hsvH, hsvS, hsvV) {
201
+ const [ rgbR, rgbG, rgbB ] = hsv2rgb(hsvH, hsvS, hsvV);
202
+ const [ xyzX, xyzY, xyzZ ] = rgb2xyz(rgbR, rgbG, rgbB);
203
+ const [ labL, labA, labB ] = xyz2lab(xyzX, xyzY, xyzZ);
204
+ const [ lchL, lchC, lchH ] = lab2lch(labL, labA, labB);
205
+
206
+ return [ lchL, lchC, lchH ];
207
+ }
208
+
209
+ function lch2hsv(lchL, lchC, lchH, fallbackhue) {
210
+ const [ labL, labA, labB ] = lch2lab(lchL, lchC, lchH);
211
+ const [ xyzX, xyzY, xyzZ ] = lab2xyz(labL, labA, labB);
212
+ const [ rgbR, rgbG, rgbB ] = xyz2rgb(xyzX, xyzY, xyzZ);
213
+ const [ hsvH, hsvS, hsvV ] = rgb2hsv(rgbR, rgbG, rgbB, fallbackhue);
131
214
 
132
215
  return [ hsvH, hsvS, hsvV ];
133
216
  }
@@ -142,51 +225,134 @@ function hsv2xyz(hsvH, hsvS, hsvV) {
142
225
  return [ xyzX, xyzY, xyzZ ];
143
226
  }
144
227
 
145
- function xyz2hsv(xyzX, xyzY, xyzZ) {
228
+ function xyz2hsv(xyzX, xyzY, xyzZ, fallbackhue) {
146
229
  const [ rgbR, rgbG, rgbB ] = xyz2rgb(xyzX, xyzY, xyzZ);
147
- const [ hsvH, hsvS, hsvV ] = rgb2hsv(rgbR, rgbG, rgbB);
230
+ const [ hsvH, hsvS, hsvV ] = rgb2hsv(rgbR, rgbG, rgbB, fallbackhue);
148
231
 
149
232
  return [ hsvH, hsvS, hsvV ];
150
233
  }
151
234
 
235
+ /* Convert between XYZ and LCH
236
+ /* ========================================================================== */
237
+
238
+ function xyz2lch(xyzX, xyzY, xyzZ) {
239
+ const [ labL, labA, labB ] = xyz2lab(xyzX, xyzY, xyzZ);
240
+ const [ lchL, lchC, lchH ] = lab2lch(labL, labA, labB);
241
+
242
+ return [ lchL, lchC, lchH ];
243
+ }
244
+
245
+ function lch2xyz(lchL, lchC, lchH) {
246
+ const [ labL, labA, labB ] = lch2lab(lchL, lchC, lchH);
247
+ const [ xyzX, xyzY, xyzZ ] = lab2xyz(labL, labA, labB);
248
+
249
+ return [ xyzX, xyzY, xyzZ ];
250
+ }
251
+
152
252
  /* All Conversions
153
253
  /* ========================================================================== */
154
254
 
255
+ export {
256
+ rgb2hsl,
257
+ rgb2hwb,
258
+ rgb2lab,
259
+ rgb2lch,
260
+ rgb2hsv,
261
+ rgb2xyz,
262
+
263
+ hsl2rgb,
264
+ hsl2hwb,
265
+ hsl2lab,
266
+ hsl2lch,
267
+ hsl2hsv,
268
+ hsl2xyz,
269
+
270
+ hwb2rgb,
271
+ hwb2hsl,
272
+ hwb2lab,
273
+ hwb2lch,
274
+ hwb2hsv,
275
+ hwb2xyz,
276
+
277
+ lab2rgb,
278
+ lab2hsl,
279
+ lab2hwb,
280
+ lab2lch,
281
+ lab2hsv,
282
+ lab2xyz,
283
+
284
+ lch2rgb,
285
+ lch2hsl,
286
+ lch2hwb,
287
+ lch2lab,
288
+ lch2hsv,
289
+ lch2xyz,
290
+
291
+ hsv2rgb,
292
+ hsv2hsl,
293
+ hsv2hwb,
294
+ hsv2lab,
295
+ hsv2lch,
296
+ hsv2xyz,
297
+
298
+ xyz2rgb,
299
+ xyz2hsl,
300
+ xyz2hwb,
301
+ xyz2lab,
302
+ xyz2lch,
303
+ xyz2hsv,
304
+
305
+ rgb2hue
306
+ };
307
+
155
308
  export default {
156
309
  rgb2hsl,
157
310
  rgb2hwb,
158
311
  rgb2lab,
312
+ rgb2lch,
159
313
  rgb2hsv,
160
314
  rgb2xyz,
161
315
 
162
316
  hsl2rgb,
163
317
  hsl2hwb,
164
318
  hsl2lab,
319
+ hsl2lch,
165
320
  hsl2hsv,
166
321
  hsl2xyz,
167
322
 
168
323
  hwb2rgb,
169
324
  hwb2hsl,
170
325
  hwb2lab,
326
+ hwb2lch,
171
327
  hwb2hsv,
172
328
  hwb2xyz,
173
329
 
174
330
  lab2rgb,
175
331
  lab2hsl,
176
332
  lab2hwb,
333
+ lab2lch,
177
334
  lab2hsv,
178
335
  lab2xyz,
179
336
 
337
+ lch2rgb,
338
+ lch2hsl,
339
+ lch2hwb,
340
+ lch2lab,
341
+ lch2hsv,
342
+ lch2xyz,
343
+
180
344
  hsv2rgb,
181
345
  hsv2hsl,
182
346
  hsv2hwb,
183
347
  hsv2lab,
348
+ hsv2lch,
184
349
  hsv2xyz,
185
350
 
186
351
  xyz2rgb,
187
352
  xyz2hsl,
188
353
  xyz2hwb,
189
354
  xyz2lab,
355
+ xyz2lch,
190
356
  xyz2hsv,
191
357
 
192
358
  rgb2hue
package/lib/hsl-hsv.js CHANGED
@@ -1,8 +1,6 @@
1
1
  /* Convert between HSL and HSV
2
2
  /* ========================================================================== */
3
3
 
4
- // https://gist.github.com/defims/0ca2ef8832833186ed396a2f8a204117
5
-
6
4
  export function hsl2hsv(hslH, hslS, hslL) {
7
5
  const hsv1 = hslS * (hslL < 50 ? hslL : 100 - hslL) / 100;
8
6
  const hsvS = hsv1 === 0 ? 0 : 2 * hsv1 / (hslL + hsv1) * 100;
@@ -21,3 +19,12 @@ export function hsv2hsl(hsvH, hsvS, hsvV) {
21
19
 
22
20
  return [ hsvH, hslS, hslV ];
23
21
  }
22
+
23
+ /*
24
+
25
+ References
26
+ ----------
27
+
28
+ - https://gist.github.com/defims/0ca2ef8832833186ed396a2f8a204117
29
+
30
+ /* ========================================================================== */
package/lib/hwb-hsv.js CHANGED
@@ -1,8 +1,6 @@
1
1
  /* Convert between HWB and HSV
2
2
  /* ========================================================================== */
3
3
 
4
- // https://en.wikipedia.org/wiki/HWB_color_model#Converting_to_and_from_HSV
5
-
6
4
  export function hwb2hsv(hwbH, hwbW, hwbB) {
7
5
  const [ hsvH, hsvS, hsvV ] = [
8
6
  hwbH,
@@ -22,3 +20,12 @@ export function hsv2hwb(hsvH, hsvS, hsvV) {
22
20
 
23
21
  return [ hwbH, hwbW, hwbB ];
24
22
  }
23
+
24
+ /*
25
+
26
+ References
27
+ ----------
28
+
29
+ - https://en.wikipedia.org/wiki/HWB_color_model#Converting_to_and_from_HSV
30
+
31
+ /* ========================================================================== */
package/lib/lab-lch.js ADDED
@@ -0,0 +1,31 @@
1
+ /* Convert between Lab and XYZ
2
+ /* ========================================================================== */
3
+
4
+ export function lab2lch(labL, labA, labB) {
5
+ const [ lchC, lchH ] = [
6
+ Math.sqrt(Math.pow(labA, 2) + Math.pow(labB, 2)), // convert to chroma
7
+ Math.atan2(labB, labA) * 180 / Math.PI // convert to hue, in degrees
8
+ ];
9
+
10
+ return [ labL, lchC, lchH ];
11
+ }
12
+
13
+ export function lch2lab(lchL, lchC, lchH) {
14
+ // convert to Lab a and b from the polar form
15
+ const [ labA, labB ] = [
16
+ lchC * Math.cos(lchH * Math.PI / 180),
17
+ lchC * Math.sin(lchH * Math.PI / 180)
18
+ ];
19
+
20
+ return [ lchL, labA, labB ];
21
+ }
22
+
23
+ /*
24
+
25
+ References
26
+ ----------
27
+
28
+ - https://www.w3.org/TR/css-color-4/#lch-to-lab
29
+ - https://www.w3.org/TR/css-color-4/#color-conversion-code
30
+
31
+ /* ========================================================================== */
package/lib/lab-xyz.js CHANGED
@@ -1,12 +1,8 @@
1
1
  import { epsilon, kappa, wd50X, wd50Y, wd50Z, matrix } from './util';
2
2
 
3
- /* Convert between LAB and XYZ
3
+ /* Convert between Lab and XYZ
4
4
  /* ========================================================================== */
5
5
 
6
- // https://www.w3.org/TR/css-color-4/#rgb-to-lab
7
- // https://www.w3.org/TR/css-color-4/#color-conversion-code
8
- // https://www.easyrgb.com/en/math.php
9
-
10
6
  export function lab2xyz(labL, labA, labB) {
11
7
  // compute f, starting with the luminance-related term
12
8
  const f2 = (labL + 16) / 116;
@@ -59,3 +55,14 @@ export function xyz2lab(xyzX, xyzY, xyzZ) {
59
55
 
60
56
  return [ labL, labA, labB ];
61
57
  }
58
+
59
+ /*
60
+
61
+ References
62
+ ----------
63
+
64
+ - https://www.w3.org/TR/css-color-4/#rgb-to-lab
65
+ - https://www.w3.org/TR/css-color-4/#color-conversion-code
66
+ - https://www.easyrgb.com/en/math.php
67
+
68
+ /* ========================================================================== */
package/lib/rgb-hsl.js CHANGED
@@ -3,13 +3,8 @@ import { rgb2hue, rgb2value, rgb2whiteness, hue2rgb } from './util';
3
3
  /* Convert between RGB and HSL
4
4
  /* ========================================================================== */
5
5
 
6
- // https://www.w3.org/TR/css-color-3/#hsl-color
7
- // https://www.w3.org/TR/css-color-4/#hsl-to-rgb
8
- // https://www.rapidtables.com/convert/color/rgb-to-hsl.html
9
- // https://www.rapidtables.com/convert/color/hsl-to-rgb.html
10
-
11
- export function rgb2hsl(rgbR, rgbG, rgbB) {
12
- const hslH = rgb2hue(rgbR, rgbG, rgbB);
6
+ export function rgb2hsl(rgbR, rgbG, rgbB, fallbackhue) {
7
+ const hslH = rgb2hue(rgbR, rgbG, rgbB, fallbackhue);
13
8
  const hslV = rgb2value(rgbR, rgbG, rgbB);
14
9
  const hslW = rgb2whiteness(rgbR, rgbG, rgbB);
15
10
 
@@ -41,3 +36,15 @@ export function hsl2rgb(hslH, hslS, hslL) {
41
36
 
42
37
  return [ rgbR, rgbG, rgbB ];
43
38
  }
39
+
40
+ /*
41
+
42
+ References
43
+ ----------
44
+
45
+ - https://www.w3.org/TR/css-color-3/#hsl-color
46
+ - https://www.w3.org/TR/css-color-4/#hsl-to-rgb
47
+ - https://www.rapidtables.com/convert/color/rgb-to-hsl.html
48
+ - https://www.rapidtables.com/convert/color/hsl-to-rgb.html
49
+
50
+ /* ========================================================================== */
package/lib/rgb-hsv.js CHANGED
@@ -3,12 +3,10 @@ import { rgb2value, rgb2whiteness, rgb2hue } from './util';
3
3
  /* Convert between RGB and HSV
4
4
  /* ========================================================================== */
5
5
 
6
- // http://alvyray.com/Papers/CG/hsv2rgb.htm
7
-
8
- export function rgb2hsv(rgbR, rgbG, rgbB) {
6
+ export function rgb2hsv(rgbR, rgbG, rgbB, fallbackhue) {
9
7
  const hsvV = rgb2value(rgbR, rgbG, rgbB);
10
8
  const hsvW = rgb2whiteness(rgbR, rgbG, rgbB);
11
- const hsvH = rgb2hue(rgbR, rgbG, rgbB);
9
+ const hsvH = rgb2hue(rgbR, rgbG, rgbB, fallbackhue);
12
10
 
13
11
  // calculate saturation
14
12
  const hsvS = hsvV === hsvW ? 0 : (hsvV - hsvW) / hsvV * 100;
@@ -20,17 +18,30 @@ export function hsv2rgb(hsvH, hsvS, hsvV) {
20
18
  const rgbI = Math.floor(hsvH / 60);
21
19
 
22
20
  // calculate rgb parts
23
- const rgbF = (hsvH / 60 - rgbI) & 1 ? hsvH / 60 - rgbI : 1 - hsvH / 60 - rgbI;
21
+ const rgbF = hsvH / 60 - rgbI & 1 ? hsvH / 60 - rgbI : 1 - hsvH / 60 - rgbI;
24
22
  const rgbM = hsvV * (100 - hsvS) / 100;
25
23
  const rgbN = hsvV * (100 - hsvS * rgbF) / 100;
26
24
 
27
- switch (rgbI) {
28
- case 6:
29
- case 0: return [hsvV, rgbN, rgbM];
30
- case 1: return [rgbN, hsvV, rgbM];
31
- case 2: return [rgbM, hsvV, rgbN];
32
- case 3: return [rgbM, rgbN, hsvV];
33
- case 4: return [rgbN, rgbM, hsvV];
34
- case 5: return [hsvV, rgbM, rgbN];
35
- }
25
+ const [ rgbR, rgbG, rgbB ] = rgbI === 5
26
+ ? [ hsvV, rgbM, rgbN ]
27
+ : rgbI === 4
28
+ ? [ rgbN, rgbM, hsvV ]
29
+ : rgbI === 3
30
+ ? [ rgbM, rgbN, hsvV ]
31
+ : rgbI === 2
32
+ ? [ rgbM, hsvV, rgbN ]
33
+ : rgbI === 1
34
+ ? [ rgbN, hsvV, rgbM ]
35
+ : [ hsvV, rgbN, rgbM ];
36
+
37
+ return [ rgbR, rgbG, rgbB ];
36
38
  }
39
+
40
+ /*
41
+
42
+ References
43
+ ----------
44
+
45
+ - http://alvyray.com/Papers/CG/hsv2rgb.htm
46
+
47
+ /* ========================================================================== */
package/lib/rgb-hwb.js CHANGED
@@ -4,11 +4,8 @@ import { hsl2rgb } from './rgb-hsl';
4
4
  /* Convert between RGB and HWB
5
5
  /* ========================================================================== */
6
6
 
7
- // https://www.w3.org/TR/css-color-4/#hwb-to-rgb
8
- // http://alvyray.com/Papers/CG/hwb2rgb.htm
9
-
10
- export function rgb2hwb(rgbR, rgbG, rgbB) {
11
- const hwbH = rgb2hue(rgbR, rgbG, rgbB);
7
+ export function rgb2hwb(rgbR, rgbG, rgbB, fallbackhue) {
8
+ const hwbH = rgb2hue(rgbR, rgbG, rgbB, fallbackhue);
12
9
  const hwbW = rgb2whiteness(rgbR, rgbG, rgbB);
13
10
  const hwbV = rgb2value(rgbR, rgbG, rgbB);
14
11
  const hwbB = 100 - hwbV;
@@ -16,10 +13,20 @@ export function rgb2hwb(rgbR, rgbG, rgbB) {
16
13
  return [hwbH, hwbW, hwbB];
17
14
  }
18
15
 
19
- export function hwb2rgb(hwbH, hwbW, hwbB) {
20
- const [ rgbR, rgbG, rgbB ] = hsl2rgb(hwbH, 100, 50).map(
16
+ export function hwb2rgb(hwbH, hwbW, hwbB, fallbackhue) {
17
+ const [ rgbR, rgbG, rgbB ] = hsl2rgb(hwbH, 100, 50, fallbackhue).map(
21
18
  v => v * (100 - hwbW - hwbB) / 100 + hwbW
22
19
  );
23
20
 
24
21
  return [ rgbR, rgbG, rgbB ];
25
22
  }
23
+
24
+ /*
25
+
26
+ References
27
+ ----------
28
+
29
+ - https://www.w3.org/TR/css-color-4/#hwb-to-rgb
30
+ - http://alvyray.com/Papers/CG/hwb2rgb.htm
31
+
32
+ /* ========================================================================== */
package/lib/rgb-xyz.js CHANGED
@@ -30,3 +30,13 @@ export function xyz2rgb(xyzX, xyzY, xyzZ) {
30
30
 
31
31
  return [ rgbR, rgbG, rgbB ];
32
32
  }
33
+
34
+ /*
35
+
36
+ References
37
+ ----------
38
+
39
+ - https://www.w3.org/TR/css-color-4/#rgb-to-lab
40
+ - https://www.w3.org/TR/css-color-4/#color-conversion-code
41
+
42
+ /* ========================================================================== */
package/lib/util.js CHANGED
@@ -1,50 +1,52 @@
1
1
  /* Convert between RGB and Hue
2
2
  /* ========================================================================== */
3
3
 
4
- export function rgb2hue(rgbR, rgbG, rgbB) {
4
+ export function rgb2hue(rgbR, rgbG, rgbB, fallbackhue = 0) {
5
5
  const value = rgb2value(rgbR, rgbG, rgbB);
6
6
  const whiteness = rgb2whiteness(rgbR, rgbG, rgbB);
7
- const delta = value - whiteness;
8
-
9
- // calculate segment
10
- const segment = value === rgbR
11
- ? (rgbG - rgbB) / delta
12
- : value === rgbG
13
- ? (rgbB - rgbR) / delta
14
- : (rgbR - rgbG) / delta;
15
-
16
- // calculate shift
17
- const shift = value === rgbR
18
- ? segment < 0
19
- ? 360 / 60
20
- : 0 / 60
21
- : value === rgbG
22
- ? 120 / 60
23
- : 240 / 60;
24
-
25
- // calculate hue
26
- const hue = (segment + shift) * 60 || 0;
27
-
28
- return hue;
7
+ const delta = value - whiteness;
8
+
9
+ if (delta) {
10
+ // calculate segment
11
+ const segment = value === rgbR
12
+ ? (rgbG - rgbB) / delta
13
+ : value === rgbG
14
+ ? (rgbB - rgbR) / delta
15
+ : (rgbR - rgbG) / delta;
16
+
17
+ // calculate shift
18
+ const shift = value === rgbR
19
+ ? segment < 0
20
+ ? 360 / 60
21
+ : 0 / 60
22
+ : value === rgbG
23
+ ? 120 / 60
24
+ : 240 / 60;
25
+
26
+ // calculate hue
27
+ const hue = (segment + shift) * 60;
28
+
29
+ return hue;
30
+ } else {
31
+ // otherwise return the fallback hue
32
+ return fallbackhue;
33
+ }
29
34
  }
30
35
 
31
36
  export function hue2rgb(t1, t2, hue) {
32
- // calculate ranged hue
37
+ // calculate the ranged hue
33
38
  const rhue = hue < 0 ? hue + 360 : hue > 360 ? hue - 360 : hue;
34
39
 
35
- if (rhue * 6 < 360) {
36
- return t1 + (t2 - t1) * rhue / 60;
37
- }
38
-
39
- if (rhue * 2 < 360) {
40
- return t2;
41
- }
42
-
43
- if (rhue * 3 < 720) {
44
- return t1 + (t2 - t1) * (240 - rhue) / 60;
45
- }
40
+ // calculate the rgb value
41
+ const rgb = rhue * 6 < 360
42
+ ? t1 + (t2 - t1) * rhue / 60
43
+ : rhue * 2 < 360
44
+ ? t2
45
+ : rhue * 3 < 720
46
+ ? t1 + (t2 - t1) * (240 - rhue) / 60
47
+ : t1;
46
48
 
47
- return t1;
49
+ return rgb;
48
50
  }
49
51
 
50
52
  /* RGB tooling
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@csstools/convert-colors",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Convert colors between RGB, HSL, and HWB",
5
5
  "author": "Jonathan Neal <jonathantneal@hotmail.com>",
6
6
  "license": "CC0-1.0",
@@ -47,10 +47,16 @@
47
47
  "keywords": [
48
48
  "colors",
49
49
  "converts",
50
+ "conversions",
51
+ "converting",
50
52
  "css",
51
53
  "rgb",
52
54
  "hsl",
53
55
  "hwb",
56
+ "lab",
57
+ "lch",
58
+ "hsv",
59
+ "xyz",
54
60
  "red",
55
61
  "green",
56
62
  "blue",
@@ -58,6 +64,7 @@
58
64
  "saturation",
59
65
  "lightness",
60
66
  "whiteness",
61
- "blackness"
67
+ "blackness",
68
+ "cie"
62
69
  ]
63
70
  }