@tenphi/glaze 0.0.0-snapshot.e76f494 → 0.0.0-snapshot.f01add5
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/dist/index.cjs +30 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -4
- package/dist/index.d.mts +11 -4
- package/dist/index.mjs +30 -65
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -81,8 +81,8 @@ const OKLab_to_linear_sRGB_coefficients = [
|
|
|
81
81
|
.73956515,
|
|
82
82
|
-.45954404,
|
|
83
83
|
.08285427,
|
|
84
|
-
.
|
|
85
|
-
|
|
84
|
+
.1254107,
|
|
85
|
+
.14503204
|
|
86
86
|
]],
|
|
87
87
|
[[.13110757611180954, 1.813339709266608], [
|
|
88
88
|
1.35733652,
|
|
@@ -254,10 +254,9 @@ const getCs = (L, a, b, cusp) => {
|
|
|
254
254
|
];
|
|
255
255
|
};
|
|
256
256
|
/**
|
|
257
|
-
* Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to
|
|
258
|
-
* Channels may exceed [0, 1] near gamut boundaries — caller must clamp if needed.
|
|
257
|
+
* Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to OKLab [L, a, b].
|
|
259
258
|
*/
|
|
260
|
-
function
|
|
259
|
+
function okhslToOklab(h, s, l) {
|
|
261
260
|
const L = toeInv(l);
|
|
262
261
|
let a = 0;
|
|
263
262
|
let b = 0;
|
|
@@ -284,11 +283,18 @@ function okhslToLinearSrgb(h, s, l) {
|
|
|
284
283
|
a = c * a_;
|
|
285
284
|
b = c * b_;
|
|
286
285
|
}
|
|
287
|
-
return
|
|
286
|
+
return [
|
|
288
287
|
L,
|
|
289
288
|
a,
|
|
290
289
|
b
|
|
291
|
-
]
|
|
290
|
+
];
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to linear sRGB.
|
|
294
|
+
* Channels may exceed [0, 1] near gamut boundaries — caller must clamp if needed.
|
|
295
|
+
*/
|
|
296
|
+
function okhslToLinearSrgb(h, s, l) {
|
|
297
|
+
return OKLabToLinearSRGB(okhslToOklab(h, s, l));
|
|
292
298
|
}
|
|
293
299
|
/**
|
|
294
300
|
* Compute relative luminance Y from linear sRGB channels.
|
|
@@ -327,40 +333,15 @@ function okhslToSrgb(h, s, l) {
|
|
|
327
333
|
];
|
|
328
334
|
}
|
|
329
335
|
/**
|
|
330
|
-
*
|
|
336
|
+
* Compute WCAG 2 relative luminance from linear sRGB, matching the browser
|
|
337
|
+
* rendering pipeline: gamma-encode, clamp to sRGB gamut [0,1], then linearize.
|
|
338
|
+
* This avoids over/under-estimating luminance for out-of-gamut OKHSL colors.
|
|
331
339
|
*/
|
|
332
|
-
function
|
|
333
|
-
const
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
if (L !== 0 && L !== 1 && s !== 0) {
|
|
338
|
-
const a_ = Math.cos(TAU * hNorm);
|
|
339
|
-
const b_ = Math.sin(TAU * hNorm);
|
|
340
|
-
const [c0, cMid, cMax] = getCs(L, a_, b_, findCuspOKLCH(a_, b_));
|
|
341
|
-
const mid = .8;
|
|
342
|
-
const midInv = 1.25;
|
|
343
|
-
let t, k0, k1, k2;
|
|
344
|
-
if (s < mid) {
|
|
345
|
-
t = midInv * s;
|
|
346
|
-
k0 = 0;
|
|
347
|
-
k1 = mid * c0;
|
|
348
|
-
k2 = 1 - k1 / cMid;
|
|
349
|
-
} else {
|
|
350
|
-
t = 5 * (s - .8);
|
|
351
|
-
k0 = cMid;
|
|
352
|
-
k1 = .2 * cMid ** 2 * 1.25 ** 2 / c0;
|
|
353
|
-
k2 = 1 - k1 / (cMax - cMid);
|
|
354
|
-
}
|
|
355
|
-
const c = k0 + t * k1 / (1 - k2 * t);
|
|
356
|
-
a = c * a_;
|
|
357
|
-
b = c * b_;
|
|
358
|
-
}
|
|
359
|
-
return [
|
|
360
|
-
L,
|
|
361
|
-
a,
|
|
362
|
-
b
|
|
363
|
-
];
|
|
340
|
+
function gamutClampedLuminance(linearRgb) {
|
|
341
|
+
const r = sRGBGammaToLinear(Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[0]))));
|
|
342
|
+
const g = sRGBGammaToLinear(Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[1]))));
|
|
343
|
+
const b = sRGBGammaToLinear(Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[2]))));
|
|
344
|
+
return .2126 * r + .7152 * g + .0722 * b;
|
|
364
345
|
}
|
|
365
346
|
const linearSrgbToOklab = (rgb) => {
|
|
366
347
|
return transform(cbrt3(transform(rgb, linear_sRGB_to_LMS_M)), LMS_to_OKLab_M);
|
|
@@ -452,12 +433,13 @@ function formatOkhsl(h, s, l) {
|
|
|
452
433
|
return `okhsl(${fmt$1(h, 2)} ${fmt$1(s, 2)}% ${fmt$1(l, 2)}%)`;
|
|
453
434
|
}
|
|
454
435
|
/**
|
|
455
|
-
* Format OKHSL values as a CSS `rgb(R G B)` string
|
|
436
|
+
* Format OKHSL values as a CSS `rgb(R G B)` string.
|
|
437
|
+
* Uses 2 decimal places to avoid 8-bit quantization contrast loss.
|
|
456
438
|
* h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
|
|
457
439
|
*/
|
|
458
440
|
function formatRgb(h, s, l) {
|
|
459
441
|
const [r, g, b] = okhslToSrgb(h, s / 100, l / 100);
|
|
460
|
-
return `rgb(${
|
|
442
|
+
return `rgb(${parseFloat((r * 255).toFixed(2))} ${parseFloat((g * 255).toFixed(2))} ${parseFloat((b * 255).toFixed(2))})`;
|
|
461
443
|
}
|
|
462
444
|
/**
|
|
463
445
|
* Format OKHSL values as a CSS `hsl(H S% L%)` string.
|
|
@@ -513,23 +495,12 @@ function resolveMinContrast(value) {
|
|
|
513
495
|
const CACHE_SIZE = 512;
|
|
514
496
|
const luminanceCache = /* @__PURE__ */ new Map();
|
|
515
497
|
const cacheOrder = [];
|
|
516
|
-
/**
|
|
517
|
-
* Compute WCAG 2 relative luminance from linear sRGB, matching the browser
|
|
518
|
-
* rendering pipeline: gamma-encode, clamp to sRGB gamut [0,1], then linearize.
|
|
519
|
-
* This avoids over/under-estimating luminance for out-of-gamut OKHSL colors.
|
|
520
|
-
*/
|
|
521
|
-
function gamutClampedLuminance$1(linearRgb) {
|
|
522
|
-
const r = sRGBGammaToLinear(Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[0]))));
|
|
523
|
-
const g = sRGBGammaToLinear(Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[1]))));
|
|
524
|
-
const b = sRGBGammaToLinear(Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[2]))));
|
|
525
|
-
return .2126 * r + .7152 * g + .0722 * b;
|
|
526
|
-
}
|
|
527
498
|
function cachedLuminance(h, s, l) {
|
|
528
499
|
const lRounded = Math.round(l * 1e4) / 1e4;
|
|
529
500
|
const key = `${h}|${s}|${lRounded}`;
|
|
530
501
|
const cached = luminanceCache.get(key);
|
|
531
502
|
if (cached !== void 0) return cached;
|
|
532
|
-
const y = gamutClampedLuminance
|
|
503
|
+
const y = gamutClampedLuminance(okhslToLinearSrgb(h, s, lRounded));
|
|
533
504
|
if (luminanceCache.size >= CACHE_SIZE) {
|
|
534
505
|
const evict = cacheOrder.shift();
|
|
535
506
|
luminanceCache.delete(evict);
|
|
@@ -649,8 +620,8 @@ function coarseScan(h, s, lo, hi, yBase, target, epsilon, maxIter) {
|
|
|
649
620
|
function findLightnessForContrast(options) {
|
|
650
621
|
const { hue, saturation, preferredLightness, baseLinearRgb, contrast: contrastInput, lightnessRange = [0, 1], epsilon = 1e-4, maxIterations = 14 } = options;
|
|
651
622
|
const target = resolveMinContrast(contrastInput);
|
|
652
|
-
const searchTarget = target
|
|
653
|
-
const yBase = gamutClampedLuminance
|
|
623
|
+
const searchTarget = target * 1.005;
|
|
624
|
+
const yBase = gamutClampedLuminance(baseLinearRgb);
|
|
654
625
|
const crPref = contrastRatioFromLuminance(cachedLuminance(hue, saturation, preferredLightness), yBase);
|
|
655
626
|
if (crPref >= searchTarget) return {
|
|
656
627
|
lightness: preferredLightness,
|
|
@@ -773,8 +744,8 @@ function searchMixBranch(lo, hi, yBase, target, epsilon, maxIter, preferred, lum
|
|
|
773
744
|
function findValueForMixContrast(options) {
|
|
774
745
|
const { preferredValue, baseLinearRgb, contrast: contrastInput, luminanceAtValue, epsilon = 1e-4, maxIterations = 20 } = options;
|
|
775
746
|
const target = resolveMinContrast(contrastInput);
|
|
776
|
-
const searchTarget = target
|
|
777
|
-
const yBase = gamutClampedLuminance
|
|
747
|
+
const searchTarget = target * 1.005;
|
|
748
|
+
const yBase = gamutClampedLuminance(baseLinearRgb);
|
|
778
749
|
const crPref = contrastRatioFromLuminance(luminanceAtValue(preferredValue), yBase);
|
|
779
750
|
if (crPref >= searchTarget) return {
|
|
780
751
|
value: preferredValue,
|
|
@@ -1145,12 +1116,6 @@ function resolveShadowForScheme(def, ctx, isDark, isHighContrast) {
|
|
|
1145
1116
|
function variantToLinearRgb(v) {
|
|
1146
1117
|
return okhslToLinearSrgb(v.h, v.s, v.l);
|
|
1147
1118
|
}
|
|
1148
|
-
function gamutClampedLuminance(linearRgb) {
|
|
1149
|
-
const r = sRGBGammaToLinear(Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[0]))));
|
|
1150
|
-
const g = sRGBGammaToLinear(Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[1]))));
|
|
1151
|
-
const b = sRGBGammaToLinear(Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[2]))));
|
|
1152
|
-
return .2126 * r + .7152 * g + .0722 * b;
|
|
1153
|
-
}
|
|
1154
1119
|
/**
|
|
1155
1120
|
* Resolve hue for OKHSL mixing, handling achromatic colors.
|
|
1156
1121
|
* When one color has no saturation, its hue is meaningless —
|
|
@@ -1681,6 +1646,7 @@ exports.formatHsl = formatHsl;
|
|
|
1681
1646
|
exports.formatOkhsl = formatOkhsl;
|
|
1682
1647
|
exports.formatOklch = formatOklch;
|
|
1683
1648
|
exports.formatRgb = formatRgb;
|
|
1649
|
+
exports.gamutClampedLuminance = gamutClampedLuminance;
|
|
1684
1650
|
exports.glaze = glaze;
|
|
1685
1651
|
exports.okhslToLinearSrgb = okhslToLinearSrgb;
|
|
1686
1652
|
exports.okhslToOklab = okhslToOklab;
|