@texel/color 1.1.2 → 1.1.3

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/README.md CHANGED
@@ -85,7 +85,7 @@ The return value is the new coordinates in the destination space; such as `[r,g,
85
85
 
86
86
  #### `output = gamutMapOKLCH(oklch, gamut = sRGBGamut, targetSpace = gamut.space, out = [0, 0, 0], mapping = MapToCuspL, [cusp])`
87
87
 
88
- Performs fast gamut mapping in OKLCH as [described by Björn Ottoson](https://bottosson.github.io/posts/gamutclipping/) (2021). This takes an input `[l,c,h]` coords in OKLCH space, and ensures the final result will lie within the specified color `gamut` (default `sRGBGamut`). You can further specify a different target space (which default's to the gamut's space), for example to get a linear-light sRGB and avoid the transfer function, or to keep the result in OKLCH:
88
+ Performs fast gamut mapping in OKLCH as [described by Björn Ottosson](https://bottosson.github.io/posts/gamutclipping/) (2021). This takes an input `[l,c,h]` coords in OKLCH space, and ensures the final result will lie within the specified color `gamut` (default `sRGBGamut`). You can further specify a different target space (which default's to the gamut's space), for example to get a linear-light sRGB and avoid the transfer function, or to keep the result in OKLCH:
89
89
 
90
90
  ```js
91
91
  import { gamutMapOKLCH, sRGBGamut, sRGBLinear, OKLCH } from "@texel/color";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@texel/color",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "a minimal and modern color library",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
package/src/gamut.js CHANGED
@@ -182,13 +182,15 @@ export const findGamutIntersectionOKLCH = (a, b, l1, c1, l0, cusp, gamut) => {
182
182
 
183
183
  // Find the intersection for upper and lower half separately
184
184
  if ((l1 - l0) * cusp[1] - (cusp[0] - l0) * c1 <= 0.0) {
185
+ const denom = (c1 * cusp[0] + cusp[1] * (l0 - l1));
185
186
  // Lower half
186
- t = (cusp[1] * l0) / (c1 * cusp[0] + cusp[1] * (l0 - l1));
187
+ t = denom === 0 ? 0 : (cusp[1] * l0) / denom;
187
188
  } else {
188
189
  // Upper half
189
190
 
190
191
  // First intersect with triangle
191
- t = (cusp[1] * (l0 - 1.0)) / (c1 * (cusp[0] - 1.0) + cusp[1] * (l0 - l1));
192
+ const denom = (c1 * (cusp[0] - 1.0) + cusp[1] * (l0 - l1));
193
+ t = denom === 0 ? 0 : (cusp[1] * (l0 - 1.0)) / denom;
192
194
 
193
195
  // Then one step Halley's method
194
196
  let dl = l1 - l0;
package/test/test.js CHANGED
@@ -44,6 +44,7 @@ import {
44
44
  DisplayP3Gamut,
45
45
  deserialize,
46
46
  parse,
47
+ MapToL,
47
48
  } from "../src/index.js";
48
49
 
49
50
  test("should convert XYZ in different whitepoints", async (t) => {
@@ -282,7 +283,6 @@ test("should serialize", async (t) => {
282
283
  // });
283
284
 
284
285
  test("should deserialize color string information", async (t) => {
285
-
286
286
  t.deepEqual(deserialize("rgb(0, 128, 255)"), {
287
287
  coords: [0, 128 / 0xff, 255 / 0xff],
288
288
  id: "srgb",
@@ -307,6 +307,10 @@ test("should deserialize color string information", async (t) => {
307
307
  coords: [0, 128 / 0xff, 255 / 0xff, 0.5],
308
308
  id: "srgb",
309
309
  });
310
+ t.deepEqual(deserialize("rgb(0 128 255 / 1e-2)"), {
311
+ coords: [0, 128 / 0xff, 255 / 0xff, 1e-2],
312
+ id: "srgb",
313
+ });
310
314
  t.deepEqual(deserialize("rgb(0 128 255 / 50%)"), {
311
315
  coords: [0, 128 / 0xff, 255 / 0xff, 0.5],
312
316
  id: "srgb",
@@ -343,6 +347,10 @@ test("should deserialize color string information", async (t) => {
343
347
  id: "srgb-linear",
344
348
  coords: [0, 0.5, 1],
345
349
  });
350
+ t.deepEqual(deserialize("color(srgb-linear 0 1e-2 1)"), {
351
+ id: "srgb-linear",
352
+ coords: [0, 1e-2, 1],
353
+ });
346
354
  t.deepEqual(deserialize("color(srgb-linear 0 0.5 1/0.25)"), {
347
355
  id: "srgb-linear",
348
356
  coords: [0, 0.5, 1, 0.25],
@@ -443,6 +451,28 @@ test("should handle problematic coords", async (t) => {
443
451
  ),
444
452
  true
445
453
  );
454
+
455
+ t.deepEqual(
456
+ convert([1, 0, 0], OKLCH, OKLab, undefined),
457
+ [1, 0, 0],
458
+ "handles [1,0,0] OKLCH to OKLab gamut map"
459
+ );
460
+
461
+ t.deepEqual(
462
+ arrayAlmostEqual(convert([1, 0, 0], OKLCH, sRGBLinear), [1, 1, 1]),
463
+ true,
464
+ "handles [1,1,1] OKLCH to sRGBLinear"
465
+ );
466
+ t.deepEqual(
467
+ gamutMapOKLCH([1, 0, 0], sRGBGamut, OKLCH, undefined, MapToL),
468
+ [1, 0, 0],
469
+ "handles [1,0,0] OKLCH to sRGB gamut map"
470
+ );
471
+ t.deepEqual(
472
+ gamutMapOKLCH([0, 0, 0], sRGBGamut, OKLCH, undefined, MapToL),
473
+ [0, 0, 0],
474
+ "handles [0,0,0] OKLCH to sRGB gamut map"
475
+ );
446
476
  });
447
477
 
448
478
  function roundToNDecimals(value, digits) {