Skip to content

Commit d016fc3

Browse files
authored
css-calc: update random() (#1567)
1 parent e3fa230 commit d016fc3

23 files changed

+90
-42
lines changed

packages/color-helpers/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes to Color Helpers
22

3+
### Unreleased (patch)
4+
5+
- Use `Number.isNaN` instead of `NaN` for consistency.
6+
37
### 5.0.1
48

59
_August 14, 2024_

packages/color-helpers/dist/index.cjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ function lin_sRGB(t){return[lin_sRGB_channel(t[0]),lin_sRGB_channel(t[1]),lin_sR
239239
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/utilities.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
240240
*
241241
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/better-rgbToHsl.js
242-
*/function sRGB_to_HSL(t){const n=t[0],_=t[1],o=t[2],e=Math.max(n,_,o),r=Math.min(n,_,o),a=(r+e)/2,i=e-r;let l=NaN,s=0;if(0!==Math.round(1e5*i)){const t=Math.round(1e5*a);switch(s=0===t||1e5===t?0:(e-a)/Math.min(a,1-a),e){case n:l=(_-o)/i+(_<o?6:0);break;case _:l=(o-n)/i+2;break;case o:l=(n-_)/i+4}l*=60}return s<0&&(l+=180,s=Math.abs(s)),l>=360&&(l-=360),[l,100*s,100*a]}function sRGB_to_Hue(t){const n=t[0],_=t[1],o=t[2],e=Math.max(n,_,o);let r=NaN;const a=e-Math.min(n,_,o);if(0!==a){switch(e){case n:r=(_-o)/a+(_<o?6:0);break;case _:r=(o-n)/a+2;break;case o:r=(n-_)/a+4}r*=60}return r>=360&&(r-=360),r}function inGamut(t){return t[0]>=-1e-4&&t[0]<=1.0001&&t[1]>=-1e-4&&t[1]<=1.0001&&t[2]>=-1e-4&&t[2]<=1.0001}function clip(t){return[t[0]<0?0:t[0]>1?1:t[0],t[1]<0?0:t[1]>1?1:t[1],t[2]<0?0:t[2]>1?1:t[2]]}
242+
*/function sRGB_to_HSL(t){const n=t[0],_=t[1],o=t[2],e=Math.max(n,_,o),r=Math.min(n,_,o),a=(r+e)/2,i=e-r;let l=Number.NaN,s=0;if(0!==Math.round(1e5*i)){const t=Math.round(1e5*a);switch(s=0===t||1e5===t?0:(e-a)/Math.min(a,1-a),e){case n:l=(_-o)/i+(_<o?6:0);break;case _:l=(o-n)/i+2;break;case o:l=(n-_)/i+4}l*=60}return s<0&&(l+=180,s=Math.abs(s)),l>=360&&(l-=360),[l,100*s,100*a]}function sRGB_to_Hue(t){const n=t[0],_=t[1],o=t[2],e=Math.max(n,_,o),r=Math.min(n,_,o);let a=Number.NaN;const i=e-r;if(0!==i){switch(e){case n:a=(_-o)/i+(_<o?6:0);break;case _:a=(o-n)/i+2;break;case o:a=(n-_)/i+4}a*=60}return a>=360&&(a-=360),a}function inGamut(t){return t[0]>=-1e-4&&t[0]<=1.0001&&t[1]>=-1e-4&&t[1]<=1.0001&&t[2]>=-1e-4&&t[2]<=1.0001}function clip(t){return[t[0]<0?0:t[0]>1?1:t[0],t[1]<0?0:t[1]>1?1:t[1],t[2]<0?0:t[2]>1?1:t[2]]}
243243
/**
244244
* @description Calculate deltaE OK which is the simple root sum of squares
245245
* @param {number[]} reference - Array of OKLab values: L as 0..1, a and b as -1..1

packages/color-helpers/dist/index.mjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ function XYZ_to_OKLab(t){const n=multiplyMatrices(l,t);return multiplyMatrices(i
113113
*
114114
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
115115
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
116-
*/const D=1.09929682680944,g=.018053968510807;function gam_2020_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _>g?n*(D*Math.pow(_,.45)-(D-1)):4.5*t}
116+
*/const D=1.09929682680944,b=.018053968510807;function gam_2020_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _>b?n*(D*Math.pow(_,.45)-(D-1)):4.5*t}
117117
/**
118118
* Convert an array of linear-light sRGB values in the range 0.0-1.0 to gamma corrected form
119119
* Extended transfer function:
@@ -138,7 +138,7 @@ function XYZ_to_OKLab(t){const n=multiplyMatrices(l,t);return multiplyMatrices(i
138138
*
139139
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
140140
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
141-
*/const b=1/512;function gam_ProPhoto_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _>=b?n*Math.pow(_,1/1.8):16*t}
141+
*/const g=1/512;function gam_ProPhoto_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _>=g?n*Math.pow(_,1/1.8):16*t}
142142
/**
143143
* Convert an array of linear-light a98-rgb in the range 0.0-1.0
144144
* to gamma corrected form. Negative values are also now accepted
@@ -239,7 +239,7 @@ function lin_sRGB(t){return[lin_sRGB_channel(t[0]),lin_sRGB_channel(t[1]),lin_sR
239239
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/utilities.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
240240
*
241241
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/better-rgbToHsl.js
242-
*/function sRGB_to_HSL(t){const n=t[0],_=t[1],o=t[2],e=Math.max(n,_,o),a=Math.min(n,_,o),r=(a+e)/2,l=e-a;let i=NaN,c=0;if(0!==Math.round(1e5*l)){const t=Math.round(1e5*r);switch(c=0===t||1e5===t?0:(e-r)/Math.min(r,1-r),e){case n:i=(_-o)/l+(_<o?6:0);break;case _:i=(o-n)/l+2;break;case o:i=(n-_)/l+4}i*=60}return c<0&&(i+=180,c=Math.abs(c)),i>=360&&(i-=360),[i,100*c,100*r]}function sRGB_to_Hue(t){const n=t[0],_=t[1],o=t[2],e=Math.max(n,_,o);let a=NaN;const r=e-Math.min(n,_,o);if(0!==r){switch(e){case n:a=(_-o)/r+(_<o?6:0);break;case _:a=(o-n)/r+2;break;case o:a=(n-_)/r+4}a*=60}return a>=360&&(a-=360),a}function sRGB_to_XYZ_D50(t){let n=t;return n=lin_sRGB(n),n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_sRGB(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n),n=gam_sRGB(n),n}function HSL_to_XYZ_D50(t){let n=t;return n=HSL_to_sRGB(n),n=lin_sRGB(n),n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_HSL(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n),n=gam_sRGB(n),n=sRGB_to_HSL(n),n}function HWB_to_XYZ_D50(t){let n=t;return n=HWB_to_sRGB(n),n=lin_sRGB(n),n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_HWB(t){let n=t;n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n);const _=gam_sRGB(n),o=Math.min(_[0],_[1],_[2]),e=1-Math.max(_[0],_[1],_[2]);return[sRGB_to_Hue(_),100*o,100*e]}function Lab_to_XYZ_D50(t){let n=t;return n=Lab_to_XYZ(n),n}function XYZ_D50_to_Lab(t){let n=t;return n=XYZ_to_Lab(n),n}function LCH_to_XYZ_D50(t){let n=t;return n=LCH_to_Lab(n),n=Lab_to_XYZ(n),n}function XYZ_D50_to_LCH(t){let n=t;return n=XYZ_to_Lab(n),n=Lab_to_LCH(n),n}function OKLab_to_XYZ_D50(t){let n=t;return n=OKLab_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_OKLab(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_OKLab(n),n}function OKLCH_to_XYZ_D50(t){let n=t;return n=OKLCH_to_OKLab(n),n=OKLab_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_OKLCH(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_OKLab(n),n=OKLab_to_OKLCH(n),n}function lin_sRGB_to_XYZ_D50(t){let n=t;return n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_lin_sRGB(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n),n}function a98_RGB_to_XYZ_D50(t){let n=t;
242+
*/function sRGB_to_HSL(t){const n=t[0],_=t[1],o=t[2],e=Math.max(n,_,o),a=Math.min(n,_,o),r=(a+e)/2,l=e-a;let i=Number.NaN,c=0;if(0!==Math.round(1e5*l)){const t=Math.round(1e5*r);switch(c=0===t||1e5===t?0:(e-r)/Math.min(r,1-r),e){case n:i=(_-o)/l+(_<o?6:0);break;case _:i=(o-n)/l+2;break;case o:i=(n-_)/l+4}i*=60}return c<0&&(i+=180,c=Math.abs(c)),i>=360&&(i-=360),[i,100*c,100*r]}function sRGB_to_Hue(t){const n=t[0],_=t[1],o=t[2],e=Math.max(n,_,o),a=Math.min(n,_,o);let r=Number.NaN;const l=e-a;if(0!==l){switch(e){case n:r=(_-o)/l+(_<o?6:0);break;case _:r=(o-n)/l+2;break;case o:r=(n-_)/l+4}r*=60}return r>=360&&(r-=360),r}function sRGB_to_XYZ_D50(t){let n=t;return n=lin_sRGB(n),n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_sRGB(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n),n=gam_sRGB(n),n}function HSL_to_XYZ_D50(t){let n=t;return n=HSL_to_sRGB(n),n=lin_sRGB(n),n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_HSL(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n),n=gam_sRGB(n),n=sRGB_to_HSL(n),n}function HWB_to_XYZ_D50(t){let n=t;return n=HWB_to_sRGB(n),n=lin_sRGB(n),n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_HWB(t){let n=t;n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n);const _=gam_sRGB(n),o=Math.min(_[0],_[1],_[2]),e=1-Math.max(_[0],_[1],_[2]);return[sRGB_to_Hue(_),100*o,100*e]}function Lab_to_XYZ_D50(t){let n=t;return n=Lab_to_XYZ(n),n}function XYZ_D50_to_Lab(t){let n=t;return n=XYZ_to_Lab(n),n}function LCH_to_XYZ_D50(t){let n=t;return n=LCH_to_Lab(n),n=Lab_to_XYZ(n),n}function XYZ_D50_to_LCH(t){let n=t;return n=XYZ_to_Lab(n),n=Lab_to_LCH(n),n}function OKLab_to_XYZ_D50(t){let n=t;return n=OKLab_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_OKLab(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_OKLab(n),n}function OKLCH_to_XYZ_D50(t){let n=t;return n=OKLCH_to_OKLab(n),n=OKLab_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_OKLCH(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_OKLab(n),n=OKLab_to_OKLCH(n),n}function lin_sRGB_to_XYZ_D50(t){let n=t;return n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_lin_sRGB(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n),n}function a98_RGB_to_XYZ_D50(t){let n=t;
243243
/**
244244
* Convert an array of a98-rgb values in the range 0.0 - 1.0
245245
* to linear light (un-companded) form. Negative values are also now accepted

packages/color-helpers/src/conversions/srgb-to-hsl.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export function sRGB_to_HSL(RGB: Color): Color {
2424
const light = (min + max) / 2;
2525
const d = max - min;
2626

27-
let hue = NaN;
27+
let hue = Number.NaN;
2828
let sat = 0;
2929

3030
if (Math.round(d * 100_000) !== 0) {

packages/color-helpers/src/conversions/srgb-to-hue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export function sRGB_to_Hue(x: Color): number {
77

88
const max = Math.max(red, green, blue);
99
const min = Math.min(red, green, blue);
10-
let hue = NaN;
10+
let hue = Number.NaN;
1111
const d = max - min;
1212

1313
if (d !== 0) {

packages/css-calc/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes to CSS Calc
22

3+
### Unreleased (patch)
4+
5+
- Update `random()` to correctly handle extremely large ranges or extremely tiny steps.
6+
37
### 2.1.1
48

59
_December 27, 2024_

packages/css-calc/dist/index.cjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

packages/css-calc/dist/index.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

packages/css-calc/src/functions/random.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ export function solveRandom(randomNode: FunctionNode, randomCachingOptions: stri
3131
result = Number.NaN;
3232
} else if (!Number.isFinite(bToken[4].value)) {
3333
result = Number.NaN;
34-
} else if (stepValueToken && (!Number.isFinite(stepValueToken[4].value) || stepValueToken[4].value <= 0)) {
34+
} else if (!Number.isFinite(bToken[4].value - aToken[4].value)) {
35+
result = Number.NaN;
36+
} else if (stepValueToken && !Number.isFinite(stepValueToken[4].value)) {
3537
result = aToken[4].value
3638
} else {
3739
const rnd = sfc32(
@@ -52,6 +54,15 @@ export function solveRandom(randomNode: FunctionNode, randomCachingOptions: stri
5254
[min, max] = [max, min];
5355
}
5456

57+
if (
58+
stepValueToken && (
59+
(stepValueToken[4].value <= 0) ||
60+
((Math.abs(min - max) / stepValueToken[4].value) > 10_000_000_000)
61+
)
62+
) {
63+
stepValueToken = null
64+
}
65+
5566
if (stepValueToken) {
5667
const delta = Math.abs(min - max);
5768
const randomValue = rnd();

packages/css-calc/test/additional/random.mjs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,12 @@ assert.strictEqual(
9393

9494
assert.strictEqual(
9595
calc('random(-10px, 20px, by -50px)'),
96-
'-10px',
96+
'13.45151px',
9797
);
9898

9999
assert.strictEqual(
100100
calc('random(-10px, 20px, by 0px)'),
101-
'-10px',
101+
'-1.86008px',
102102
);
103103

104104
assert.strictEqual(
@@ -140,3 +140,28 @@ assert.strictEqual(
140140
calc('random(0deg, 360deg)'),
141141
'173.25527deg',
142142
);
143+
144+
assert.strictEqual(
145+
calc('random(--foo, 10, 20, by -2)'),
146+
'17.30236',
147+
);
148+
149+
assert.strictEqual(
150+
calc('random(10, 20, by 0.00005)'), // Number of steps is small enough
151+
'18.7764',
152+
);
153+
154+
assert.strictEqual(
155+
calc('random(10, 20, by 0.000005)'), // Number of steps is small enough
156+
'15.882265',
157+
);
158+
159+
assert.strictEqual(
160+
calc('random(0, 1, by 0.00000000005)'), // Number of steps is too large
161+
'0.70517',
162+
);
163+
164+
assert.strictEqual(
165+
calc('random(0, 10000000, by 0.00000000005)'), // Number of steps is too large
166+
'8282240.00987',
167+
);

0 commit comments

Comments
 (0)