@luntta/swatch 3.0.0 → 3.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/CHANGELOG.md +7 -1
- package/MIGRATING.md +1 -1
- package/README.md +3 -3
- package/package.json +1 -1
- package/src/data/cvd-matrices.js +223 -118
- package/src/operations/cvd.js +10 -29
- package/src/operations/image.js +4 -21
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.0.1 — PATCH
|
|
4
|
+
|
|
5
|
+
- Fixed protan/deutan/tritan CVD simulation matrices to use the Machado severity table in linear-light sRGB, making protanopia and deuteranopia previews visibly distinct again.
|
|
6
|
+
- Updated the batch `simulateImageData`/`daltonizeImageData` paths to share the same CVD matrix builder as color-level simulation.
|
|
7
|
+
- Fixed the docs image playground fallback path so non-worker previews pass canonical CVD type keys.
|
|
8
|
+
|
|
3
9
|
## 3.0.0 — BREAKING
|
|
4
10
|
|
|
5
11
|
A complete rewrite. Storage moved to a canonical `{ space, coords, alpha }` state (colorjs.io / culori model) so wide-gamut inputs are preserved losslessly, conversions go through a lazy CIE XYZ D65 hub, and the monolithic `src/swatch.js` has been split into `src/core`, `src/spaces`, `src/parse`, `src/format`, `src/operations`, `src/scale`, `src/palettes`, and `src/data`.
|
|
@@ -41,7 +47,7 @@ See [`MIGRATING.md`](./MIGRATING.md) for the v2 → v3 cookbook.
|
|
|
41
47
|
|
|
42
48
|
The CVD / APCA / WCAG story is preserved end-to-end:
|
|
43
49
|
|
|
44
|
-
- `simulate(type, { severity })` —
|
|
50
|
+
- `simulate(type, { severity })` — CVD simulation with a severity continuum
|
|
45
51
|
- `daltonize(type, { severity })` — Fidaner error redistribution
|
|
46
52
|
- `swatch.checkPalette(colors, { cvd, minDeltaE, mode })`
|
|
47
53
|
- `swatch.nearestDistinguishable(target, against, { cvd, minDeltaE, step })`
|
package/MIGRATING.md
CHANGED
|
@@ -178,7 +178,7 @@ See [README.md](./README.md) for examples of each.
|
|
|
178
178
|
|
|
179
179
|
The CVD/APCA/WCAG story — the heart of swatch — is unchanged:
|
|
180
180
|
|
|
181
|
-
- `simulate(type, { severity })` —
|
|
181
|
+
- `simulate(type, { severity })` — CVD simulation with a severity continuum
|
|
182
182
|
- `daltonize(type, { severity })` — Fidaner error redistribution
|
|
183
183
|
- `swatch.checkPalette(colors, { cvd, minDeltaE, mode })`
|
|
184
184
|
- `swatch.nearestDistinguishable(target, against, { cvd, minDeltaE, step })`
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Swatch
|
|
2
2
|
|
|
3
|
-
A color library with **first-class colorblind support** —
|
|
3
|
+
A color library with **first-class colorblind support** — Machado CVD simulation, severity continuum, Fidaner daltonization, and palette distinguishability checks — plus the things you expect from a modern color library: CSS Color 4 parsing, wide-gamut spaces, OKLab/OKLCh manipulation, color scales, built-in scientific palettes, blend modes, naming, temperature, WCAG 2.1, and APCA.
|
|
4
4
|
|
|
5
5
|
**Docs & interactive playground:** <https://luntta.github.io/swatch/>
|
|
6
6
|
|
|
@@ -281,7 +281,7 @@ The `.srgb` / `.linearSrgb` / `.hsl` getters return raw conversions, so wide-gam
|
|
|
281
281
|
|
|
282
282
|
## Colorblind simulation
|
|
283
283
|
|
|
284
|
-
|
|
284
|
+
Physiologically based Machado/Oliveira/Fernandes CVD simulation in linear-light sRGB.
|
|
285
285
|
|
|
286
286
|
```js
|
|
287
287
|
const red = swatch("#ff0000");
|
|
@@ -294,7 +294,7 @@ red.simulate("achroma"); // Rec. 709 grayscale
|
|
|
294
294
|
|
|
295
295
|
Accepted aliases: `protanopia`/`protanomaly` → `protan`, `deuteranopia`/`deuteranomaly` → `deutan`, `tritanopia`/`tritanomaly` → `tritan`, `achromatopsia` → `achroma`.
|
|
296
296
|
|
|
297
|
-
Severity `0.0` is identity, `1.0` is the full dichromat, in
|
|
297
|
+
Severity `0.0` is identity, `1.0` is the full dichromat, and in-between values interpolate across the published Machado severity table.
|
|
298
298
|
|
|
299
299
|
### ImageData simulation
|
|
300
300
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luntta/swatch",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "A color library with first-class colorblind support, CSS Color 4 parsing, wide-gamut spaces, OKLCh manipulation, color scales, built-in palettes, blend modes, WCAG 2.1, and APCA.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/swatch.js",
|
package/src/data/cvd-matrices.js
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
// CVD (Color Vision Deficiency) simulation matrices.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// Protan/deutan/tritan simulation uses the Machado, Oliveira & Fernandes
|
|
4
|
+
// physiologically-based matrices in linear-light sRGB. The table contains
|
|
5
|
+
// severity samples from 0.0 (identity) through 1.0 (full dichromacy); callers
|
|
6
|
+
// interpolate between adjacent samples for the severity continuum.
|
|
6
7
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// and a confusion-line anchor (blue for protan/deutan, red for
|
|
12
|
-
// tritan). The missing cone's response is reconstructed as
|
|
13
|
-
// a·X + b·Y in LMS space, solved via Cramer's rule.
|
|
8
|
+
// This replaces the old single-plane LMS projection, which used the sRGB blue
|
|
9
|
+
// primary as the shared protan/deutan anchor. That shortcut forced red and
|
|
10
|
+
// green output rows to collapse together, so image previews for protanopia and
|
|
11
|
+
// deuteranopia were much closer than expected.
|
|
14
12
|
|
|
15
|
-
import { multiplyMatrices, invertMatrix } from "../util/matrix.js";
|
|
16
13
|
import { appendSuggestion } from "../util/suggest.js";
|
|
17
14
|
|
|
18
15
|
const CVD_TYPES = [
|
|
@@ -30,107 +27,201 @@ const CVD_TYPES = [
|
|
|
30
27
|
"achromatomaly"
|
|
31
28
|
];
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
[0
|
|
36
|
-
[0
|
|
37
|
-
[0.0193339, 0.119192, 0.9503041]
|
|
30
|
+
export const IDENTITY3 = [
|
|
31
|
+
[1, 0, 0],
|
|
32
|
+
[0, 1, 0],
|
|
33
|
+
[0, 0, 1]
|
|
38
34
|
];
|
|
39
35
|
|
|
40
|
-
//
|
|
41
|
-
const
|
|
42
|
-
[0.
|
|
43
|
-
[
|
|
44
|
-
[0, 0, 0.
|
|
36
|
+
// Rec. 709 luminance row, used for the achromatopsia projection.
|
|
37
|
+
export const ACHROMA_MATRIX = [
|
|
38
|
+
[0.2126, 0.7152, 0.0722],
|
|
39
|
+
[0.2126, 0.7152, 0.0722],
|
|
40
|
+
[0.2126, 0.7152, 0.0722]
|
|
45
41
|
];
|
|
46
42
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
export const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
[
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
43
|
+
// Machado (2010) Φ_CVD matrices, sampled at severity 0.0, 0.1, …, 1.0.
|
|
44
|
+
// Matrix rows are linear-sRGB output channels; columns are linear-sRGB input
|
|
45
|
+
// channels. The 1.0 samples correspond to protanopia, deuteranopia, and
|
|
46
|
+
// tritanopia respectively.
|
|
47
|
+
export const CVD_MACHADO_MATRICES = {
|
|
48
|
+
protan: [
|
|
49
|
+
[
|
|
50
|
+
[1.0, 0.0, -0.0],
|
|
51
|
+
[0.0, 1.0, 0.0],
|
|
52
|
+
[-0.0, -0.0, 1.0]
|
|
53
|
+
],
|
|
54
|
+
[
|
|
55
|
+
[0.856167, 0.182038, -0.038205],
|
|
56
|
+
[0.029342, 0.955115, 0.015544],
|
|
57
|
+
[-0.00288, -0.001563, 1.004443]
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
[0.734766, 0.334872, -0.069637],
|
|
61
|
+
[0.05184, 0.919198, 0.028963],
|
|
62
|
+
[-0.004928, -0.004209, 1.009137]
|
|
63
|
+
],
|
|
64
|
+
[
|
|
65
|
+
[0.630323, 0.465641, -0.095964],
|
|
66
|
+
[0.069181, 0.890046, 0.040773],
|
|
67
|
+
[-0.006308, -0.007724, 1.014032]
|
|
68
|
+
],
|
|
69
|
+
[
|
|
70
|
+
[0.539009, 0.579343, -0.118352],
|
|
71
|
+
[0.082546, 0.866121, 0.051332],
|
|
72
|
+
[-0.007136, -0.011959, 1.019095]
|
|
73
|
+
],
|
|
74
|
+
[
|
|
75
|
+
[0.458064, 0.679578, -0.137642],
|
|
76
|
+
[0.092785, 0.846313, 0.060902],
|
|
77
|
+
[-0.007494, -0.016807, 1.024301]
|
|
78
|
+
],
|
|
79
|
+
[
|
|
80
|
+
[0.38545, 0.769005, -0.154455],
|
|
81
|
+
[0.100526, 0.829802, 0.069673],
|
|
82
|
+
[-0.007442, -0.02219, 1.029632]
|
|
83
|
+
],
|
|
84
|
+
[
|
|
85
|
+
[0.319627, 0.849633, -0.169261],
|
|
86
|
+
[0.106241, 0.815969, 0.07779],
|
|
87
|
+
[-0.007025, -0.028051, 1.035076]
|
|
88
|
+
],
|
|
89
|
+
[
|
|
90
|
+
[0.259411, 0.923008, -0.18242],
|
|
91
|
+
[0.110296, 0.80434, 0.085364],
|
|
92
|
+
[-0.006276, -0.034346, 1.040622]
|
|
93
|
+
],
|
|
94
|
+
[
|
|
95
|
+
[0.203876, 0.990338, -0.194214],
|
|
96
|
+
[0.112975, 0.794542, 0.092483],
|
|
97
|
+
[-0.005222, -0.041043, 1.046265]
|
|
98
|
+
],
|
|
99
|
+
[
|
|
100
|
+
[0.152286, 1.052583, -0.204868],
|
|
101
|
+
[0.114503, 0.786281, 0.099216],
|
|
102
|
+
[-0.003882, -0.048116, 1.051998]
|
|
103
|
+
]
|
|
104
|
+
],
|
|
105
|
+
deutan: [
|
|
106
|
+
[
|
|
107
|
+
[1.0, 0.0, -0.0],
|
|
108
|
+
[0.0, 1.0, 0.0],
|
|
109
|
+
[-0.0, -0.0, 1.0]
|
|
110
|
+
],
|
|
111
|
+
[
|
|
112
|
+
[0.866435, 0.177704, -0.044139],
|
|
113
|
+
[0.049567, 0.939063, 0.01137],
|
|
114
|
+
[-0.003453, 0.007233, 0.99622]
|
|
115
|
+
],
|
|
116
|
+
[
|
|
117
|
+
[0.760729, 0.319078, -0.079807],
|
|
118
|
+
[0.090568, 0.889315, 0.020117],
|
|
119
|
+
[-0.006027, 0.013325, 0.992702]
|
|
120
|
+
],
|
|
121
|
+
[
|
|
122
|
+
[0.675425, 0.43385, -0.109275],
|
|
123
|
+
[0.125303, 0.847755, 0.026942],
|
|
124
|
+
[-0.00795, 0.018572, 0.989378]
|
|
125
|
+
],
|
|
126
|
+
[
|
|
127
|
+
[0.605511, 0.52856, -0.134071],
|
|
128
|
+
[0.155318, 0.812366, 0.032316],
|
|
129
|
+
[-0.009376, 0.023176, 0.9862]
|
|
130
|
+
],
|
|
131
|
+
[
|
|
132
|
+
[0.547494, 0.607765, -0.155259],
|
|
133
|
+
[0.181692, 0.781742, 0.036566],
|
|
134
|
+
[-0.01041, 0.027275, 0.983136]
|
|
135
|
+
],
|
|
136
|
+
[
|
|
137
|
+
[0.498864, 0.674741, -0.173604],
|
|
138
|
+
[0.205199, 0.754872, 0.039929],
|
|
139
|
+
[-0.011131, 0.030969, 0.980162]
|
|
140
|
+
],
|
|
141
|
+
[
|
|
142
|
+
[0.457771, 0.731899, -0.18967],
|
|
143
|
+
[0.226409, 0.731012, 0.042579],
|
|
144
|
+
[-0.011595, 0.034333, 0.977261]
|
|
145
|
+
],
|
|
146
|
+
[
|
|
147
|
+
[0.422823, 0.781057, -0.203881],
|
|
148
|
+
[0.245752, 0.709602, 0.044646],
|
|
149
|
+
[-0.011843, 0.037423, 0.974421]
|
|
150
|
+
],
|
|
151
|
+
[
|
|
152
|
+
[0.392952, 0.82361, -0.216562],
|
|
153
|
+
[0.263559, 0.69021, 0.046232],
|
|
154
|
+
[-0.01191, 0.040281, 0.97163]
|
|
155
|
+
],
|
|
156
|
+
[
|
|
157
|
+
[0.367322, 0.860646, -0.227968],
|
|
158
|
+
[0.280085, 0.672501, 0.047413],
|
|
159
|
+
[-0.01182, 0.04294, 0.968881]
|
|
160
|
+
]
|
|
161
|
+
],
|
|
162
|
+
tritan: [
|
|
163
|
+
[
|
|
164
|
+
[1.0, 0.0, -0.0],
|
|
165
|
+
[0.0, 1.0, 0.0],
|
|
166
|
+
[-0.0, -0.0, 1.0]
|
|
167
|
+
],
|
|
168
|
+
[
|
|
169
|
+
[0.92667, 0.092514, -0.019184],
|
|
170
|
+
[0.021191, 0.964503, 0.014306],
|
|
171
|
+
[0.008437, 0.054813, 0.93675]
|
|
172
|
+
],
|
|
173
|
+
[
|
|
174
|
+
[0.89572, 0.13333, -0.02905],
|
|
175
|
+
[0.029997, 0.9454, 0.024603],
|
|
176
|
+
[0.013027, 0.104707, 0.882266]
|
|
177
|
+
],
|
|
178
|
+
[
|
|
179
|
+
[0.905871, 0.127791, -0.033662],
|
|
180
|
+
[0.026856, 0.941251, 0.031893],
|
|
181
|
+
[0.01341, 0.148296, 0.838294]
|
|
182
|
+
],
|
|
183
|
+
[
|
|
184
|
+
[0.948035, 0.08949, -0.037526],
|
|
185
|
+
[0.014364, 0.946792, 0.038844],
|
|
186
|
+
[0.010853, 0.193991, 0.795156]
|
|
187
|
+
],
|
|
188
|
+
[
|
|
189
|
+
[1.017277, 0.027029, -0.044306],
|
|
190
|
+
[-0.006113, 0.958479, 0.047634],
|
|
191
|
+
[0.006379, 0.248708, 0.744913]
|
|
192
|
+
],
|
|
193
|
+
[
|
|
194
|
+
[1.104996, -0.046633, -0.058363],
|
|
195
|
+
[-0.032137, 0.971635, 0.060503],
|
|
196
|
+
[0.001336, 0.317922, 0.680742]
|
|
197
|
+
],
|
|
198
|
+
[
|
|
199
|
+
[1.193214, -0.109812, -0.083402],
|
|
200
|
+
[-0.058496, 0.97941, 0.079086],
|
|
201
|
+
[-0.002346, 0.403492, 0.598854]
|
|
202
|
+
],
|
|
203
|
+
[
|
|
204
|
+
[1.257728, -0.139648, -0.118081],
|
|
205
|
+
[-0.078003, 0.975409, 0.102594],
|
|
206
|
+
[-0.003316, 0.501214, 0.502102]
|
|
207
|
+
],
|
|
208
|
+
[
|
|
209
|
+
[1.278864, -0.125333, -0.153531],
|
|
210
|
+
[-0.084748, 0.957674, 0.127074],
|
|
211
|
+
[-0.000989, 0.601151, 0.399838]
|
|
212
|
+
],
|
|
213
|
+
[
|
|
214
|
+
[1.255528, -0.076749, -0.178779],
|
|
215
|
+
[-0.078411, 0.930809, 0.147602],
|
|
216
|
+
[0.004733, 0.691367, 0.3039]
|
|
217
|
+
]
|
|
218
|
+
]
|
|
219
|
+
};
|
|
129
220
|
|
|
130
221
|
export const CVD_RGB_MATRICES = {
|
|
131
|
-
protan:
|
|
132
|
-
deutan:
|
|
133
|
-
tritan:
|
|
222
|
+
protan: CVD_MACHADO_MATRICES.protan[10],
|
|
223
|
+
deutan: CVD_MACHADO_MATRICES.deutan[10],
|
|
224
|
+
tritan: CVD_MACHADO_MATRICES.tritan[10]
|
|
134
225
|
};
|
|
135
226
|
|
|
136
227
|
export function normalizeCVDType(type) {
|
|
@@ -151,18 +242,11 @@ export function normalizeCVDType(type) {
|
|
|
151
242
|
);
|
|
152
243
|
}
|
|
153
244
|
|
|
154
|
-
export
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
// Rec. 709 luminance row, used for the achromatopsia projection.
|
|
161
|
-
export const ACHROMA_MATRIX = [
|
|
162
|
-
[0.2126, 0.7152, 0.0722],
|
|
163
|
-
[0.2126, 0.7152, 0.0722],
|
|
164
|
-
[0.2126, 0.7152, 0.0722]
|
|
165
|
-
];
|
|
245
|
+
export function normalizeCVDSeverity(severity) {
|
|
246
|
+
const n = Number(severity);
|
|
247
|
+
if (!Number.isFinite(n)) return 1;
|
|
248
|
+
return n < 0 ? 0 : n > 1 ? 1 : n;
|
|
249
|
+
}
|
|
166
250
|
|
|
167
251
|
export function interpolateMatrix3(A, B, t) {
|
|
168
252
|
const out = [
|
|
@@ -177,3 +261,24 @@ export function interpolateMatrix3(A, B, t) {
|
|
|
177
261
|
}
|
|
178
262
|
return out;
|
|
179
263
|
}
|
|
264
|
+
|
|
265
|
+
function interpolateMachadoTable(table, severity) {
|
|
266
|
+
if (severity <= 0) return table[0];
|
|
267
|
+
if (severity >= 1) return table[10];
|
|
268
|
+
|
|
269
|
+
const scaled = severity * 10;
|
|
270
|
+
const lo = Math.min(9, Math.floor(scaled));
|
|
271
|
+
const hi = lo + 1;
|
|
272
|
+
const t = scaled - lo;
|
|
273
|
+
if (t === 0) return table[lo];
|
|
274
|
+
return interpolateMatrix3(table[lo], table[hi], t);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export function cvdSimulationMatrix(type, severity = 1) {
|
|
278
|
+
const normalized = normalizeCVDType(type);
|
|
279
|
+
const sev = normalizeCVDSeverity(severity);
|
|
280
|
+
if (normalized === "achroma") {
|
|
281
|
+
return interpolateMatrix3(IDENTITY3, ACHROMA_MATRIX, sev);
|
|
282
|
+
}
|
|
283
|
+
return interpolateMachadoTable(CVD_MACHADO_MATRICES[normalized], sev);
|
|
284
|
+
}
|
package/src/operations/cvd.js
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
// Color Vision Deficiency simulation and daltonization.
|
|
2
2
|
//
|
|
3
|
-
// Projection matrices for protan/deutan/tritan come from
|
|
4
|
-
// data/cvd-matrices.js
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
// linear sRGB) and shift it into channels the user can still see.
|
|
3
|
+
// Projection matrices for protan/deutan/tritan come from the
|
|
4
|
+
// Machado/Oliveira/Fernandes severity table in data/cvd-matrices.js.
|
|
5
|
+
// daltonize() uses Fidaner-style error redistribution: compute what the
|
|
6
|
+
// dichromat loses (the delta in linear sRGB) and shift it into channels the
|
|
7
|
+
// user can still see.
|
|
9
8
|
|
|
10
9
|
import { Swatch, swatch } from "../core/swatch-class.js";
|
|
11
10
|
import { srgbToLinear, linearToSrgb } from "../spaces/srgb.js";
|
|
12
11
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
ACHROMA_MATRIX,
|
|
16
|
-
interpolateMatrix3,
|
|
12
|
+
cvdSimulationMatrix,
|
|
13
|
+
normalizeCVDSeverity,
|
|
17
14
|
normalizeCVDType
|
|
18
15
|
} from "../data/cvd-matrices.js";
|
|
19
16
|
|
|
@@ -39,19 +36,7 @@ function clamp01Triplet(v) {
|
|
|
39
36
|
|
|
40
37
|
export function simulate(input, type, { severity = 1 } = {}) {
|
|
41
38
|
const s = toSwatch(input);
|
|
42
|
-
const
|
|
43
|
-
const normalized = normalizeCVDType(type);
|
|
44
|
-
|
|
45
|
-
let M;
|
|
46
|
-
if (normalized === "achroma") {
|
|
47
|
-
M = interpolateMatrix3(IDENTITY3, ACHROMA_MATRIX, sev);
|
|
48
|
-
} else {
|
|
49
|
-
M = interpolateMatrix3(
|
|
50
|
-
IDENTITY3,
|
|
51
|
-
CVD_RGB_MATRICES[normalized],
|
|
52
|
-
sev
|
|
53
|
-
);
|
|
54
|
-
}
|
|
39
|
+
const M = cvdSimulationMatrix(type, severity);
|
|
55
40
|
|
|
56
41
|
const { r, g, b } = s.srgb;
|
|
57
42
|
const lin = srgbToLinear([r, g, b]);
|
|
@@ -67,7 +52,7 @@ export function simulate(input, type, { severity = 1 } = {}) {
|
|
|
67
52
|
|
|
68
53
|
export function daltonize(input, type, { severity = 1 } = {}) {
|
|
69
54
|
const s = toSwatch(input);
|
|
70
|
-
const sev =
|
|
55
|
+
const sev = normalizeCVDSeverity(severity);
|
|
71
56
|
const normalized = normalizeCVDType(type);
|
|
72
57
|
if (normalized === "achroma") {
|
|
73
58
|
throw new Error(
|
|
@@ -75,11 +60,7 @@ export function daltonize(input, type, { severity = 1 } = {}) {
|
|
|
75
60
|
);
|
|
76
61
|
}
|
|
77
62
|
|
|
78
|
-
const M =
|
|
79
|
-
IDENTITY3,
|
|
80
|
-
CVD_RGB_MATRICES[normalized],
|
|
81
|
-
sev
|
|
82
|
-
);
|
|
63
|
+
const M = cvdSimulationMatrix(normalized, sev);
|
|
83
64
|
|
|
84
65
|
const { r, g, b } = s.srgb;
|
|
85
66
|
const lin = srgbToLinear([r, g, b]);
|
package/src/operations/image.js
CHANGED
|
@@ -6,10 +6,8 @@
|
|
|
6
6
|
// and preserves alpha untouched.
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
ACHROMA_MATRIX,
|
|
12
|
-
interpolateMatrix3,
|
|
9
|
+
cvdSimulationMatrix,
|
|
10
|
+
normalizeCVDSeverity,
|
|
13
11
|
normalizeCVDType
|
|
14
12
|
} from "../data/cvd-matrices.js";
|
|
15
13
|
|
|
@@ -36,12 +34,6 @@ function clamp01ToByte(v) {
|
|
|
36
34
|
return LINEAR_TO_SRGB8[(v * (LUT_SIZE - 1) + 0.5) | 0];
|
|
37
35
|
}
|
|
38
36
|
|
|
39
|
-
function normalizeSeverity(severity) {
|
|
40
|
-
const n = Number(severity);
|
|
41
|
-
if (!Number.isFinite(n)) return 1;
|
|
42
|
-
return n < 0 ? 0 : n > 1 ? 1 : n;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
37
|
function assertImageDataLike(imageData) {
|
|
46
38
|
if (!imageData || !imageData.data) {
|
|
47
39
|
throw new Error("imageData: expected { data, width, height }");
|
|
@@ -102,12 +94,7 @@ function targetImageData(imageData, inPlace) {
|
|
|
102
94
|
}
|
|
103
95
|
|
|
104
96
|
function simulationMatrix(type, severity) {
|
|
105
|
-
|
|
106
|
-
const sev = normalizeSeverity(severity);
|
|
107
|
-
const target = normalized === "achroma"
|
|
108
|
-
? ACHROMA_MATRIX
|
|
109
|
-
: CVD_RGB_MATRICES[normalized];
|
|
110
|
-
return interpolateMatrix3(IDENTITY3, target, sev);
|
|
97
|
+
return cvdSimulationMatrix(type, severity);
|
|
111
98
|
}
|
|
112
99
|
|
|
113
100
|
function correctionMatrix(type, severity) {
|
|
@@ -119,11 +106,7 @@ function correctionMatrix(type, severity) {
|
|
|
119
106
|
}
|
|
120
107
|
return {
|
|
121
108
|
normalized,
|
|
122
|
-
matrix:
|
|
123
|
-
IDENTITY3,
|
|
124
|
-
CVD_RGB_MATRICES[normalized],
|
|
125
|
-
normalizeSeverity(severity)
|
|
126
|
-
)
|
|
109
|
+
matrix: cvdSimulationMatrix(normalized, normalizeCVDSeverity(severity))
|
|
127
110
|
};
|
|
128
111
|
}
|
|
129
112
|
|