@thi.ng/color 5.7.66 → 5.8.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/README.md CHANGED
@@ -21,6 +21,14 @@ For the Clojure version, please visit: [thi.ng/color-clj](https://thi.ng/color-c
21
21
  - [Color creation / conversion](#color-creation--conversion)
22
22
  - [Storage & memory mapping](#storage--memory-mapping)
23
23
  - [Color theme generation](#color-theme-generation)
24
+ - [Color theme strategies](#color-theme-strategies)
25
+ - [Analog colors](#analog-colors)
26
+ - [Split-analog colors](#split-analog-colors)
27
+ - [Complementary colors](#complementary-colors)
28
+ - [Split-complementary colors](#split-complementary-colors)
29
+ - [Monochrome colors](#monochrome-colors)
30
+ - [Triadic colors](#triadic-colors)
31
+ - [Tetradic colors](#tetradic-colors)
24
32
  - [Color sorting & distance](#color-sorting--distance)
25
33
  - [Sorting memory-mapped colors](#sorting-memory-mapped-colors)
26
34
  - [Gradients](#gradients)
@@ -372,6 +380,87 @@ writeFileSync("swatches-ex01.svg", serialize(doc));
372
380
 
373
381
  ![example result color swatches](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/color/swatches-ex01.svg)
374
382
 
383
+ ### Color theme strategies
384
+
385
+ In addition to the above approaches to create color themes, the package also provides these more standard strategies to derive a color theme from a given base color:
386
+
387
+ #### Analog colors
388
+
389
+ [Documentation](https://docs.thi.ng/umbrella/color/functions/analogStrategy.html)
390
+
391
+ ```ts tangle:export/analog-strategy.ts
392
+ import { analogStrategy, cssColors } from "@thi.ng/color";
393
+
394
+ console.log(cssColors(analogStrategy("#f90")));
395
+ //
396
+ ```
397
+
398
+ #### Split-analog colors
399
+
400
+ [Documentation](https://docs.thi.ng/umbrella/color/functions/splitAnalogStrategy.html)
401
+
402
+ ```ts tangle:export/split-analog-strategy.ts
403
+ import { splitAnalogStrategy, cssColors } from "@thi.ng/color";
404
+
405
+ console.log(cssColors(splitAnalogStrategy("#f90")));
406
+ //
407
+ ```
408
+
409
+ #### Complementary colors
410
+
411
+ [Documentation](https://docs.thi.ng/umbrella/color/functions/complementaryStrategy.html)
412
+
413
+ ```ts tangle:export/complementary-strategy.ts
414
+ import { complementaryStrategy, cssColors } from "@thi.ng/color";
415
+
416
+ console.log(cssColors(complementaryStrategy("#f90")));
417
+ //
418
+ ```
419
+
420
+ #### Split-complementary colors
421
+
422
+ [Documentation](https://docs.thi.ng/umbrella/color/functions/splitComplementaryStrategy.html)
423
+
424
+ ```ts tangle:export/split-complementary-strategy.ts
425
+ import { splitComplementaryStrategy, cssColors } from "@thi.ng/color";
426
+
427
+ console.log(cssColors(splitComplementaryStrategy("#f90")));
428
+ //
429
+ ```
430
+
431
+ #### Monochrome colors
432
+
433
+ [Documentation](https://docs.thi.ng/umbrella/color/functions/monochromeStrategy.html)
434
+
435
+ ```ts tangle:export/monochrome-strategy.ts
436
+ import { monochromeStrategy, cssColors } from "@thi.ng/color";
437
+
438
+ console.log(cssColors(monochromeStrategy("#f90")));
439
+ //
440
+ ```
441
+
442
+ #### Triadic colors
443
+
444
+ [Documentation](https://docs.thi.ng/umbrella/color/functions/triadicStrategy.html)
445
+
446
+ ```ts tangle:export/triadic-strategy.ts
447
+ import { triadicStrategy, cssColors } from "@thi.ng/color";
448
+
449
+ console.log(cssColors(triadicStrategy("#f90")));
450
+ //
451
+ ```
452
+
453
+ #### Tetradic colors
454
+
455
+ [Documentation](https://docs.thi.ng/umbrella/color/functions/tetradicStrategy.html)
456
+
457
+ ```ts tangle:export/tetradic-strategy.ts
458
+ import { tetradicStrategy, cssColors } from "@thi.ng/color";
459
+
460
+ console.log(cssColors(tetradicStrategy("#f90")));
461
+ //
462
+ ```
463
+
375
464
  ### Color sorting & distance
376
465
 
377
466
  The package provides several functions to compute full or channel-wise distances
@@ -693,7 +782,7 @@ For Node.js REPL:
693
782
  const color = await import("@thi.ng/color");
694
783
  ```
695
784
 
696
- Package sizes (brotli'd, pre-treeshake): ESM: 15.84 KB
785
+ Package sizes (brotli'd, pre-treeshake): ESM: 15.80 KB
697
786
 
698
787
  ## Dependencies
699
788
 
package/css/css.d.ts CHANGED
@@ -55,4 +55,12 @@ export declare const setDefaultCSSConversions: (fns: CSSConversions) => Partial<
55
55
  * @param cssTarget - CSS conversions
56
56
  */
57
57
  export declare const css: (src: Exclude<MaybeColor, IParsedColor>, cssTarget?: CSSConversions) => string;
58
+ /**
59
+ * Convenience helper to convert an iterable of colors into an array of CSS
60
+ * strings (using {@link css}).
61
+ *
62
+ * @param colors
63
+ * @param cssTarget
64
+ */
65
+ export declare const cssColors: (colors: Iterable<Exclude<MaybeColor, IParsedColor>>, cssTarget?: CSSConversions) => string[];
58
66
  //# sourceMappingURL=css.d.ts.map
package/css/css.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { ensureArray } from "@thi.ng/arrays/ensure-array";
1
2
  import { isNumber } from "@thi.ng/checks/is-number";
2
3
  import { isString } from "@thi.ng/checks/is-string";
3
4
  import { convert } from "../convert.js";
@@ -42,9 +43,11 @@ const css = (src, cssTarget = CSS_DEFAULT) => {
42
43
  convert([], src, "rgb", src.mode)
43
44
  ) : srgbCss(src);
44
45
  };
46
+ const cssColors = (colors, cssTarget = CSS_DEFAULT) => ensureArray(colors).map((x) => css(x, cssTarget));
45
47
  export {
46
48
  CSS_LEVEL3,
47
49
  CSS_LEVEL4,
48
50
  css,
51
+ cssColors,
49
52
  setDefaultCSSConversions
50
53
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/color",
3
- "version": "5.7.66",
3
+ "version": "5.8.0",
4
4
  "description": "Array-based color types, CSS parsing, conversions, transformations, declarative theme generation, gradients, presets",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -43,19 +43,19 @@
43
43
  "tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
44
44
  },
45
45
  "dependencies": {
46
- "@thi.ng/api": "^8.12.6",
47
- "@thi.ng/arrays": "^2.13.15",
48
- "@thi.ng/binary": "^3.4.64",
49
- "@thi.ng/checks": "^3.7.22",
50
- "@thi.ng/compare": "^2.4.32",
51
- "@thi.ng/compose": "^3.0.43",
52
- "@thi.ng/defmulti": "^3.0.82",
53
- "@thi.ng/errors": "^2.5.46",
54
- "@thi.ng/math": "^5.13.3",
55
- "@thi.ng/random": "^4.1.31",
56
- "@thi.ng/strings": "^3.9.26",
57
- "@thi.ng/transducers": "^9.6.14",
58
- "@thi.ng/vectors": "^8.6.10"
46
+ "@thi.ng/api": "^8.12.7",
47
+ "@thi.ng/arrays": "^2.13.16",
48
+ "@thi.ng/binary": "^3.4.65",
49
+ "@thi.ng/checks": "^3.7.23",
50
+ "@thi.ng/compare": "^2.4.33",
51
+ "@thi.ng/compose": "^3.0.44",
52
+ "@thi.ng/defmulti": "^3.0.83",
53
+ "@thi.ng/errors": "^2.5.47",
54
+ "@thi.ng/math": "^5.13.4",
55
+ "@thi.ng/random": "^4.1.32",
56
+ "@thi.ng/strings": "^3.9.27",
57
+ "@thi.ng/transducers": "^9.6.15",
58
+ "@thi.ng/vectors": "^8.6.11"
59
59
  },
60
60
  "devDependencies": {
61
61
  "esbuild": "^0.25.11",
@@ -446,5 +446,5 @@
446
446
  "vectors"
447
447
  ]
448
448
  },
449
- "gitHead": "136a5e5ef0b69e82329db00d806c3c4e8f1aa063\n"
449
+ "gitHead": "d977f819bcafdcb2b24c45f8d01a167fe29fc85a\n"
450
450
  }
package/strategies.d.ts CHANGED
@@ -1,13 +1,15 @@
1
+ import type { MaybeColor } from "./api.js";
1
2
  import { type LCH } from "./lch/lch.js";
2
3
  /**
3
- * Returns array of `src` color and its complementary color, possibly adjusted
4
- * via optional `deltaL` and `deltaC` args (offsets for L & C channels).
4
+ * Returns array of `src` color (converted to LCH) and its complementary color,
5
+ * possibly adjusted via optional `deltaL` and `deltaC` args (offsets for L & C
6
+ * channels).
5
7
  *
6
8
  * @param src -
7
9
  * @param deltaL -
8
10
  * @param deltaC -
9
11
  */
10
- export declare const complementaryStrategy: (src: LCH, deltaL?: number, deltaC?: number) => LCH[];
12
+ export declare const complementaryStrategy: (src: MaybeColor, deltaL?: number, deltaC?: number) => LCH[];
11
13
  /**
12
14
  * Returns array of `src` color and 2 neighboring colors, each ±rotated by
13
15
  * normalized `theta` and possibly adjusted via optional `deltaL` and `deltaC`
@@ -18,7 +20,7 @@ export declare const complementaryStrategy: (src: LCH, deltaL?: number, deltaC?:
18
20
  * @param deltaL -
19
21
  * @param deltaC -
20
22
  */
21
- export declare const analogStrategy: (src: LCH, theta?: number, deltaL?: number, deltaC?: number) => LCH[];
23
+ export declare const analogStrategy: (src: MaybeColor, theta?: number, deltaL?: number, deltaC?: number) => LCH[];
22
24
  /**
23
25
  * Similar to {@link splitComplementaryStrategy}. Returns array of `src` color,
24
26
  * its complementary color and 2 of that colors' neighbors, each ±rotated by
@@ -30,7 +32,7 @@ export declare const analogStrategy: (src: LCH, theta?: number, deltaL?: number,
30
32
  * @param deltaL -
31
33
  * @param deltaC -
32
34
  */
33
- export declare const splitAnalogStrategy: (src: LCH, theta?: number, deltaL?: number, deltaC?: number) => LCH[];
35
+ export declare const splitAnalogStrategy: (src: MaybeColor, theta?: number, deltaL?: number, deltaC?: number) => LCH[];
34
36
  /**
35
37
  * Similar to {@link splitAnalogStrategy}. Returns array of `src` color and 2
36
38
  * neighbors of its complementary color, each ±rotated by normalized `theta`
@@ -42,7 +44,7 @@ export declare const splitAnalogStrategy: (src: LCH, theta?: number, deltaL?: nu
42
44
  * @param deltaL -
43
45
  * @param deltaC -
44
46
  */
45
- export declare const splitComplementaryStrategy: (src: LCH, theta?: number, deltaL?: number, deltaC?: number) => LCH[];
47
+ export declare const splitComplementaryStrategy: (src: MaybeColor, theta?: number, deltaL?: number, deltaC?: number) => LCH[];
46
48
  /**
47
49
  * Returns array of 5 colors all sharing same hue and chromacity of given `src`
48
50
  * color, but with these luminance settings: 0.0, 0.25, 0.5, 0.75, 1.0. Chroma
@@ -51,7 +53,7 @@ export declare const splitComplementaryStrategy: (src: LCH, theta?: number, delt
51
53
  * @param src -
52
54
  * @param deltaC -
53
55
  */
54
- export declare const monochromeStrategy: (src: LCH, deltaC?: number) => LCH[];
56
+ export declare const monochromeStrategy: (src: MaybeColor, deltaC?: number) => LCH[];
55
57
  /**
56
58
  * Version of {@link splitComplementaryStrategy} with an hardcoded `theta` of
57
59
  * 1/6 to produce 3 colors with hues uniformly distributed on the color wheel
@@ -62,7 +64,7 @@ export declare const monochromeStrategy: (src: LCH, deltaC?: number) => LCH[];
62
64
  * @param deltaL -
63
65
  * @param deltaC -
64
66
  */
65
- export declare const triadicStrategy: (src: LCH, deltaL?: number, deltaC?: number) => LCH[];
67
+ export declare const triadicStrategy: (src: MaybeColor, deltaL?: number, deltaC?: number) => LCH[];
66
68
  /**
67
69
  * Returns array of `src` color and 3 other colors whose hues form a rectangle,
68
70
  * using `theta` to define the angular separation. The hues are at: `src`,
@@ -75,7 +77,7 @@ export declare const triadicStrategy: (src: LCH, deltaL?: number, deltaC?: numbe
75
77
  * @param deltaL -
76
78
  * @param deltaC -
77
79
  */
78
- export declare const tetradicStrategy: (src: LCH, theta?: number, deltaL?: number, deltaC?: number) => LCH[];
80
+ export declare const tetradicStrategy: (src: MaybeColor, theta?: number, deltaL?: number, deltaC?: number) => LCH[];
79
81
  /**
80
82
  * Version of {@link tetradicStrategy} with an hardcoded `theta` of 1/4 to
81
83
  * produce 4 colors with hues uniformly distributed on the color wheel (possibly
@@ -86,5 +88,5 @@ export declare const tetradicStrategy: (src: LCH, theta?: number, deltaL?: numbe
86
88
  * @param deltaL -
87
89
  * @param deltaC -
88
90
  */
89
- export declare const squareStrategy: (src: LCH, deltaL?: number, deltaC?: number) => LCH[];
91
+ export declare const squareStrategy: (src: MaybeColor, deltaL?: number, deltaC?: number) => LCH[];
90
92
  //# sourceMappingURL=strategies.d.ts.map
package/strategies.js CHANGED
@@ -1,29 +1,40 @@
1
- import { clamp, clamp01 } from "@thi.ng/math/interval";
2
1
  import { lch } from "./lch/lch.js";
3
2
  import { rotate } from "./rotate.js";
4
3
  const $ = (src, l = 0, c = 0) => {
5
- src.l = clamp01(src.l + l);
6
- src.c = clamp(src.c + c, 0, 1.312);
4
+ src.l += l;
5
+ src.c += c;
7
6
  return src;
8
7
  };
9
- const complementaryStrategy = (src, deltaL, deltaC) => [src, $(rotate(lch(), src, 0.5), deltaL, deltaC)];
10
- const analogStrategy = (src, theta = 1 / 12, deltaL, deltaC) => [
11
- src,
12
- $(rotate(lch(), src, -theta), deltaL, deltaC),
13
- $(rotate(lch(), src, theta), deltaL, deltaC)
14
- ];
15
- const splitAnalogStrategy = (src, theta = 1 / 12, deltaL, deltaC) => [
16
- ...splitComplementaryStrategy(src, theta, deltaL, deltaC),
17
- $(rotate(lch(), src, theta), deltaL, deltaC)
18
- ];
19
- const splitComplementaryStrategy = (src, theta = 1 / 12, deltaL, deltaC) => [
20
- src,
21
- $(rotate(lch(), src, 0.5 - theta), deltaL, deltaC),
22
- $(rotate(lch(), src, 0.5 + theta), deltaL, deltaC)
23
- ];
8
+ const complementaryStrategy = (src, deltaL, deltaC) => {
9
+ const $src = lch(src);
10
+ return [$src, $(rotate(lch(), $src, 0.5), deltaL, deltaC)];
11
+ };
12
+ const analogStrategy = (src, theta = 1 / 12, deltaL, deltaC) => {
13
+ const $src = lch(src);
14
+ return [
15
+ $src,
16
+ $(rotate(lch(), $src, -theta), deltaL, deltaC),
17
+ $(rotate(lch(), $src, theta), deltaL, deltaC)
18
+ ];
19
+ };
20
+ const splitAnalogStrategy = (src, theta = 1 / 12, deltaL, deltaC) => {
21
+ const $src = lch(src);
22
+ return [
23
+ ...splitComplementaryStrategy($src, theta, deltaL, deltaC),
24
+ $(rotate(lch(), $src, theta), deltaL, deltaC)
25
+ ];
26
+ };
27
+ const splitComplementaryStrategy = (src, theta = 1 / 12, deltaL, deltaC) => {
28
+ const $src = lch(src);
29
+ return [
30
+ $src,
31
+ $(rotate(lch(), $src, 0.5 - theta), deltaL, deltaC),
32
+ $(rotate(lch(), $src, 0.5 + theta), deltaL, deltaC)
33
+ ];
34
+ };
24
35
  const monochromeStrategy = (src, deltaC = 0) => {
25
- let [_, c, h, a] = src;
26
- c = clamp(c + deltaC, 0, 1.312);
36
+ let [_, c, h, a] = lch(src);
37
+ c += deltaC;
27
38
  return [
28
39
  lch(0, c, h, a),
29
40
  lch(0.25, c, h, a),
@@ -33,12 +44,15 @@ const monochromeStrategy = (src, deltaC = 0) => {
33
44
  ];
34
45
  };
35
46
  const triadicStrategy = (src, deltaL, deltaC) => splitComplementaryStrategy(src, 1 / 6, deltaL, deltaC);
36
- const tetradicStrategy = (src, theta = 1 / 12, deltaL, deltaC) => [
37
- src,
38
- $(rotate(lch(), src, theta), deltaL, deltaC),
39
- $(rotate(lch(), src, 0.5), deltaL, deltaC),
40
- $(rotate(lch(), src, 0.5 + theta), deltaL, deltaC)
41
- ];
47
+ const tetradicStrategy = (src, theta = 1 / 12, deltaL, deltaC) => {
48
+ const $src = lch(src);
49
+ return [
50
+ $src,
51
+ $(rotate(lch(), $src, theta), deltaL, deltaC),
52
+ $(rotate(lch(), $src, 0.5), deltaL, deltaC),
53
+ $(rotate(lch(), $src, 0.5 + theta), deltaL, deltaC)
54
+ ];
55
+ };
42
56
  const squareStrategy = (src, deltaL, deltaC) => tetradicStrategy(src, 0.25, deltaL, deltaC);
43
57
  export {
44
58
  analogStrategy,