@tempots/std 0.27.0 → 0.28.1
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/color-D7FAmkht.cjs +1 -0
- package/color-SZxckS9U.js +522 -0
- package/color-adjust.cjs +1 -0
- package/color-adjust.d.ts +148 -0
- package/color-adjust.js +47 -0
- package/color-channel.cjs +1 -0
- package/color-channel.d.ts +118 -0
- package/color-channel.js +75 -0
- package/color-contrast.cjs +1 -0
- package/color-contrast.d.ts +96 -0
- package/color-contrast.js +22 -0
- package/color-distance.cjs +1 -0
- package/color-distance.d.ts +41 -0
- package/color-distance.js +25 -0
- package/color-gamut.cjs +1 -0
- package/color-gamut.d.ts +59 -0
- package/color-gamut.js +72 -0
- package/color-harmony.cjs +1 -0
- package/color-harmony.d.ts +81 -0
- package/color-harmony.js +35 -0
- package/color-hsl.cjs +1 -0
- package/color-hsl.d.ts +81 -0
- package/color-hsl.js +10 -0
- package/color-hsv.cjs +1 -0
- package/color-hsv.d.ts +116 -0
- package/color-hsv.js +12 -0
- package/color-hwb.cjs +1 -0
- package/color-hwb.d.ts +88 -0
- package/color-hwb.js +10 -0
- package/color-lab.cjs +1 -0
- package/color-lab.d.ts +161 -0
- package/color-lab.js +15 -0
- package/color-mix.cjs +1 -0
- package/color-mix.d.ts +50 -0
- package/color-mix.js +101 -0
- package/color-named.cjs +1 -0
- package/color-named.d.ts +8 -0
- package/color-named.js +153 -0
- package/color-oklab.cjs +1 -0
- package/color-oklab.d.ts +141 -0
- package/color-oklab.js +15 -0
- package/color-rgb.cjs +1 -0
- package/color-rgb.d.ts +119 -0
- package/color-rgb.js +14 -0
- package/color-utils.cjs +1 -0
- package/color-utils.d.ts +57 -0
- package/color-utils.js +54 -0
- package/color.cjs +1 -0
- package/color.d.ts +466 -0
- package/color.js +33 -0
- package/index.cjs +1 -1
- package/index.d.ts +16 -0
- package/index.js +383 -267
- package/package.json +113 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Color } from './color';
|
|
2
|
+
/**
|
|
3
|
+
* Increases the lightness of a color by the given amount.
|
|
4
|
+
*
|
|
5
|
+
* Operates in OKLCH space and returns the result in the
|
|
6
|
+
* same color space as the input.
|
|
7
|
+
*
|
|
8
|
+
* @param c - The color to lighten.
|
|
9
|
+
* @param amount - A value between 0 and 1 indicating how
|
|
10
|
+
* much to increase lightness.
|
|
11
|
+
* @returns The lightened color in the original color space.
|
|
12
|
+
* @public
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const light = lighten(rgb8a(100, 50, 50, 1), 0.2)
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare const lighten: (c: Color, amount: number) => Color;
|
|
19
|
+
/**
|
|
20
|
+
* Decreases the lightness of a color by the given amount.
|
|
21
|
+
*
|
|
22
|
+
* Operates in OKLCH space and returns the result in the
|
|
23
|
+
* same color space as the input.
|
|
24
|
+
*
|
|
25
|
+
* @param c - The color to darken.
|
|
26
|
+
* @param amount - A value between 0 and 1 indicating how
|
|
27
|
+
* much to decrease lightness.
|
|
28
|
+
* @returns The darkened color in the original color space.
|
|
29
|
+
* @public
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* const dark = darken(rgb8a(200, 150, 150, 1), 0.2)
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare const darken: (c: Color, amount: number) => Color;
|
|
36
|
+
/**
|
|
37
|
+
* Increases the chroma (saturation) of a color by the
|
|
38
|
+
* given amount.
|
|
39
|
+
*
|
|
40
|
+
* Operates in OKLCH space. The amount is scaled by 0.4 to
|
|
41
|
+
* map the 0–1 input range to the typical OKLCH chroma
|
|
42
|
+
* range.
|
|
43
|
+
*
|
|
44
|
+
* @param c - The color to saturate.
|
|
45
|
+
* @param amount - A value between 0 and 1 indicating how
|
|
46
|
+
* much to increase chroma.
|
|
47
|
+
* @returns The saturated color in the original color space.
|
|
48
|
+
* @public
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* const vivid = saturate(rgb8a(100, 100, 100, 1), 0.5)
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare const saturate: (c: Color, amount: number) => Color;
|
|
55
|
+
/**
|
|
56
|
+
* Decreases the chroma (saturation) of a color by the
|
|
57
|
+
* given amount.
|
|
58
|
+
*
|
|
59
|
+
* Operates in OKLCH space. The amount is scaled by 0.4 to
|
|
60
|
+
* map the 0–1 input range to the typical OKLCH chroma
|
|
61
|
+
* range.
|
|
62
|
+
*
|
|
63
|
+
* @param c - The color to desaturate.
|
|
64
|
+
* @param amount - A value between 0 and 1 indicating how
|
|
65
|
+
* much to decrease chroma.
|
|
66
|
+
* @returns The desaturated color in the original color
|
|
67
|
+
* space.
|
|
68
|
+
* @public
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* const muted = desaturate(rgb8a(255, 0, 0, 1), 0.5)
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare const desaturate: (c: Color, amount: number) => Color;
|
|
75
|
+
/**
|
|
76
|
+
* Increases the opacity (alpha) of a color by the given
|
|
77
|
+
* amount.
|
|
78
|
+
*
|
|
79
|
+
* No color space conversion is performed — the alpha
|
|
80
|
+
* channel is adjusted directly.
|
|
81
|
+
*
|
|
82
|
+
* @param c - The color to make more opaque.
|
|
83
|
+
* @param amount - A value between 0 and 1 indicating how
|
|
84
|
+
* much to increase alpha.
|
|
85
|
+
* @returns The color with increased opacity, in the same
|
|
86
|
+
* color space.
|
|
87
|
+
* @public
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* const opaque = opacify(rgb8a(100, 50, 50, 0.5), 0.3)
|
|
91
|
+
* // alpha is now 0.8
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export declare const opacify: (c: Color, amount: number) => Color;
|
|
95
|
+
/**
|
|
96
|
+
* Decreases the opacity (alpha) of a color by the given
|
|
97
|
+
* amount.
|
|
98
|
+
*
|
|
99
|
+
* No color space conversion is performed — the alpha
|
|
100
|
+
* channel is adjusted directly.
|
|
101
|
+
*
|
|
102
|
+
* @param c - The color to make more transparent.
|
|
103
|
+
* @param amount - A value between 0 and 1 indicating how
|
|
104
|
+
* much to decrease alpha.
|
|
105
|
+
* @returns The color with decreased opacity, in the same
|
|
106
|
+
* color space.
|
|
107
|
+
* @public
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* const faded = transparentize(rgb8a(100, 50, 50, 1), 0.3)
|
|
111
|
+
* // alpha is now 0.7
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export declare const transparentize: (c: Color, amount: number) => Color;
|
|
115
|
+
/**
|
|
116
|
+
* Inverts the RGB channels of a color while preserving
|
|
117
|
+
* alpha.
|
|
118
|
+
*
|
|
119
|
+
* Converts to RGB8 space, inverts each channel
|
|
120
|
+
* (`255 - value`), and converts back to the original
|
|
121
|
+
* color space.
|
|
122
|
+
*
|
|
123
|
+
* @param c - The color to invert.
|
|
124
|
+
* @returns The inverted color in the original color space.
|
|
125
|
+
* @public
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* const inv = invert(rgb8a(255, 0, 0, 1))
|
|
129
|
+
* // result is cyan: rgb8a(0, 255, 255, 1)
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
export declare const invert: (c: Color) => Color;
|
|
133
|
+
/**
|
|
134
|
+
* Converts a color to grayscale by removing all chroma.
|
|
135
|
+
*
|
|
136
|
+
* Operates in OKLCH space by setting chroma to 0 while
|
|
137
|
+
* preserving lightness and hue. Returns the result in the
|
|
138
|
+
* same color space as the input.
|
|
139
|
+
*
|
|
140
|
+
* @param c - The color to convert to grayscale.
|
|
141
|
+
* @returns The grayscale color in the original color space.
|
|
142
|
+
* @public
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* const gray = grayscale(rgb8a(255, 0, 0, 1))
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
export declare const grayscale: (c: Color) => Color;
|
package/color-adjust.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { clamp as e } from "./number.js";
|
|
2
|
+
import { m as s, R as c, a4 as l } from "./color-SZxckS9U.js";
|
|
3
|
+
const i = (a, n) => {
|
|
4
|
+
const o = a.space, t = s(a, "oklch"), r = c(e(t.l + n, 0, 1), t.c, t.h, t.alpha);
|
|
5
|
+
return s(r, o);
|
|
6
|
+
}, u = (a, n) => {
|
|
7
|
+
const o = a.space, t = s(a, "oklch"), r = c(e(t.l - n, 0, 1), t.c, t.h, t.alpha);
|
|
8
|
+
return s(r, o);
|
|
9
|
+
}, d = (a, n) => {
|
|
10
|
+
const o = a.space, t = s(a, "oklch"), r = c(
|
|
11
|
+
t.l,
|
|
12
|
+
Math.max(0, t.c + n * 0.4),
|
|
13
|
+
t.h,
|
|
14
|
+
t.alpha
|
|
15
|
+
);
|
|
16
|
+
return s(r, o);
|
|
17
|
+
}, g = (a, n) => {
|
|
18
|
+
const o = a.space, t = s(a, "oklch"), r = c(
|
|
19
|
+
t.l,
|
|
20
|
+
Math.max(0, t.c - n * 0.4),
|
|
21
|
+
t.h,
|
|
22
|
+
t.alpha
|
|
23
|
+
);
|
|
24
|
+
return s(r, o);
|
|
25
|
+
}, k = (a, n) => ({
|
|
26
|
+
...a,
|
|
27
|
+
alpha: e(a.alpha + n, 0, 1)
|
|
28
|
+
}), m = (a, n) => ({
|
|
29
|
+
...a,
|
|
30
|
+
alpha: e(a.alpha - n, 0, 1)
|
|
31
|
+
}), j = (a) => {
|
|
32
|
+
const n = a.space, o = s(a, "rgb8"), t = l(255 - o.r, 255 - o.g, 255 - o.b, o.alpha);
|
|
33
|
+
return s(t, n);
|
|
34
|
+
}, b = (a) => {
|
|
35
|
+
const n = a.space, o = s(a, "oklch"), t = c(o.l, 0, o.h, o.alpha);
|
|
36
|
+
return s(t, n);
|
|
37
|
+
};
|
|
38
|
+
export {
|
|
39
|
+
u as darken,
|
|
40
|
+
g as desaturate,
|
|
41
|
+
b as grayscale,
|
|
42
|
+
j as invert,
|
|
43
|
+
i as lighten,
|
|
44
|
+
k as opacify,
|
|
45
|
+
d as saturate,
|
|
46
|
+
m as transparentize
|
|
47
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./number.cjs"),e=require("./color-D7FAmkht.cjs"),t=(a,l)=>a[l],h=a=>{const{space:l,...r}=a;return r},n=a=>{switch(a.space){case"rgb":return[a.r,a.g,a.b,a.alpha];case"rgb8":return[a.r,a.g,a.b,a.alpha];case"hsl":return[a.h,a.s,a.l,a.alpha];case"hsv":return[a.h,a.s,a.v,a.alpha];case"hwb":return[a.h,a.w,a.b,a.alpha];case"lab":return[a.l,a.a,a.b,a.alpha];case"lch":return[a.l,a.c,a.h,a.alpha];case"oklab":return[a.l,a.a,a.b,a.alpha];case"oklch":return[a.l,a.c,a.h,a.alpha]}},o=(a,l)=>{switch(a.space){case"rgb":{const r={...a,...l};return e.rgba(r.r,r.g,r.b,r.alpha)}case"rgb8":{const r={...a,...l};return e.rgb8a(r.r,r.g,r.b,r.alpha)}case"hsl":{const r={...a,...l};return e.hsla(r.h,r.s,r.l,r.alpha)}case"hsv":{const r={...a,...l};return e.hsva(r.h,r.s,r.v,r.alpha)}case"hwb":{const r={...a,...l};return e.hwba(r.h,r.w,r.b,r.alpha)}case"lab":{const r={...a,...l};return e.laba(r.l,r.a,r.b,r.alpha)}case"lch":{const r={...a,...l};return e.lcha(r.l,r.c,r.h,r.alpha)}case"oklab":{const r={...a,...l};return e.oklaba(r.l,r.a,r.b,r.alpha)}case"oklch":{const r={...a,...l};return e.oklcha(r.l,r.c,r.h,r.alpha)}}},p=(a,l)=>({...a,alpha:s.clamp(l,0,1)}),b=a=>a.alpha>=1,u=a=>a.alpha<=0;exports.getChannel=t;exports.getChannels=h;exports.getChannelsAsArray=n;exports.isOpaque=b;exports.isTransparent=u;exports.withAlpha=p;exports.withColor=o;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Color } from './color';
|
|
2
|
+
/**
|
|
3
|
+
* Extracts the channel names of a color type, excluding the `space`
|
|
4
|
+
* discriminant.
|
|
5
|
+
*
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export type ChannelOf<C extends Color> = Exclude<keyof C, 'space'>;
|
|
9
|
+
/**
|
|
10
|
+
* Returns the value of a single channel from a color.
|
|
11
|
+
*
|
|
12
|
+
* The `channel` parameter is type-safe — only channels that exist on the
|
|
13
|
+
* specific color type are accepted.
|
|
14
|
+
*
|
|
15
|
+
* @param c - The color to read from.
|
|
16
|
+
* @param channel - The channel name.
|
|
17
|
+
* @returns The channel value.
|
|
18
|
+
* @public
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* getChannel(rgb8a(255, 0, 0), 'r') // 255
|
|
22
|
+
* getChannel(hsla(120, 50, 75), 'h') // 120
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare const getChannel: <C extends Color>(c: C, channel: ChannelOf<C>) => number;
|
|
26
|
+
/**
|
|
27
|
+
* Returns all channels of a color as a plain object, excluding the `space`
|
|
28
|
+
* discriminant.
|
|
29
|
+
*
|
|
30
|
+
* @param c - The color to extract channels from.
|
|
31
|
+
* @returns An object mapping channel names to values.
|
|
32
|
+
* @public
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* getChannels(rgb8a(255, 0, 0))
|
|
36
|
+
* // { r: 255, g: 0, b: 0, alpha: 1 }
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare const getChannels: <C extends Color>(c: C) => Omit<C, "space">;
|
|
40
|
+
/**
|
|
41
|
+
* Returns all channel values of a color as a number array.
|
|
42
|
+
*
|
|
43
|
+
* The order is consistent per color space: color-specific channels first,
|
|
44
|
+
* then alpha. For example, RGB8 returns `[r, g, b, alpha]`, HSL returns
|
|
45
|
+
* `[h, s, l, alpha]`.
|
|
46
|
+
*
|
|
47
|
+
* @param c - The color to extract values from.
|
|
48
|
+
* @returns An array of channel values.
|
|
49
|
+
* @public
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* getChannelsAsArray(rgb8a(255, 0, 0)) // [255, 0, 0, 1]
|
|
53
|
+
* getChannelsAsArray(hsla(120, 50, 75, 0.5)) // [120, 50, 75, 0.5]
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare const getChannelsAsArray: (c: Color) => number[];
|
|
57
|
+
/**
|
|
58
|
+
* Creates a new color with one or more channels replaced, applying
|
|
59
|
+
* clamping and hue wrapping via the color's constructor.
|
|
60
|
+
*
|
|
61
|
+
* Returns the same color type as the input.
|
|
62
|
+
*
|
|
63
|
+
* @param c - The source color.
|
|
64
|
+
* @param changes - An object with the channels to change.
|
|
65
|
+
* @returns A new color with the changes applied.
|
|
66
|
+
* @public
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* withColor(rgb8a(255, 0, 0), { g: 255 })
|
|
70
|
+
* // rgb8a(255, 255, 0)
|
|
71
|
+
*
|
|
72
|
+
* withColor(hsla(0, 100, 50), { h: 120 })
|
|
73
|
+
* // hsla(120, 100, 50)
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare const withColor: <C extends Color>(c: C, changes: Partial<Omit<C, "space">>) => C;
|
|
77
|
+
/**
|
|
78
|
+
* Creates a new color with the alpha channel set to the given value.
|
|
79
|
+
*
|
|
80
|
+
* This is a shortcut for `withColor(c, { alpha })`.
|
|
81
|
+
*
|
|
82
|
+
* @param c - The source color.
|
|
83
|
+
* @param alpha - The new alpha value (0–1).
|
|
84
|
+
* @returns A new color with the updated alpha.
|
|
85
|
+
* @public
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* withAlpha(rgb8a(255, 0, 0), 0.5) // rgb8a(255, 0, 0, 0.5)
|
|
89
|
+
* withAlpha(hsla(120, 100, 50), 0) // hsla(120, 100, 50, 0)
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export declare const withAlpha: <C extends Color>(c: C, alpha: number) => C;
|
|
93
|
+
/**
|
|
94
|
+
* Returns `true` if the color is fully opaque (alpha >= 1).
|
|
95
|
+
*
|
|
96
|
+
* @param c - The color to check.
|
|
97
|
+
* @returns `true` if opaque.
|
|
98
|
+
* @public
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* isOpaque(rgb8a(255, 0, 0)) // true
|
|
102
|
+
* isOpaque(rgb8a(255, 0, 0, 0.5)) // false
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export declare const isOpaque: (c: Color) => boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Returns `true` if the color is fully transparent (alpha <= 0).
|
|
108
|
+
*
|
|
109
|
+
* @param c - The color to check.
|
|
110
|
+
* @returns `true` if transparent.
|
|
111
|
+
* @public
|
|
112
|
+
* @example
|
|
113
|
+
* ```ts
|
|
114
|
+
* isTransparent(rgb8a(255, 0, 0, 0)) // true
|
|
115
|
+
* isTransparent(rgb8a(255, 0, 0, 0.5)) // false
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
export declare const isTransparent: (c: Color) => boolean;
|
package/color-channel.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { clamp as l } from "./number.js";
|
|
2
|
+
import { R as h, O as t, L as e, I as n, w as o, s as p, o as b, a4 as u, af as m } from "./color-SZxckS9U.js";
|
|
3
|
+
const k = (a, r) => a[r], g = (a) => {
|
|
4
|
+
const { space: r, ...s } = a;
|
|
5
|
+
return s;
|
|
6
|
+
}, v = (a) => {
|
|
7
|
+
switch (a.space) {
|
|
8
|
+
case "rgb":
|
|
9
|
+
return [a.r, a.g, a.b, a.alpha];
|
|
10
|
+
case "rgb8":
|
|
11
|
+
return [a.r, a.g, a.b, a.alpha];
|
|
12
|
+
case "hsl":
|
|
13
|
+
return [a.h, a.s, a.l, a.alpha];
|
|
14
|
+
case "hsv":
|
|
15
|
+
return [a.h, a.s, a.v, a.alpha];
|
|
16
|
+
case "hwb":
|
|
17
|
+
return [a.h, a.w, a.b, a.alpha];
|
|
18
|
+
case "lab":
|
|
19
|
+
return [a.l, a.a, a.b, a.alpha];
|
|
20
|
+
case "lch":
|
|
21
|
+
return [a.l, a.c, a.h, a.alpha];
|
|
22
|
+
case "oklab":
|
|
23
|
+
return [a.l, a.a, a.b, a.alpha];
|
|
24
|
+
case "oklch":
|
|
25
|
+
return [a.l, a.c, a.h, a.alpha];
|
|
26
|
+
}
|
|
27
|
+
}, C = (a, r) => {
|
|
28
|
+
switch (a.space) {
|
|
29
|
+
case "rgb": {
|
|
30
|
+
const s = { ...a, ...r };
|
|
31
|
+
return m(s.r, s.g, s.b, s.alpha);
|
|
32
|
+
}
|
|
33
|
+
case "rgb8": {
|
|
34
|
+
const s = { ...a, ...r };
|
|
35
|
+
return u(s.r, s.g, s.b, s.alpha);
|
|
36
|
+
}
|
|
37
|
+
case "hsl": {
|
|
38
|
+
const s = { ...a, ...r };
|
|
39
|
+
return b(s.h, s.s, s.l, s.alpha);
|
|
40
|
+
}
|
|
41
|
+
case "hsv": {
|
|
42
|
+
const s = { ...a, ...r };
|
|
43
|
+
return p(s.h, s.s, s.v, s.alpha);
|
|
44
|
+
}
|
|
45
|
+
case "hwb": {
|
|
46
|
+
const s = { ...a, ...r };
|
|
47
|
+
return o(s.h, s.w, s.b, s.alpha);
|
|
48
|
+
}
|
|
49
|
+
case "lab": {
|
|
50
|
+
const s = { ...a, ...r };
|
|
51
|
+
return n(s.l, s.a, s.b, s.alpha);
|
|
52
|
+
}
|
|
53
|
+
case "lch": {
|
|
54
|
+
const s = { ...a, ...r };
|
|
55
|
+
return e(s.l, s.c, s.h, s.alpha);
|
|
56
|
+
}
|
|
57
|
+
case "oklab": {
|
|
58
|
+
const s = { ...a, ...r };
|
|
59
|
+
return t(s.l, s.a, s.b, s.alpha);
|
|
60
|
+
}
|
|
61
|
+
case "oklch": {
|
|
62
|
+
const s = { ...a, ...r };
|
|
63
|
+
return h(s.l, s.c, s.h, s.alpha);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}, f = (a, r) => ({ ...a, alpha: l(r, 0, 1) }), A = (a) => a.alpha >= 1, O = (a) => a.alpha <= 0;
|
|
67
|
+
export {
|
|
68
|
+
k as getChannel,
|
|
69
|
+
g as getChannels,
|
|
70
|
+
v as getChannelsAsArray,
|
|
71
|
+
A as isOpaque,
|
|
72
|
+
O as isTransparent,
|
|
73
|
+
f as withAlpha,
|
|
74
|
+
C as withColor
|
|
75
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./color-D7FAmkht.cjs"),a=t=>t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4),l=t=>{const o=e.convertColor(t,"rgb8"),n=a(o.r/255),r=a(o.g/255),s=a(o.b/255);return .2126*n+.7152*r+.0722*s},c=(t,o)=>{const n=l(t),r=l(o),s=Math.max(n,r),g=Math.min(n,r);return(s+.05)/(g+.05)},i=(t,o=e.rgb8a(0,0,0),n=e.rgb8a(255,255,255))=>{const r=c(t,o),s=c(t,n);return r>=s?o:n},b={AA:4.5,AAA:7,"AA-large":3,"AAA-large":4.5},A=(t,o,n)=>c(t,o)>=b[n];exports.contrastColor=i;exports.contrastRatio=c;exports.luminance=l;exports.meetsContrast=A;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Color } from './color';
|
|
2
|
+
/**
|
|
3
|
+
* WCAG contrast level thresholds.
|
|
4
|
+
*
|
|
5
|
+
* - `'AA'` — 4.5:1 for normal text
|
|
6
|
+
* - `'AAA'` — 7:1 for normal text
|
|
7
|
+
* - `'AA-large'` — 3:1 for large text
|
|
8
|
+
* - `'AAA-large'` — 4.5:1 for large text
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export type ContrastLevel = 'AA' | 'AAA' | 'AA-large' | 'AAA-large';
|
|
13
|
+
/**
|
|
14
|
+
* Computes the WCAG relative luminance of a color.
|
|
15
|
+
*
|
|
16
|
+
* Converts the color to sRGB, linearizes each channel,
|
|
17
|
+
* and returns the weighted sum per the WCAG 2.x formula.
|
|
18
|
+
*
|
|
19
|
+
* @param c - The color to measure
|
|
20
|
+
* @returns A number between 0 (darkest) and 1 (lightest)
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* luminance(rgb8a(255, 255, 255)) // 1
|
|
25
|
+
* luminance(rgb8a(0, 0, 0)) // 0
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export declare const luminance: (c: Color) => number;
|
|
31
|
+
/**
|
|
32
|
+
* Computes the WCAG contrast ratio between two colors.
|
|
33
|
+
*
|
|
34
|
+
* The ratio ranges from 1:1 (identical) to 21:1
|
|
35
|
+
* (black vs white).
|
|
36
|
+
*
|
|
37
|
+
* @param a - The first color
|
|
38
|
+
* @param b - The second color
|
|
39
|
+
* @returns A number between 1 and 21
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* contrastRatio(
|
|
44
|
+
* rgb8a(0, 0, 0),
|
|
45
|
+
* rgb8a(255, 255, 255)
|
|
46
|
+
* ) // 21
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
export declare const contrastRatio: (a: Color, b: Color) => number;
|
|
52
|
+
/**
|
|
53
|
+
* Picks whichever of two candidates has better contrast
|
|
54
|
+
* against a reference color.
|
|
55
|
+
*
|
|
56
|
+
* Useful for choosing a readable foreground color for
|
|
57
|
+
* a given background.
|
|
58
|
+
*
|
|
59
|
+
* @param c - The reference color (e.g. a background)
|
|
60
|
+
* @param dark - The dark candidate (defaults to black)
|
|
61
|
+
* @param light - The light candidate (defaults to white)
|
|
62
|
+
* @returns The candidate with the higher contrast ratio
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* // Returns white for a dark background
|
|
67
|
+
* contrastColor(rgb8a(30, 30, 30))
|
|
68
|
+
*
|
|
69
|
+
* // Returns black for a light background
|
|
70
|
+
* contrastColor(rgb8a(220, 220, 220))
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* @public
|
|
74
|
+
*/
|
|
75
|
+
export declare const contrastColor: (c: Color, dark?: Color, light?: Color) => Color;
|
|
76
|
+
/**
|
|
77
|
+
* Checks whether two colors meet a WCAG contrast level.
|
|
78
|
+
*
|
|
79
|
+
* @param a - The first color
|
|
80
|
+
* @param b - The second color
|
|
81
|
+
* @param level - The WCAG level to test against
|
|
82
|
+
* @returns `true` if the contrast ratio meets or exceeds
|
|
83
|
+
* the threshold for the given level
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* meetsContrast(
|
|
88
|
+
* rgb8a(0, 0, 0),
|
|
89
|
+
* rgb8a(255, 255, 255),
|
|
90
|
+
* 'AAA'
|
|
91
|
+
* ) // true
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @public
|
|
95
|
+
*/
|
|
96
|
+
export declare const meetsContrast: (a: Color, b: Color, level: ContrastLevel) => boolean;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { a4 as e, m as g } from "./color-SZxckS9U.js";
|
|
2
|
+
const a = (t) => t <= 0.04045 ? t / 12.92 : Math.pow((t + 0.055) / 1.055, 2.4), l = (t) => {
|
|
3
|
+
const o = g(t, "rgb8"), n = a(o.r / 255), r = a(o.g / 255), s = a(o.b / 255);
|
|
4
|
+
return 0.2126 * n + 0.7152 * r + 0.0722 * s;
|
|
5
|
+
}, c = (t, o) => {
|
|
6
|
+
const n = l(t), r = l(o), s = Math.max(n, r), A = Math.min(n, r);
|
|
7
|
+
return (s + 0.05) / (A + 0.05);
|
|
8
|
+
}, m = (t, o = e(0, 0, 0), n = e(255, 255, 255)) => {
|
|
9
|
+
const r = c(t, o), s = c(t, n);
|
|
10
|
+
return r >= s ? o : n;
|
|
11
|
+
}, b = {
|
|
12
|
+
AA: 4.5,
|
|
13
|
+
AAA: 7,
|
|
14
|
+
"AA-large": 3,
|
|
15
|
+
"AAA-large": 4.5
|
|
16
|
+
}, h = (t, o, n) => c(t, o) >= b[n];
|
|
17
|
+
export {
|
|
18
|
+
m as contrastColor,
|
|
19
|
+
c as contrastRatio,
|
|
20
|
+
l as luminance,
|
|
21
|
+
h as meetsContrast
|
|
22
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("./color-D7FAmkht.cjs"),r=l=>l*Math.PI/180,F=(l,q)=>{const n=d.convertColor(l,"lab"),c=d.convertColor(q,"lab"),h=n.l-c.l,e=n.a-c.a,a=n.b-c.b;return Math.sqrt(h*h+e*e+a*a)},J=(l,q)=>{const n=d.convertColor(l,"lab"),c=d.convertColor(q,"lab"),h=n.l,e=n.a,a=n.b,v=c.l,m=c.a,M=c.b,T=Math.sqrt(e*e+a*a),H=Math.sqrt(m*m+M*M),I=(T+H)/2,g=Math.pow(I,7),w=.5*(1-Math.sqrt(g/(g+Math.pow(25,7)))),f=e*(1+w),L=m*(1+w),i=Math.sqrt(f*f+a*a),p=Math.sqrt(L*L+M*M);let t=Math.atan2(a,f)*180/Math.PI;t<0&&(t+=360);let o=Math.atan2(M,L)*180/Math.PI;o<0&&(o+=360);const R=v-h,y=p-i;let b;i*p===0?b=0:Math.abs(o-t)<=180?b=o-t:o-t>180?b=o-t-360:b=o-t+360;const j=2*Math.sqrt(i*p)*Math.sin(r(b/2)),x=(h+v)/2,_=(i+p)/2;let s;i*p===0?s=t+o:Math.abs(t-o)<=180?s=(t+o)/2:t+o<360?s=(t+o+360)/2:s=(t+o-360)/2;const G=1-.17*Math.cos(r(s-30))+.24*Math.cos(r(2*s))+.32*Math.cos(r(3*s+6))-.2*Math.cos(r(4*s-63)),C=x-50,O=1+.015*C*C/Math.sqrt(20+C*C),k=1+.045*_,z=1+.015*_*G,A=30*Math.exp(-((s-275)/25*((s-275)/25))),D=Math.pow(_,7),B=2*Math.sqrt(D/(D+Math.pow(25,7))),E=-Math.sin(r(2*A))*B,P=R/O,S=y/k,u=j/z;return Math.sqrt(P*P+S*S+u*u+E*S*u)};exports.colorDistance=J;exports.colorDistanceSimple=F;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Color } from './color';
|
|
2
|
+
/**
|
|
3
|
+
* Computes the CIE76 color distance (Euclidean distance in
|
|
4
|
+
* CIELAB space) between two colors.
|
|
5
|
+
*
|
|
6
|
+
* @param a - The first color.
|
|
7
|
+
* @param b - The second color.
|
|
8
|
+
* @returns The Euclidean distance in LAB space.
|
|
9
|
+
* @public
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { rgb8a } from './color'
|
|
13
|
+
* colorDistanceSimple(
|
|
14
|
+
* rgb8a(255, 0, 0),
|
|
15
|
+
* rgb8a(0, 255, 0)
|
|
16
|
+
* ) // ~170.56
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare const colorDistanceSimple: (a: Color, b: Color) => number;
|
|
20
|
+
/**
|
|
21
|
+
* Computes the CIEDE2000 color distance between two colors.
|
|
22
|
+
*
|
|
23
|
+
* This is the most perceptually uniform color difference metric
|
|
24
|
+
* standardized by the CIE. It accounts for lightness, chroma,
|
|
25
|
+
* and hue weighting as well as interactive effects between
|
|
26
|
+
* chroma and hue differences.
|
|
27
|
+
*
|
|
28
|
+
* @param a - The first color.
|
|
29
|
+
* @param b - The second color.
|
|
30
|
+
* @returns The CIEDE2000 deltaE value.
|
|
31
|
+
* @public
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { rgb8a } from './color'
|
|
35
|
+
* colorDistance(
|
|
36
|
+
* rgb8a(255, 0, 0),
|
|
37
|
+
* rgb8a(0, 255, 0)
|
|
38
|
+
* ) // ~86.61
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare const colorDistance: (a: Color, b: Color) => number;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { m } from "./color-SZxckS9U.js";
|
|
2
|
+
const h = (M) => M * Math.PI / 180, K = (M, d) => {
|
|
3
|
+
const n = m(M, "lab"), c = m(d, "lab"), l = n.l - c.l, e = n.a - c.a, o = n.b - c.b;
|
|
4
|
+
return Math.sqrt(l * l + e * e + o * o);
|
|
5
|
+
}, N = (M, d) => {
|
|
6
|
+
const n = m(M, "lab"), c = m(d, "lab"), l = n.l, e = n.a, o = n.b, H = c.l, q = c.a, r = c.b, x = Math.sqrt(e * e + o * o), D = Math.sqrt(q * q + r * r), R = (x + D) / 2, I = Math.pow(R, 7), P = 0.5 * (1 - Math.sqrt(I / (I + Math.pow(25, 7)))), f = e * (1 + P), L = q * (1 + P), p = Math.sqrt(f * f + o * o), b = Math.sqrt(L * L + r * r);
|
|
7
|
+
let t = Math.atan2(o, f) * 180 / Math.PI;
|
|
8
|
+
t < 0 && (t += 360);
|
|
9
|
+
let s = Math.atan2(r, L) * 180 / Math.PI;
|
|
10
|
+
s < 0 && (s += 360);
|
|
11
|
+
const g = H - l, v = b - p;
|
|
12
|
+
let i;
|
|
13
|
+
p * b === 0 ? i = 0 : Math.abs(s - t) <= 180 ? i = s - t : s - t > 180 ? i = s - t - 360 : i = s - t + 360;
|
|
14
|
+
const G = 2 * Math.sqrt(p * b) * Math.sin(h(i / 2)), j = (l + H) / 2, _ = (p + b) / 2;
|
|
15
|
+
let a;
|
|
16
|
+
p * b === 0 ? a = t + s : Math.abs(t - s) <= 180 ? a = (t + s) / 2 : t + s < 360 ? a = (t + s + 360) / 2 : a = (t + s - 360) / 2;
|
|
17
|
+
const k = 1 - 0.17 * Math.cos(h(a - 30)) + 0.24 * Math.cos(h(2 * a)) + 0.32 * Math.cos(h(3 * a + 6)) - 0.2 * Math.cos(h(4 * a - 63)), C = j - 50, y = 1 + 0.015 * C * C / Math.sqrt(20 + C * C), z = 1 + 0.045 * _, A = 1 + 0.015 * _ * k, B = 30 * Math.exp(-((a - 275) / 25 * ((a - 275) / 25))), T = Math.pow(_, 7), E = 2 * Math.sqrt(T / (T + Math.pow(25, 7))), F = -Math.sin(h(2 * B)) * E, u = g / y, w = v / z, S = G / A;
|
|
18
|
+
return Math.sqrt(
|
|
19
|
+
u * u + w * w + S * S + F * w * S
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
N as colorDistance,
|
|
24
|
+
K as colorDistanceSimple
|
|
25
|
+
};
|
package/color-gamut.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("./color-D7FAmkht.cjs"),e=o=>o<=.0031308?o*12.92:1.055*Math.pow(o,1/2.4)-.055,i=(o,t,n)=>[3.2404542*o-1.5371385*t-.4985314*n,-.969266*o+1.8760108*t+.041556*n,.0556434*o-.2040259*t+1.0572252*n],k=.95047,d=1,f=1.08883,T=6/29,M=3*T**2,p=(o,t,n)=>{const r=c=>c>T?c**3:M*(c-.13793103448275862),l=(o+16)/116,s=t/500+l,a=l-n/200;return[k*r(s),d*r(l),f*r(a)]},m=(o,t,n)=>{const r=o+.3963377774*t+.2158037573*n,l=o-.1055613458*t-.0638541728*n,s=o-.0894841775*t-1.291485548*n,a=r*r*r,c=l*l*l,h=s*s*s;return[4.0767416621*a-3.3077115913*c+.2309699292*h,-1.2684380046*a+2.6097574011*c-.3413193965*h,-.0041960863*a-.7034186147*c+1.707614701*h]},_=(o,t,n)=>{const r=n*Math.PI/180;return[o,t*Math.cos(r),t*Math.sin(r)]},G=(o,t,n)=>{const r=n*Math.PI/180;return[o,t*Math.cos(r),t*Math.sin(r)]},S=o=>{switch(o.space){case"rgb":return[o.r,o.g,o.b,o.alpha];case"rgb8":return[o.r/255,o.g/255,o.b/255,o.alpha];case"oklab":{const[t,n,r]=m(o.l,o.a,o.b);return[e(t),e(n),e(r),o.alpha]}case"oklch":{const[t,n,r]=_(o.l,o.c,o.h),[l,s,a]=m(t,n,r);return[e(l),e(s),e(a),o.alpha]}case"lab":{const[t,n,r]=p(o.l,o.a,o.b),[l,s,a]=i(t,n,r);return[e(l),e(s),e(a),o.alpha]}case"lch":{const[t,n,r]=G(o.l,o.c,o.h),[l,s,a]=p(t,n,r),[c,h,g]=i(l,s,a);return[e(c),e(h),e(g),o.alpha]}default:{const t=b.convertColor(o,"rgb8");return[t.r/255,t.g/255,t.b/255,t.alpha]}}},u=(o,t=.002)=>{const[n,r,l]=S(o);return n>=-t&&n<=1+t&&r>=-t&&r<=1+t&&l>=-t&&l<=1+t},v=o=>{if(u(o))return o;const t=o.space,n=b.convertColor(o,"rgb8"),r=b.rgb8a(n.r,n.g,n.b,n.alpha);return b.convertColor(r,t)},y=o=>{if(u(o))return o;const t=o.space,n=b.convertColor(o,"oklch");let r=0,l=n.c;const s=1e-4;for(let c=0;c<50&&l-r>s;c++){const h=(r+l)/2,g=b.oklcha(n.l,h,n.h,n.alpha);u(g)?r=h:l=h}const a=b.oklcha(n.l,r,n.h,n.alpha);return b.convertColor(a,t)};exports.clampToGamut=v;exports.clampToGamutOklch=y;exports.isInGamut=u;
|
package/color-gamut.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Color } from './color';
|
|
2
|
+
/**
|
|
3
|
+
* Tests whether a color is within the sRGB gamut.
|
|
4
|
+
*
|
|
5
|
+
* Colors in HSL, HSV, HWB, RGB, and RGB8 spaces are always in gamut by
|
|
6
|
+
* definition. Colors in LAB, LCH, OKLAB, and OKLCH may fall outside sRGB
|
|
7
|
+
* if their chroma is too high.
|
|
8
|
+
*
|
|
9
|
+
* @param c - The color to test.
|
|
10
|
+
* @param tolerance - How far outside 0–1 is still considered in-gamut.
|
|
11
|
+
* Defaults to 0.002 to account for floating-point imprecision.
|
|
12
|
+
* @returns `true` if the color is representable in sRGB.
|
|
13
|
+
* @public
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* isInGamut(rgb8a(255, 0, 0)) // true
|
|
17
|
+
* isInGamut(oklcha(0.5, 0.4, 150)) // likely false (very high chroma)
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare const isInGamut: (c: Color, tolerance?: number) => boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Clamps a color to the sRGB gamut by clamping RGB channel values.
|
|
23
|
+
*
|
|
24
|
+
* If the color is already in gamut, it is returned unchanged. Otherwise,
|
|
25
|
+
* it is converted to RGB8 (which clamps channels to 0–255) and converted
|
|
26
|
+
* back to the original color space.
|
|
27
|
+
*
|
|
28
|
+
* For perceptually better results on wide-gamut colors, use
|
|
29
|
+
* {@link clampToGamutOklch} which preserves lightness and hue.
|
|
30
|
+
*
|
|
31
|
+
* @param c - The color to clamp.
|
|
32
|
+
* @returns A color within the sRGB gamut in the original color space.
|
|
33
|
+
* @public
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* clampToGamut(rgb8a(255, 0, 0)) // unchanged
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare const clampToGamut: (c: Color) => Color;
|
|
40
|
+
/**
|
|
41
|
+
* Clamps a color to the sRGB gamut by reducing chroma in OKLCH space
|
|
42
|
+
* while preserving lightness and hue.
|
|
43
|
+
*
|
|
44
|
+
* This produces more perceptually pleasing results than simple RGB
|
|
45
|
+
* clamping, as it finds the most saturated version of the color that
|
|
46
|
+
* still fits within sRGB.
|
|
47
|
+
*
|
|
48
|
+
* Uses binary search to find the maximum in-gamut chroma.
|
|
49
|
+
*
|
|
50
|
+
* @param c - The color to clamp.
|
|
51
|
+
* @returns A color within the sRGB gamut in the original color space.
|
|
52
|
+
* @public
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* clampToGamutOklch(oklcha(0.5, 0.4, 150))
|
|
56
|
+
* // Same lightness and hue, reduced chroma to fit sRGB
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare const clampToGamutOklch: (c: Color) => Color;
|