@a_ng_d/utils-ui-color-palette 1.0.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/LICENSE +21 -0
- package/README.md +158 -0
- package/dist/color-BND6T00o.js +485 -0
- package/dist/color-BND6T00o.js.map +1 -0
- package/dist/index-Beb8qoyd.js +1403 -0
- package/dist/index-Beb8qoyd.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/color/color.d.ts +46 -0
- package/dist/modules/color/color.d.ts.map +1 -0
- package/dist/modules/color/color.js +6 -0
- package/dist/modules/color/color.js.map +1 -0
- package/dist/modules/contrast/contrast.d.ts +20 -0
- package/dist/modules/contrast/contrast.d.ts.map +1 -0
- package/dist/modules/contrast/contrast.js +203 -0
- package/dist/modules/contrast/contrast.js.map +1 -0
- package/dist/modules/data/data.d.ts +19 -0
- package/dist/modules/data/data.d.ts.map +1 -0
- package/dist/modules/data/data.js +263 -0
- package/dist/modules/data/data.js.map +1 -0
- package/dist/types/color.types.d.ts +16 -0
- package/dist/types/color.types.d.ts.map +1 -0
- package/dist/types/configuration.types.d.ts +152 -0
- package/dist/types/configuration.types.d.ts.map +1 -0
- package/dist/types/data.types.d.ts +77 -0
- package/dist/types/data.types.d.ts.map +1 -0
- package/dist/types/model.types.d.ts +7 -0
- package/dist/types/model.types.d.ts.map +1 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Aurélien Grimaud
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
  
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
# UI Color Palette Utils
|
|
5
|
+
|
|
6
|
+
Core utilities library for UI Color Palette - a color management plugin for design tools. This library provides the foundational color manipulation, contrast calculation, and palette generation features used in the plugin.
|
|
7
|
+
|
|
8
|
+
## Design Tools Compatibility
|
|
9
|
+
|
|
10
|
+
UI Color Palette is available for:
|
|
11
|
+
- Figma - Create and manage color primivites directly in your Figma designs
|
|
12
|
+
- FigJam - Collaborate on color decisions with your team
|
|
13
|
+
- Penpot - Open-source design tool alternative with full color management support
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- **Color Contrast Tools**:
|
|
18
|
+
- APCA contrast calculations
|
|
19
|
+
- WCAG 2.1 compliance checking
|
|
20
|
+
- Contrast ratio calculations between colors
|
|
21
|
+
|
|
22
|
+
- **Color Manipulation**:
|
|
23
|
+
- Color space conversions (RGB, HSL, HSLuv, LAB)
|
|
24
|
+
- Color mixing and blending
|
|
25
|
+
- Brightness and saturation adjustments
|
|
26
|
+
|
|
27
|
+
- **Palette Generation**:
|
|
28
|
+
- Create harmonious color schemes
|
|
29
|
+
- Generate accessible color combinations
|
|
30
|
+
- Scale generation for design systems
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install @a_ng_d/utils-ui-color-palette
|
|
36
|
+
# or
|
|
37
|
+
yarn add @a_ng_d/utils-ui-color-palette
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { calculateContrast, generatePalette } from '@a_ng_d/utils-ui-color-palette';
|
|
44
|
+
|
|
45
|
+
// Calculate contrast between two colors
|
|
46
|
+
const contrast = calculateContrast('#000000', '#FFFFFF');
|
|
47
|
+
|
|
48
|
+
// Generate a color palette
|
|
49
|
+
const palette = generatePalette('#FF0000', { steps: 10 });
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Examples
|
|
53
|
+
|
|
54
|
+
### Contrast Calculations
|
|
55
|
+
```typescript
|
|
56
|
+
import { Contrast } from '@a_ng_d/utils-ui-color-palette';
|
|
57
|
+
|
|
58
|
+
// Create a contrast checker instance
|
|
59
|
+
const contrast = new Contrast({
|
|
60
|
+
backgroundColor: [255, 255, 255], // White background
|
|
61
|
+
textColor: '#000000' // Black text
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Get WCAG contrast ratio
|
|
65
|
+
const wcagScore = contrast.getWCAGScore(); // Returns: 'AAA'
|
|
66
|
+
|
|
67
|
+
// Get APCA contrast value
|
|
68
|
+
const apcaScore = contrast.getAPCAContrast(); // Returns: ~106
|
|
69
|
+
|
|
70
|
+
// Get recommended usage
|
|
71
|
+
const usage = contrast.getRecommendedUsage(); // Returns: 'FLUENT_TEXT'
|
|
72
|
+
|
|
73
|
+
// Get minimum font sizes
|
|
74
|
+
const sizes = contrast.getMinFontSizes(); // Returns recommended font sizes
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Color Space Conversions
|
|
78
|
+
```typescript
|
|
79
|
+
import { Color } from '@a_ng_d/utils-ui-color-palette';
|
|
80
|
+
|
|
81
|
+
// Create a color instance
|
|
82
|
+
const color = new Color({
|
|
83
|
+
sourceColor: [255, 0, 0], // Red in RGB
|
|
84
|
+
lightness: 50,
|
|
85
|
+
chromaShifting: 100,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Convert to different color spaces
|
|
89
|
+
const lchColor = color.lch();
|
|
90
|
+
const oklchColor = color.oklch();
|
|
91
|
+
const hsluvColor = color.hsluv();
|
|
92
|
+
|
|
93
|
+
// Handle color blindness simulation
|
|
94
|
+
const protanopiaColor = new Color({
|
|
95
|
+
sourceColor: [255, 0, 0],
|
|
96
|
+
visionSimulationMode: 'PROTANOPIA'
|
|
97
|
+
}).setColor();
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Color Mixing
|
|
101
|
+
```typescript
|
|
102
|
+
import { Color } from '@a_ng_d/utils-ui-color-palette';
|
|
103
|
+
|
|
104
|
+
const color = new Color({});
|
|
105
|
+
|
|
106
|
+
// Mix RGB colors with alpha
|
|
107
|
+
const mixed = color.mixColorsRgb(
|
|
108
|
+
[255, 0, 0, 0.5], // Semi-transparent red
|
|
109
|
+
[0, 0, 255, 1] // Solid blue
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
// Mix hex colors
|
|
113
|
+
const mixedHex = color.mixColorsHex('#FF0000', '#0000FF');
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Testing
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npm test
|
|
120
|
+
# or
|
|
121
|
+
yarn test
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Code Coverage
|
|
125
|
+
|
|
126
|
+
Current test coverage results:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
File | % Stmts | % Branch | % Funcs | % Lines
|
|
130
|
+
--------------|---------|----------|---------|--------
|
|
131
|
+
All files | 76.09 | 62.63 | 75.86 | 76.09
|
|
132
|
+
color.ts | 72.06 | 68.05 | 66.66 | 72.06
|
|
133
|
+
contrast.ts | 81.51 | 65.51 | 100 | 81.51
|
|
134
|
+
data.ts | 80.14 | 57.3 | 100 | 80.14
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
To run coverage tests:
|
|
138
|
+
```bash
|
|
139
|
+
npm run test:coverage
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Credits
|
|
143
|
+
|
|
144
|
+
This project relies on several excellent open source packages:
|
|
145
|
+
|
|
146
|
+
### Color Processing
|
|
147
|
+
- [chroma.js](https://gka.github.io/chroma.js/) - A powerful library for color manipulations and conversions
|
|
148
|
+
- Author: Gregor Aisch
|
|
149
|
+
- License: BSD-3-Clause
|
|
150
|
+
|
|
151
|
+
### Contrast Calculation
|
|
152
|
+
- [APCA-W3](https://github.com/Myndex/SAPC-APCA) - Advanced Perceptual Contrast Algorithm
|
|
153
|
+
- Author: Andrew Somers
|
|
154
|
+
- License: W3C Software and Document Notice and License
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more information.
|
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
var f = Object.defineProperty;
|
|
2
|
+
var T = (b, t, h) => t in b ? f(b, t, { enumerable: !0, configurable: !0, writable: !0, value: h }) : b[t] = h;
|
|
3
|
+
var l = (b, t, h) => T(b, typeof t != "symbol" ? t + "" : t, h);
|
|
4
|
+
import { c as n } from "./index-Beb8qoyd.js";
|
|
5
|
+
class s {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.hex = "#000000", this.rgb_r = 0, this.rgb_g = 0, this.rgb_b = 0, this.xyz_x = 0, this.xyz_y = 0, this.xyz_z = 0, this.luv_l = 0, this.luv_u = 0, this.luv_v = 0, this.lch_l = 0, this.lch_c = 0, this.lch_h = 0, this.hsluv_h = 0, this.hsluv_s = 0, this.hsluv_l = 0, this.hpluv_h = 0, this.hpluv_p = 0, this.hpluv_l = 0, this.r0s = 0, this.r0i = 0, this.r1s = 0, this.r1i = 0, this.g0s = 0, this.g0i = 0, this.g1s = 0, this.g1i = 0, this.b0s = 0, this.b0i = 0, this.b1s = 0, this.b1i = 0;
|
|
8
|
+
}
|
|
9
|
+
static fromLinear(t) {
|
|
10
|
+
return t <= 31308e-7 ? 12.92 * t : 1.055 * Math.pow(t, 1 / 2.4) - 0.055;
|
|
11
|
+
}
|
|
12
|
+
static toLinear(t) {
|
|
13
|
+
return t > 0.04045 ? Math.pow((t + 0.055) / 1.055, 2.4) : t / 12.92;
|
|
14
|
+
}
|
|
15
|
+
static yToL(t) {
|
|
16
|
+
return t <= s.epsilon ? t / s.refY * s.kappa : 116 * Math.pow(t / s.refY, 1 / 3) - 16;
|
|
17
|
+
}
|
|
18
|
+
static lToY(t) {
|
|
19
|
+
return t <= 8 ? s.refY * t / s.kappa : s.refY * Math.pow((t + 16) / 116, 3);
|
|
20
|
+
}
|
|
21
|
+
static rgbChannelToHex(t) {
|
|
22
|
+
const h = Math.round(t * 255), r = h % 16, o = (h - r) / 16 | 0;
|
|
23
|
+
return s.hexChars.charAt(o) + s.hexChars.charAt(r);
|
|
24
|
+
}
|
|
25
|
+
static hexToRgbChannel(t, h) {
|
|
26
|
+
const r = s.hexChars.indexOf(t.charAt(h)), o = s.hexChars.indexOf(t.charAt(h + 1));
|
|
27
|
+
return (r * 16 + o) / 255;
|
|
28
|
+
}
|
|
29
|
+
static distanceFromOriginAngle(t, h, r) {
|
|
30
|
+
const o = h / (Math.sin(r) - t * Math.cos(r));
|
|
31
|
+
return o < 0 ? 1 / 0 : o;
|
|
32
|
+
}
|
|
33
|
+
static distanceFromOrigin(t, h) {
|
|
34
|
+
return Math.abs(h) / Math.sqrt(Math.pow(t, 2) + 1);
|
|
35
|
+
}
|
|
36
|
+
static min6(t, h, r, o, i, e) {
|
|
37
|
+
return Math.min(t, Math.min(h, Math.min(r, Math.min(o, Math.min(i, e)))));
|
|
38
|
+
}
|
|
39
|
+
rgbToHex() {
|
|
40
|
+
this.hex = "#", this.hex += s.rgbChannelToHex(this.rgb_r), this.hex += s.rgbChannelToHex(this.rgb_g), this.hex += s.rgbChannelToHex(this.rgb_b);
|
|
41
|
+
}
|
|
42
|
+
hexToRgb() {
|
|
43
|
+
this.hex = this.hex.toLowerCase(), this.rgb_r = s.hexToRgbChannel(this.hex, 1), this.rgb_g = s.hexToRgbChannel(this.hex, 3), this.rgb_b = s.hexToRgbChannel(this.hex, 5);
|
|
44
|
+
}
|
|
45
|
+
xyzToRgb() {
|
|
46
|
+
this.rgb_r = s.fromLinear(s.m_r0 * this.xyz_x + s.m_r1 * this.xyz_y + s.m_r2 * this.xyz_z), this.rgb_g = s.fromLinear(s.m_g0 * this.xyz_x + s.m_g1 * this.xyz_y + s.m_g2 * this.xyz_z), this.rgb_b = s.fromLinear(s.m_b0 * this.xyz_x + s.m_b1 * this.xyz_y + s.m_b2 * this.xyz_z);
|
|
47
|
+
}
|
|
48
|
+
rgbToXyz() {
|
|
49
|
+
const t = s.toLinear(this.rgb_r), h = s.toLinear(this.rgb_g), r = s.toLinear(this.rgb_b);
|
|
50
|
+
this.xyz_x = 0.41239079926595 * t + 0.35758433938387 * h + 0.18048078840183 * r, this.xyz_y = 0.21263900587151 * t + 0.71516867876775 * h + 0.072192315360733 * r, this.xyz_z = 0.019330818715591 * t + 0.11919477979462 * h + 0.95053215224966 * r;
|
|
51
|
+
}
|
|
52
|
+
xyzToLuv() {
|
|
53
|
+
const t = this.xyz_x + 15 * this.xyz_y + 3 * this.xyz_z;
|
|
54
|
+
let h = 4 * this.xyz_x, r = 9 * this.xyz_y;
|
|
55
|
+
t !== 0 ? (h /= t, r /= t) : (h = NaN, r = NaN), this.luv_l = s.yToL(this.xyz_y), this.luv_l === 0 ? (this.luv_u = 0, this.luv_v = 0) : (this.luv_u = 13 * this.luv_l * (h - s.refU), this.luv_v = 13 * this.luv_l * (r - s.refV));
|
|
56
|
+
}
|
|
57
|
+
luvToXyz() {
|
|
58
|
+
if (this.luv_l === 0) {
|
|
59
|
+
this.xyz_x = 0, this.xyz_y = 0, this.xyz_z = 0;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const t = this.luv_u / (13 * this.luv_l) + s.refU, h = this.luv_v / (13 * this.luv_l) + s.refV;
|
|
63
|
+
this.xyz_y = s.lToY(this.luv_l), this.xyz_x = 0 - 9 * this.xyz_y * t / ((t - 4) * h - t * h), this.xyz_z = (9 * this.xyz_y - 15 * h * this.xyz_y - h * this.xyz_x) / (3 * h);
|
|
64
|
+
}
|
|
65
|
+
luvToLch() {
|
|
66
|
+
if (this.lch_l = this.luv_l, this.lch_c = Math.sqrt(this.luv_u * this.luv_u + this.luv_v * this.luv_v), this.lch_c < 1e-8)
|
|
67
|
+
this.lch_h = 0;
|
|
68
|
+
else {
|
|
69
|
+
const t = Math.atan2(this.luv_v, this.luv_u);
|
|
70
|
+
this.lch_h = t * 180 / Math.PI, this.lch_h < 0 && (this.lch_h = 360 + this.lch_h);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
lchToLuv() {
|
|
74
|
+
const t = this.lch_h / 180 * Math.PI;
|
|
75
|
+
this.luv_l = this.lch_l, this.luv_u = Math.cos(t) * this.lch_c, this.luv_v = Math.sin(t) * this.lch_c;
|
|
76
|
+
}
|
|
77
|
+
calculateBoundingLines(t) {
|
|
78
|
+
const h = Math.pow(t + 16, 3) / 1560896, r = h > s.epsilon ? h : t / s.kappa, o = r * (284517 * s.m_r0 - 94839 * s.m_r2), i = r * (838422 * s.m_r2 + 769860 * s.m_r1 + 731718 * s.m_r0), e = r * (632260 * s.m_r2 - 126452 * s.m_r1), a = r * (284517 * s.m_g0 - 94839 * s.m_g2), g = r * (838422 * s.m_g2 + 769860 * s.m_g1 + 731718 * s.m_g0), m = r * (632260 * s.m_g2 - 126452 * s.m_g1), _ = r * (284517 * s.m_b0 - 94839 * s.m_b2), M = r * (838422 * s.m_b2 + 769860 * s.m_b1 + 731718 * s.m_b0), C = r * (632260 * s.m_b2 - 126452 * s.m_b1);
|
|
79
|
+
this.r0s = o / e, this.r0i = i * t / e, this.r1s = o / (e + 126452), this.r1i = (i - 769860) * t / (e + 126452), this.g0s = a / m, this.g0i = g * t / m, this.g1s = a / (m + 126452), this.g1i = (g - 769860) * t / (m + 126452), this.b0s = _ / C, this.b0i = M * t / C, this.b1s = _ / (C + 126452), this.b1i = (M - 769860) * t / (C + 126452);
|
|
80
|
+
}
|
|
81
|
+
calcMaxChromaHpluv() {
|
|
82
|
+
const t = s.distanceFromOrigin(this.r0s, this.r0i), h = s.distanceFromOrigin(this.r1s, this.r1i), r = s.distanceFromOrigin(this.g0s, this.g0i), o = s.distanceFromOrigin(this.g1s, this.g1i), i = s.distanceFromOrigin(this.b0s, this.b0i), e = s.distanceFromOrigin(this.b1s, this.b1i);
|
|
83
|
+
return s.min6(t, h, r, o, i, e);
|
|
84
|
+
}
|
|
85
|
+
calcMaxChromaHsluv(t) {
|
|
86
|
+
const h = t / 360 * Math.PI * 2, r = s.distanceFromOriginAngle(this.r0s, this.r0i, h), o = s.distanceFromOriginAngle(this.r1s, this.r1i, h), i = s.distanceFromOriginAngle(this.g0s, this.g0i, h), e = s.distanceFromOriginAngle(this.g1s, this.g1i, h), a = s.distanceFromOriginAngle(this.b0s, this.b0i, h), g = s.distanceFromOriginAngle(this.b1s, this.b1i, h);
|
|
87
|
+
return s.min6(r, o, i, e, a, g);
|
|
88
|
+
}
|
|
89
|
+
hsluvToLch() {
|
|
90
|
+
if (this.hsluv_l > 99.9999999)
|
|
91
|
+
this.lch_l = 100, this.lch_c = 0;
|
|
92
|
+
else if (this.hsluv_l < 1e-8)
|
|
93
|
+
this.lch_l = 0, this.lch_c = 0;
|
|
94
|
+
else {
|
|
95
|
+
this.lch_l = this.hsluv_l, this.calculateBoundingLines(this.hsluv_l);
|
|
96
|
+
const t = this.calcMaxChromaHsluv(this.hsluv_h);
|
|
97
|
+
this.lch_c = t / 100 * this.hsluv_s;
|
|
98
|
+
}
|
|
99
|
+
this.lch_h = this.hsluv_h;
|
|
100
|
+
}
|
|
101
|
+
lchToHsluv() {
|
|
102
|
+
if (this.lch_l > 99.9999999)
|
|
103
|
+
this.hsluv_s = 0, this.hsluv_l = 100;
|
|
104
|
+
else if (this.lch_l < 1e-8)
|
|
105
|
+
this.hsluv_s = 0, this.hsluv_l = 0;
|
|
106
|
+
else {
|
|
107
|
+
this.calculateBoundingLines(this.lch_l);
|
|
108
|
+
const t = this.calcMaxChromaHsluv(this.lch_h);
|
|
109
|
+
this.hsluv_s = this.lch_c / t * 100, this.hsluv_l = this.lch_l;
|
|
110
|
+
}
|
|
111
|
+
this.hsluv_h = this.lch_h;
|
|
112
|
+
}
|
|
113
|
+
hpluvToLch() {
|
|
114
|
+
if (this.hpluv_l > 99.9999999)
|
|
115
|
+
this.lch_l = 100, this.lch_c = 0;
|
|
116
|
+
else if (this.hpluv_l < 1e-8)
|
|
117
|
+
this.lch_l = 0, this.lch_c = 0;
|
|
118
|
+
else {
|
|
119
|
+
this.lch_l = this.hpluv_l, this.calculateBoundingLines(this.hpluv_l);
|
|
120
|
+
const t = this.calcMaxChromaHpluv();
|
|
121
|
+
this.lch_c = t / 100 * this.hpluv_p;
|
|
122
|
+
}
|
|
123
|
+
this.lch_h = this.hpluv_h;
|
|
124
|
+
}
|
|
125
|
+
lchToHpluv() {
|
|
126
|
+
if (this.lch_l > 99.9999999)
|
|
127
|
+
this.hpluv_p = 0, this.hpluv_l = 100;
|
|
128
|
+
else if (this.lch_l < 1e-8)
|
|
129
|
+
this.hpluv_p = 0, this.hpluv_l = 0;
|
|
130
|
+
else {
|
|
131
|
+
this.calculateBoundingLines(this.lch_l);
|
|
132
|
+
const t = this.calcMaxChromaHpluv();
|
|
133
|
+
this.hpluv_p = this.lch_c / t * 100, this.hpluv_l = this.lch_l;
|
|
134
|
+
}
|
|
135
|
+
this.hpluv_h = this.lch_h;
|
|
136
|
+
}
|
|
137
|
+
hsluvToRgb() {
|
|
138
|
+
this.hsluvToLch(), this.lchToLuv(), this.luvToXyz(), this.xyzToRgb();
|
|
139
|
+
}
|
|
140
|
+
hpluvToRgb() {
|
|
141
|
+
this.hpluvToLch(), this.lchToLuv(), this.luvToXyz(), this.xyzToRgb();
|
|
142
|
+
}
|
|
143
|
+
hsluvToHex() {
|
|
144
|
+
this.hsluvToRgb(), this.rgbToHex();
|
|
145
|
+
}
|
|
146
|
+
hpluvToHex() {
|
|
147
|
+
this.hpluvToRgb(), this.rgbToHex();
|
|
148
|
+
}
|
|
149
|
+
rgbToHsluv() {
|
|
150
|
+
this.rgbToXyz(), this.xyzToLuv(), this.luvToLch(), this.lchToHpluv(), this.lchToHsluv();
|
|
151
|
+
}
|
|
152
|
+
rgbToHpluv() {
|
|
153
|
+
this.rgbToXyz(), this.xyzToLuv(), this.luvToLch(), this.lchToHpluv(), this.lchToHpluv();
|
|
154
|
+
}
|
|
155
|
+
hexToHsluv() {
|
|
156
|
+
this.hexToRgb(), this.rgbToHsluv();
|
|
157
|
+
}
|
|
158
|
+
hexToHpluv() {
|
|
159
|
+
this.hexToRgb(), this.rgbToHpluv();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
s.hexChars = "0123456789abcdef";
|
|
163
|
+
s.refY = 1;
|
|
164
|
+
s.refU = 0.19783000664283;
|
|
165
|
+
s.refV = 0.46831999493879;
|
|
166
|
+
s.kappa = 903.2962962;
|
|
167
|
+
s.epsilon = 0.0088564516;
|
|
168
|
+
s.m_r0 = 3.240969941904521;
|
|
169
|
+
s.m_r1 = -1.537383177570093;
|
|
170
|
+
s.m_r2 = -0.498610760293;
|
|
171
|
+
s.m_g0 = -0.96924363628087;
|
|
172
|
+
s.m_g1 = 1.87596750150772;
|
|
173
|
+
s.m_g2 = 0.041555057407175;
|
|
174
|
+
s.m_b0 = 0.055630079696993;
|
|
175
|
+
s.m_b1 = -0.20397695888897;
|
|
176
|
+
s.m_b2 = 1.056971514242878;
|
|
177
|
+
const u = {
|
|
178
|
+
PROTANOPIA: [
|
|
179
|
+
[0.567, 0.433, 0],
|
|
180
|
+
[0.558, 0.442, 0],
|
|
181
|
+
[0, 0.242, 0.758]
|
|
182
|
+
],
|
|
183
|
+
PROTANOMALY: [
|
|
184
|
+
[0.817, 0.183, 0],
|
|
185
|
+
[0.333, 0.667, 0],
|
|
186
|
+
[0, 0.125, 0.875]
|
|
187
|
+
],
|
|
188
|
+
DEUTERANOPIA: [
|
|
189
|
+
[0.625, 0.375, 0],
|
|
190
|
+
[0.7, 0.3, 0],
|
|
191
|
+
[0, 0.3, 0.7]
|
|
192
|
+
],
|
|
193
|
+
DEUTERANOMALY: [
|
|
194
|
+
[0.8, 0.2, 0],
|
|
195
|
+
[0.258, 0.742, 0],
|
|
196
|
+
[0, 0.142, 0.858]
|
|
197
|
+
],
|
|
198
|
+
TRITANOPIA: [
|
|
199
|
+
[0.95, 0.05, 0],
|
|
200
|
+
[0, 0.433, 0.567],
|
|
201
|
+
[0, 0.475, 0.525]
|
|
202
|
+
],
|
|
203
|
+
TRITANOMALY: [
|
|
204
|
+
[0.967, 0.033, 0],
|
|
205
|
+
[0, 0.733, 0.267],
|
|
206
|
+
[0, 0.183, 0.817]
|
|
207
|
+
],
|
|
208
|
+
ACHROMATOPSIA: [
|
|
209
|
+
[0.299, 0.587, 0.114],
|
|
210
|
+
[0.299, 0.587, 0.114],
|
|
211
|
+
[0.299, 0.587, 0.114]
|
|
212
|
+
],
|
|
213
|
+
ACHROMATOMALY: [
|
|
214
|
+
[0.618, 0.32, 0.062],
|
|
215
|
+
[0.163, 0.775, 0.062],
|
|
216
|
+
[0.163, 0.32, 0.516]
|
|
217
|
+
]
|
|
218
|
+
}, c = (b, t) => {
|
|
219
|
+
const [h, r, o] = b, [i, e, a] = t;
|
|
220
|
+
return [
|
|
221
|
+
Math.round(h * i[0] + r * i[1] + o * i[2]),
|
|
222
|
+
Math.round(h * e[0] + r * e[1] + o * e[2]),
|
|
223
|
+
Math.round(h * a[0] + r * a[1] + o * a[2])
|
|
224
|
+
];
|
|
225
|
+
};
|
|
226
|
+
class R {
|
|
227
|
+
constructor({
|
|
228
|
+
render: t = "HEX",
|
|
229
|
+
sourceColor: h = [0, 0, 0],
|
|
230
|
+
lightness: r = parseFloat((n(h).luminance() * 100).toFixed(1)),
|
|
231
|
+
alpha: o = 1,
|
|
232
|
+
hueShifting: i = 0,
|
|
233
|
+
chromaShifting: e = 100,
|
|
234
|
+
algorithmVersion: a = "v3",
|
|
235
|
+
visionSimulationMode: g = "NONE"
|
|
236
|
+
}) {
|
|
237
|
+
l(this, "render");
|
|
238
|
+
l(this, "sourceColor");
|
|
239
|
+
l(this, "lightness");
|
|
240
|
+
l(this, "alpha");
|
|
241
|
+
l(this, "hueShifting");
|
|
242
|
+
l(this, "chromaShifting");
|
|
243
|
+
l(this, "algorithmVersion");
|
|
244
|
+
l(this, "visionSimulationMode");
|
|
245
|
+
l(this, "adjustHue", (t) => t + this.hueShifting < 0 ? t + this.hueShifting + 360 : t + this.hueShifting > 360 ? t + this.hueShifting - 360 : t + this.hueShifting);
|
|
246
|
+
l(this, "adjustChroma", (t) => {
|
|
247
|
+
if (this.algorithmVersion === "v1") return t;
|
|
248
|
+
if (this.algorithmVersion === "v2")
|
|
249
|
+
return Math.sin(this.lightness / 100 * Math.PI) * t;
|
|
250
|
+
if (this.algorithmVersion === "v3") {
|
|
251
|
+
const h = this.lightness / 100, r = Math.sin(h * Math.PI), o = Math.tanh(h * Math.PI), i = r * 0.5 + o * 0.5;
|
|
252
|
+
return Math.pow(i, 0.5) * t;
|
|
253
|
+
}
|
|
254
|
+
return t;
|
|
255
|
+
});
|
|
256
|
+
l(this, "setColor", () => this.render === "HEX" ? this.simulateColorBlindHex(this.sourceColor) : this.simulateColorBlindRgb(this.sourceColor));
|
|
257
|
+
l(this, "setColorWithAlpha", () => this.render === "HEX" ? n.rgb(...this.simulateColorBlindRgb(this.sourceColor), this.alpha).hex() : [...this.simulateColorBlindRgb(this.sourceColor), this.alpha]);
|
|
258
|
+
l(this, "lch", () => {
|
|
259
|
+
const t = n(this.sourceColor).lch(), h = n.lch(
|
|
260
|
+
this.lightness,
|
|
261
|
+
this.adjustChroma(t[1] * (this.chromaShifting / 100)),
|
|
262
|
+
this.adjustHue(t[2])
|
|
263
|
+
).rgb();
|
|
264
|
+
return this.render === "HEX" ? this.simulateColorBlindHex(h) : this.simulateColorBlindRgb(h);
|
|
265
|
+
});
|
|
266
|
+
l(this, "lcha", () => {
|
|
267
|
+
const t = n(this.sourceColor).lch(), h = n.lch(
|
|
268
|
+
t[0],
|
|
269
|
+
this.adjustChroma(t[1] * (this.chromaShifting / 100)),
|
|
270
|
+
this.adjustHue(t[2])
|
|
271
|
+
).rgb();
|
|
272
|
+
return this.render === "HEX" ? n.rgb(...this.simulateColorBlindRgb(h), this.alpha).hex() : [...this.simulateColorBlindRgb(h), this.alpha];
|
|
273
|
+
});
|
|
274
|
+
l(this, "oklch", () => {
|
|
275
|
+
const t = n(this.sourceColor).oklch(), h = n.oklch(
|
|
276
|
+
this.lightness / 100,
|
|
277
|
+
this.adjustChroma(t[1] * (this.chromaShifting / 100)),
|
|
278
|
+
this.adjustHue(t[2])
|
|
279
|
+
).rgb();
|
|
280
|
+
return this.render === "HEX" ? this.simulateColorBlindHex(h) : this.simulateColorBlindRgb(h);
|
|
281
|
+
});
|
|
282
|
+
l(this, "oklcha", () => {
|
|
283
|
+
const t = n(this.sourceColor).oklch(), h = n.oklch(
|
|
284
|
+
t[0],
|
|
285
|
+
this.adjustChroma(t[1] * (this.chromaShifting / 100)),
|
|
286
|
+
this.adjustHue(t[2])
|
|
287
|
+
).rgb();
|
|
288
|
+
return this.render === "HEX" ? n.rgb(...this.simulateColorBlindRgb(h), this.alpha).hex() : [...this.simulateColorBlindRgb(h), this.alpha];
|
|
289
|
+
});
|
|
290
|
+
l(this, "lab", () => {
|
|
291
|
+
const t = n(this.sourceColor).get("lab.a"), h = n(this.sourceColor).get("lab.b"), r = Math.sqrt(t ** 2 + h ** 2) * (this.chromaShifting / 100);
|
|
292
|
+
let o = Math.atan(h / t) + this.hueShifting * (Math.PI / 180);
|
|
293
|
+
(o > Math.PI || o < -Math.PI) && (o = Math.PI);
|
|
294
|
+
let i = r * Math.cos(o), e = r * Math.sin(o);
|
|
295
|
+
Math.sign(t) === -1 && Math.sign(h) === 1 && (i *= -1, e *= -1), Math.sign(t) === -1 && Math.sign(h) === -1 && (i *= -1, e *= -1);
|
|
296
|
+
const a = n.lab(
|
|
297
|
+
this.lightness,
|
|
298
|
+
this.adjustChroma(i),
|
|
299
|
+
this.adjustChroma(e)
|
|
300
|
+
).rgb();
|
|
301
|
+
return this.render === "HEX" ? this.simulateColorBlindHex(a) : this.simulateColorBlindRgb(a);
|
|
302
|
+
});
|
|
303
|
+
l(this, "laba", () => {
|
|
304
|
+
const t = n(this.sourceColor).get("lab.a"), h = n(this.sourceColor).get("lab.b"), r = n(this.sourceColor).get("lab.l"), o = Math.sqrt(t ** 2 + h ** 2) * (this.chromaShifting / 100);
|
|
305
|
+
let i = Math.atan(h / t) + this.hueShifting * (Math.PI / 180);
|
|
306
|
+
(i > Math.PI || i < -Math.PI) && (i = Math.PI);
|
|
307
|
+
let e = o * Math.cos(i), a = o * Math.sin(i);
|
|
308
|
+
Math.sign(t) === -1 && Math.sign(h) === 1 && (e *= -1, a *= -1), Math.sign(t) === -1 && Math.sign(h) === -1 && (e *= -1, a *= -1);
|
|
309
|
+
const g = n.lab(r, this.adjustChroma(e), this.adjustChroma(a)).rgb();
|
|
310
|
+
return this.render === "HEX" ? n.rgb(...this.simulateColorBlindRgb(g), this.alpha).hex() : [...this.simulateColorBlindRgb(g), this.alpha];
|
|
311
|
+
});
|
|
312
|
+
l(this, "oklab", () => {
|
|
313
|
+
const t = n(this.sourceColor).get("oklab.a"), h = n(this.sourceColor).get("oklab.b"), r = Math.sqrt(t ** 2 + h ** 2) * (this.chromaShifting / 100);
|
|
314
|
+
let o = Math.atan(h / t) + this.hueShifting * (Math.PI / 180);
|
|
315
|
+
(o > Math.PI || o < -Math.PI) && (o = Math.PI);
|
|
316
|
+
let i = r * Math.cos(o), e = r * Math.sin(o);
|
|
317
|
+
Math.sign(t) === -1 && Math.sign(h) === 1 && (i *= -1, e *= -1), Math.sign(t) === -1 && Math.sign(h) === -1 && (i *= -1, e *= -1), Number.isNaN(i) && (i = 0), Number.isNaN(e) && (e = 0);
|
|
318
|
+
const a = n.oklab(
|
|
319
|
+
this.lightness / 100,
|
|
320
|
+
this.adjustChroma(i),
|
|
321
|
+
this.adjustChroma(e)
|
|
322
|
+
).rgb();
|
|
323
|
+
return this.render === "HEX" ? this.simulateColorBlindHex(a) : this.simulateColorBlindRgb(a);
|
|
324
|
+
});
|
|
325
|
+
l(this, "oklaba", () => {
|
|
326
|
+
const t = n(this.sourceColor).get("oklab.a"), h = n(this.sourceColor).get("oklab.b"), r = n(this.sourceColor).get("oklab.l"), o = Math.sqrt(t ** 2 + h ** 2) * (this.chromaShifting / 100);
|
|
327
|
+
let i = Math.atan(h / t) + this.hueShifting * (Math.PI / 180);
|
|
328
|
+
(i > Math.PI || i < -Math.PI) && (i = Math.PI);
|
|
329
|
+
let e = o * Math.cos(i), a = o * Math.sin(i);
|
|
330
|
+
Math.sign(t) === -1 && Math.sign(h) === 1 && (e *= -1, a *= -1), Math.sign(t) === -1 && Math.sign(h) === -1 && (e *= -1, a *= -1), Number.isNaN(e) && (e = 0), Number.isNaN(a) && (a = 0);
|
|
331
|
+
const g = n.oklab(r, this.adjustChroma(e), this.adjustChroma(a)).rgb();
|
|
332
|
+
return this.render === "HEX" ? n.rgb(...this.simulateColorBlindRgb(g), this.alpha).hex() : [...this.simulateColorBlindRgb(g), this.alpha];
|
|
333
|
+
});
|
|
334
|
+
l(this, "hsl", () => {
|
|
335
|
+
const t = n(this.sourceColor).hsl(), h = n.hsl(
|
|
336
|
+
this.adjustHue(t[0]),
|
|
337
|
+
this.adjustChroma(t[1] * (this.chromaShifting / 100)),
|
|
338
|
+
this.lightness / 100
|
|
339
|
+
).rgb();
|
|
340
|
+
return this.render === "HEX" ? this.simulateColorBlindHex(h) : this.simulateColorBlindRgb(h);
|
|
341
|
+
});
|
|
342
|
+
l(this, "hsla", () => {
|
|
343
|
+
const t = n(this.sourceColor).hsl(), h = n.hsl(
|
|
344
|
+
this.adjustHue(t[0]),
|
|
345
|
+
this.adjustChroma(t[1] * (this.chromaShifting / 100)),
|
|
346
|
+
t[2]
|
|
347
|
+
).rgb();
|
|
348
|
+
return this.render === "HEX" ? n.rgb(...this.simulateColorBlindRgb(h), this.alpha).hex() : [...this.simulateColorBlindRgb(h), this.alpha];
|
|
349
|
+
});
|
|
350
|
+
l(this, "hsluv", () => {
|
|
351
|
+
const t = new s();
|
|
352
|
+
t.rgb_r = this.sourceColor[0] / 255, t.rgb_g = this.sourceColor[1] / 255, t.rgb_b = this.sourceColor[2] / 255, t.rgbToHsluv(), t.hsluv_l = this.lightness, t.hsluv_s = this.adjustChroma(
|
|
353
|
+
t.hsluv_s * (this.chromaShifting / 100)
|
|
354
|
+
), t.hsluv_h = this.adjustHue(t.hsluv_h), Number.isNaN(t.hsluv_s) && (t.hsluv_s = 0), Number.isNaN(t.hsluv_h) && (t.hsluv_h = 0), t.hsluvToRgb();
|
|
355
|
+
const h = [
|
|
356
|
+
t.rgb_r * 255,
|
|
357
|
+
t.rgb_g * 255,
|
|
358
|
+
t.rgb_b * 255
|
|
359
|
+
];
|
|
360
|
+
return this.render === "HEX" ? this.simulateColorBlindHex(h) : this.simulateColorBlindRgb(h);
|
|
361
|
+
});
|
|
362
|
+
l(this, "hsluva", () => {
|
|
363
|
+
const t = new s();
|
|
364
|
+
t.rgb_r = this.sourceColor[0] / 255, t.rgb_g = this.sourceColor[1] / 255, t.rgb_b = this.sourceColor[2] / 255, t.rgbToHsluv(), t.hsluv_s = this.adjustChroma(
|
|
365
|
+
t.hsluv_s * (this.chromaShifting / 100)
|
|
366
|
+
), t.hsluv_h = this.adjustHue(t.hsluv_h), Number.isNaN(t.hsluv_s) && (t.hsluv_s = 0), Number.isNaN(t.hsluv_h) && (t.hsluv_h = 0), t.hsluvToRgb();
|
|
367
|
+
const h = [
|
|
368
|
+
t.rgb_r * 255,
|
|
369
|
+
t.rgb_g * 255,
|
|
370
|
+
t.rgb_b * 255
|
|
371
|
+
];
|
|
372
|
+
return this.render === "HEX" ? n.rgb(...this.simulateColorBlindRgb(h), this.alpha).hex() : [...this.simulateColorBlindRgb(h), this.alpha];
|
|
373
|
+
});
|
|
374
|
+
l(this, "getHsluv", () => {
|
|
375
|
+
const t = new s();
|
|
376
|
+
return t.rgb_r = this.sourceColor[0] / 255, t.rgb_g = this.sourceColor[1] / 255, t.rgb_b = this.sourceColor[2] / 255, t.rgbToHsluv(), [t.hsluv_h, t.hsluv_s, t.hsluv_l];
|
|
377
|
+
});
|
|
378
|
+
l(this, "simulateColorBlindHex", (t) => {
|
|
379
|
+
var o;
|
|
380
|
+
const h = {
|
|
381
|
+
NONE: () => n(t).hex(),
|
|
382
|
+
PROTANOMALY: () => {
|
|
383
|
+
const i = c(
|
|
384
|
+
t,
|
|
385
|
+
u.PROTANOMALY
|
|
386
|
+
);
|
|
387
|
+
return n(i).hex();
|
|
388
|
+
},
|
|
389
|
+
PROTANOPIA: () => {
|
|
390
|
+
const i = c(
|
|
391
|
+
t,
|
|
392
|
+
u.PROTANOPIA
|
|
393
|
+
);
|
|
394
|
+
return n(i).hex();
|
|
395
|
+
},
|
|
396
|
+
DEUTERANOMALY: () => {
|
|
397
|
+
const i = c(
|
|
398
|
+
t,
|
|
399
|
+
u.DEUTERANOMALY
|
|
400
|
+
);
|
|
401
|
+
return n(i).hex();
|
|
402
|
+
},
|
|
403
|
+
DEUTERANOPIA: () => {
|
|
404
|
+
const i = c(
|
|
405
|
+
t,
|
|
406
|
+
u.DEUTERANOPIA
|
|
407
|
+
);
|
|
408
|
+
return n(i).hex();
|
|
409
|
+
},
|
|
410
|
+
TRITANOMALY: () => {
|
|
411
|
+
const i = c(
|
|
412
|
+
t,
|
|
413
|
+
u.TRITANOMALY
|
|
414
|
+
);
|
|
415
|
+
return n(i).hex();
|
|
416
|
+
},
|
|
417
|
+
TRITANOPIA: () => {
|
|
418
|
+
const i = c(
|
|
419
|
+
t,
|
|
420
|
+
u.TRITANOPIA
|
|
421
|
+
);
|
|
422
|
+
return n(i).hex();
|
|
423
|
+
},
|
|
424
|
+
ACHROMATOMALY: () => {
|
|
425
|
+
const i = c(
|
|
426
|
+
t,
|
|
427
|
+
u.ACHROMATOMALY
|
|
428
|
+
);
|
|
429
|
+
return n(i).hex();
|
|
430
|
+
},
|
|
431
|
+
ACHROMATOPSIA: () => {
|
|
432
|
+
const i = c(
|
|
433
|
+
t,
|
|
434
|
+
u.ACHROMATOPSIA
|
|
435
|
+
);
|
|
436
|
+
return n(i).hex();
|
|
437
|
+
}
|
|
438
|
+
}, r = (o = h[this.visionSimulationMode]) == null ? void 0 : o.call(h);
|
|
439
|
+
return r !== void 0 ? r : "#000000";
|
|
440
|
+
});
|
|
441
|
+
l(this, "simulateColorBlindRgb", (t) => {
|
|
442
|
+
var o;
|
|
443
|
+
const h = {
|
|
444
|
+
NONE: () => n(t).rgb(),
|
|
445
|
+
PROTANOMALY: () => c(t, u.PROTANOMALY),
|
|
446
|
+
PROTANOPIA: () => c(t, u.PROTANOPIA),
|
|
447
|
+
DEUTERANOMALY: () => c(t, u.DEUTERANOMALY),
|
|
448
|
+
DEUTERANOPIA: () => c(t, u.DEUTERANOPIA),
|
|
449
|
+
TRITANOMALY: () => c(t, u.TRITANOMALY),
|
|
450
|
+
TRITANOPIA: () => c(t, u.TRITANOPIA),
|
|
451
|
+
ACHROMATOMALY: () => c(t, u.ACHROMATOMALY),
|
|
452
|
+
ACHROMATOPSIA: () => c(t, u.ACHROMATOPSIA)
|
|
453
|
+
}, r = (o = h[this.visionSimulationMode]) == null ? void 0 : o.call(h);
|
|
454
|
+
return r !== void 0 ? r : [0, 0, 0];
|
|
455
|
+
});
|
|
456
|
+
l(this, "mixColorsRgb", (t, h) => {
|
|
457
|
+
const [r, o, i, e] = t, [a, g, m, _] = h;
|
|
458
|
+
if (e === 1) return [r, o, i];
|
|
459
|
+
if (e === 0) return [a, g, m];
|
|
460
|
+
const M = e + _ * (1 - e), C = Math.min(
|
|
461
|
+
255,
|
|
462
|
+
Math.max(0, Math.round((r * e + a * _ * (1 - e)) / M))
|
|
463
|
+
), d = Math.min(
|
|
464
|
+
255,
|
|
465
|
+
Math.max(0, Math.round((o * e + g * _ * (1 - e)) / M))
|
|
466
|
+
), x = Math.min(
|
|
467
|
+
255,
|
|
468
|
+
Math.max(0, Math.round((i * e + m * _ * (1 - e)) / M))
|
|
469
|
+
);
|
|
470
|
+
return this.simulateColorBlindRgb([C, d, x]);
|
|
471
|
+
});
|
|
472
|
+
l(this, "mixColorsHex", (t, h) => {
|
|
473
|
+
if (!/^#([0-9A-Fa-f]{3}){1,2}$/.test(t)) return t;
|
|
474
|
+
if (!/^#([0-9A-Fa-f]{3}){1,2}$/.test(h)) return h;
|
|
475
|
+
const r = n(t).rgba(), o = n(h).rgba(), i = this.mixColorsRgb(r, o);
|
|
476
|
+
return n(i).hex();
|
|
477
|
+
});
|
|
478
|
+
this.render = t, this.sourceColor = h, this.lightness = r, this.alpha = o, this.hueShifting = i, this.chromaShifting = e, this.algorithmVersion = a, this.visionSimulationMode = g;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
export {
|
|
482
|
+
R as C,
|
|
483
|
+
s as H
|
|
484
|
+
};
|
|
485
|
+
//# sourceMappingURL=color-BND6T00o.js.map
|