vireglass 2.3.0 → 3.0.0
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/README.md +37 -6
- package/dist/{adapters-DugC6Qri.d.cts → adapters--bXcGvhW.d.cts} +5 -3
- package/dist/{adapters-BfeAopGO.d.ts → adapters-BlMhc6pI.d.ts} +5 -3
- package/dist/{chunk-MMPK6DCK.js → chunk-CPSIY2DZ.js} +58 -8
- package/dist/chunk-CPSIY2DZ.js.map +1 -0
- package/dist/{chunk-PM2SWCSF.js → chunk-RWUR3OV6.js} +26 -6
- package/dist/chunk-RWUR3OV6.js.map +1 -0
- package/dist/{chunk-CTTZNZFV.js → chunk-VLDD655U.js} +3 -3
- package/dist/{chunk-CTTZNZFV.js.map → chunk-VLDD655U.js.map} +1 -1
- package/dist/{chunk-H5QTBF67.js → chunk-YAN2OK4H.js} +31 -38
- package/dist/chunk-YAN2OK4H.js.map +1 -0
- package/dist/{chunk-SLRPHDV7.js → chunk-Z4FKYY47.js} +3 -3
- package/dist/{chunk-SLRPHDV7.js.map → chunk-Z4FKYY47.js.map} +1 -1
- package/dist/dom.cjs +180 -55
- package/dist/dom.cjs.map +1 -1
- package/dist/dom.d.cts +72 -25
- package/dist/dom.d.ts +72 -25
- package/dist/dom.js +116 -54
- package/dist/dom.js.map +1 -1
- package/dist/{geometry-RhKd7CM5.d.cts → geometry-ip9WSlZv.d.cts} +1 -1
- package/dist/{geometry-GvXtt-_S.d.ts → geometry-pabkYV7w.d.ts} +1 -1
- package/dist/{group-model-z4N27qsC.d.ts → group-model-CQiI5cCe.d.ts} +1 -1
- package/dist/{group-model-DwtixGhG.d.cts → group-model-DX2_W9J_.d.cts} +1 -1
- package/dist/index.cjs +114 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -8
- package/dist/index.d.ts +13 -8
- package/dist/index.js +5 -5
- package/dist/law.cjs +56 -6
- package/dist/law.cjs.map +1 -1
- package/dist/law.d.cts +54 -4
- package/dist/law.d.ts +54 -4
- package/dist/law.js +1 -1
- package/dist/{material-CnUmdKg1.d.ts → material-D9m1EN47.d.cts} +9 -6
- package/dist/{material-CnUmdKg1.d.cts → material-D9m1EN47.d.ts} +9 -6
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/reference.d.cts +2 -2
- package/dist/reference.d.ts +2 -2
- package/dist/reference.js +2 -2
- package/dist/web/index.cjs +112 -40
- package/dist/web/index.cjs.map +1 -1
- package/dist/web/index.d.cts +3 -3
- package/dist/web/index.d.ts +3 -3
- package/dist/web/index.js +4 -4
- package/docs/dom.md +49 -3
- package/docs/law.md +1 -1
- package/package.json +1 -1
- package/src/adapters.ts +3 -1
- package/src/dom/body.ts +93 -39
- package/src/dom/index.ts +49 -20
- package/src/dom/probe.ts +1 -1
- package/src/dom/rim.ts +63 -28
- package/src/dom/style-hold.ts +8 -0
- package/src/law.ts +54 -4
- package/src/lens-shader.ts +26 -33
- package/src/material.ts +10 -7
- package/src/targets/glsl.ts +27 -2
- package/dist/chunk-H5QTBF67.js.map +0 -1
- package/dist/chunk-MMPK6DCK.js.map +0 -1
- package/dist/chunk-PM2SWCSF.js.map +0 -1
package/dist/dom.cjs
CHANGED
|
@@ -41,7 +41,41 @@ var RIM = {
|
|
|
41
41
|
*/
|
|
42
42
|
darkEdge: 0.22,
|
|
43
43
|
/** Width of the hairline, CSS px. "About a point, not a band and not a bevel" (§2). */
|
|
44
|
-
widthPx: 1
|
|
44
|
+
widthPx: 1,
|
|
45
|
+
/**
|
|
46
|
+
* How strongly the line is drawn, by the lightness around the element. The rim is a reflection
|
|
47
|
+
* of the surroundings, so it is faint over a dark one and plain over a bright one, not white at
|
|
48
|
+
* full strength everywhere (§2, §6).
|
|
49
|
+
*
|
|
50
|
+
* MEASURED off the controls of A 2:17 (over dark video), M 2:52 (over sky) and A 2:18 (over
|
|
51
|
+
* grass), as the brightest rim bin's OKLab lightness over the surround's: 0.24 to 0.27 over dark,
|
|
52
|
+
* 0.25 over sky, 0.37 over grass. Through the DOM path onto the same backdrops these land within
|
|
53
|
+
* 0.08 of the smooth rows (docs/dom.md); a line white at full strength reads 0.70 to 0.80 over the
|
|
54
|
+
* dark frames.
|
|
55
|
+
*/
|
|
56
|
+
strengthDark: 0.37,
|
|
57
|
+
strengthLight: 0.95,
|
|
58
|
+
/**
|
|
59
|
+
* The surround lightness between which the strength moves from one to the other. UNMEASURED: the
|
|
60
|
+
* two ends are, and the controls in between were not looked for.
|
|
61
|
+
*/
|
|
62
|
+
ambientFrom: 0.15,
|
|
63
|
+
ambientTo: 0.45,
|
|
64
|
+
/**
|
|
65
|
+
* The share of the peak that the line keeps along the whole contour, away from the key light.
|
|
66
|
+
* MEASURED: the reference line goes all the way round. Its dimmest bin sits 0.06 to 0.12 of
|
|
67
|
+
* lightness over the surround on the dark frames, against a peak of 0.24 to 0.27 (A 2:17).
|
|
68
|
+
*/
|
|
69
|
+
contour: 0.3,
|
|
70
|
+
/** How far the line's colour is lifted from the surroundings' toward white. UNMEASURED: the
|
|
71
|
+
* lens always had 0.75 here, and this is that figure with a name. */
|
|
72
|
+
whiteShare: 0.75,
|
|
73
|
+
/**
|
|
74
|
+
* The reflectance (`fresnelStrength`) at which the line is drawn at the strengths above: that
|
|
75
|
+
* of ordinary glass, index 1.5. A denser medium does not draw it brighter than they say; a
|
|
76
|
+
* thinner one draws it fainter. UNMEASURED.
|
|
77
|
+
*/
|
|
78
|
+
reflectanceRef: 0.7
|
|
45
79
|
};
|
|
46
80
|
var BODY = {
|
|
47
81
|
/** Lightness ceiling for the body when legibility is loose. */
|
|
@@ -55,10 +89,14 @@ var BODY = {
|
|
|
55
89
|
busyEdge: 0.75,
|
|
56
90
|
/** Fine texture the body has to stop being a window for. */
|
|
57
91
|
groundSpan: 0.06,
|
|
58
|
-
/**
|
|
59
|
-
*
|
|
60
|
-
|
|
61
|
-
|
|
92
|
+
/**
|
|
93
|
+
* The spread under the element at which the ink's legibility requirement starts to bind, and the
|
|
94
|
+
* spread where it binds fully. Over a flat backdrop polarity flips before the ink drowns, so
|
|
95
|
+
* the body does not darken under a light glyph there; over texture it does. UNMEASURED: the
|
|
96
|
+
* reference shows a lighter body under a white glyph over sky, nothing about texture.
|
|
97
|
+
*/
|
|
98
|
+
inkBusyFrom: 0.02,
|
|
99
|
+
inkBusyTo: 0.12,
|
|
62
100
|
/** Ceiling on any single demand, so one requirement cannot make the glass opaque on its own. */
|
|
63
101
|
maxDemand: 0.92,
|
|
64
102
|
/**
|
|
@@ -67,7 +105,13 @@ var BODY = {
|
|
|
67
105
|
* separation is the ceiling, and glass at `maxDemand` has stopped being a window. Better to
|
|
68
106
|
* separate as far as transparency allows and no further. UNMEASURED.
|
|
69
107
|
*/
|
|
70
|
-
presenceDemand: 0.5
|
|
108
|
+
presenceDemand: 0.5,
|
|
109
|
+
/**
|
|
110
|
+
* The density at which the body is wholly the ink's own pole. Between `presenceDemand` and this
|
|
111
|
+
* the body moves from the light a thin body carries to the pole: a density no presence floor
|
|
112
|
+
* reaches is one the ink's legibility, or a system setting, has asked for. UNMEASURED.
|
|
113
|
+
*/
|
|
114
|
+
inkPoleTo: 0.8
|
|
71
115
|
};
|
|
72
116
|
var SHADOW = {
|
|
73
117
|
/**
|
|
@@ -135,6 +179,21 @@ var BEVEL = {
|
|
|
135
179
|
slopeMax: 3.2
|
|
136
180
|
};
|
|
137
181
|
var EPSILON = 1e-5;
|
|
182
|
+
var MEDIUM = {
|
|
183
|
+
/** The lightness content under the glass is pulled toward, and how hard. The medium both removes
|
|
184
|
+
* light and mixes scattered light back in: over a light backdrop the body darkens, over a dark
|
|
185
|
+
* one it lightens. A layer that only ADDED light pushed the body the wrong way over light
|
|
186
|
+
* backdrops (M 2:35). */
|
|
187
|
+
luma: 0.4,
|
|
188
|
+
pull: 0.07,
|
|
189
|
+
/** Ambient light reaching the body on top of that pull. */
|
|
190
|
+
ambientSpill: 0.01,
|
|
191
|
+
/** Glass concentrates light: the body is a touch lighter than what lies beneath it (M 2:29). */
|
|
192
|
+
concentrate: 0.01,
|
|
193
|
+
/** Scattered light on a frosted element is an ADDITION over the backdrop, not a fraction of the
|
|
194
|
+
* way to the tint — a fraction goes to zero once the backdrop reaches the tint's lightness and
|
|
195
|
+
* darkens past it (docs/benchmarks.md). */
|
|
196
|
+
matteLift: 0.1};
|
|
138
197
|
var LENS = {
|
|
139
198
|
/** Same reason, for the profile's slope. */
|
|
140
199
|
slopeMax: 40,
|
|
@@ -1028,8 +1087,10 @@ var {
|
|
|
1028
1087
|
tintLight: TINT_LIGHT,
|
|
1029
1088
|
groundSpan: GROUND_SPAN,
|
|
1030
1089
|
busyEdge: BUSY_EDGE,
|
|
1031
|
-
|
|
1032
|
-
|
|
1090
|
+
inkBusyFrom: INK_BUSY_FROM,
|
|
1091
|
+
inkBusyTo: INK_BUSY_TO,
|
|
1092
|
+
inkPoleTo: INK_POLE_TO,
|
|
1093
|
+
presenceDemand: PRESENCE_DEMAND,
|
|
1033
1094
|
maxDemand: MAX_DEMAND
|
|
1034
1095
|
} = BODY;
|
|
1035
1096
|
var clamp3 = (v, lo, hi) => v < lo ? lo : v > hi ? hi : v;
|
|
@@ -1038,6 +1099,10 @@ function smoothstep2(edge0, edge1, x) {
|
|
|
1038
1099
|
const t = clamp3((x - edge0) / (edge1 - edge0), 0, 1);
|
|
1039
1100
|
return t * t * (3 - 2 * t);
|
|
1040
1101
|
}
|
|
1102
|
+
function tintFor(density, need, pole) {
|
|
1103
|
+
const asked = Math.max(clamp3(need / Math.max(density, 1e-4), 0, 1), smoothstep2(PRESENCE_DEMAND, INK_POLE_TO, density));
|
|
1104
|
+
return mix(TINT_LIGHT, pole, asked);
|
|
1105
|
+
}
|
|
1041
1106
|
function resolveBody(optics, sample, ink) {
|
|
1042
1107
|
const strict = clamp3(optics.legibility * 2, 0, 1);
|
|
1043
1108
|
const capLight = mix(BODY_CAP_LOOSE, BODY_CAP_TIGHT, strict);
|
|
@@ -1046,33 +1111,45 @@ function resolveBody(optics, sample, ink) {
|
|
|
1046
1111
|
const demand = clamp3(optics.legibility * 4, 0, 1);
|
|
1047
1112
|
const mean = clamp3(sample.luma, 0, 1);
|
|
1048
1113
|
const busy = Math.max(sample.busy, 0);
|
|
1049
|
-
const
|
|
1050
|
-
const away = mix(TINT_LIGHT, TINT_DARK, darkSide);
|
|
1051
|
-
const tintLuma = mix(away, mix(TINT_LIGHT, TINT_DARK, pol), demand);
|
|
1114
|
+
const pole = mix(TINT_LIGHT, TINT_DARK, pol);
|
|
1052
1115
|
const edge = busy * BUSY_EDGE;
|
|
1053
1116
|
const inkHi = Math.min(mean + edge, 1);
|
|
1054
1117
|
const inkLo = Math.max(mean - edge, 0);
|
|
1055
1118
|
const needForLight = inkHi > capLight ? clamp3((inkHi - capLight) / Math.max(inkHi - TINT_DARK, 1e-4), 0, MAX_DEMAND) : 0;
|
|
1056
1119
|
const needForDark = inkLo < floorDark ? clamp3((floorDark - inkLo) / Math.max(TINT_LIGHT - inkLo, 1e-4), 0, MAX_DEMAND) : 0;
|
|
1057
|
-
const
|
|
1120
|
+
const structured = smoothstep2(INK_BUSY_FROM, INK_BUSY_TO, busy);
|
|
1121
|
+
const needForInk = mix(needForDark, needForLight, pol) * demand * structured;
|
|
1058
1122
|
const ground = busy * optics.legibility * GROUND_SPAN;
|
|
1059
|
-
|
|
1123
|
+
const density = Math.max(Math.max(optics.bodyDensity, ground), needForInk);
|
|
1124
|
+
return { density, tintLuma: tintFor(density, needForInk, pole), need: needForInk, pole };
|
|
1060
1125
|
}
|
|
1061
|
-
function withPresence(body, optics,
|
|
1126
|
+
function withPresence(body, optics, _sample) {
|
|
1062
1127
|
if (optics.presence <= 0) return body;
|
|
1063
|
-
const
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
const
|
|
1068
|
-
if (
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1128
|
+
const density = Math.max(body.density, Math.min(optics.presence / TINT_LIGHT, PRESENCE_DEMAND));
|
|
1129
|
+
return { ...body, density, tintLuma: tintFor(density, body.need, body.pole) };
|
|
1130
|
+
}
|
|
1131
|
+
function hueOf(c) {
|
|
1132
|
+
const l = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
|
|
1133
|
+
if (l < 0.02) return [1, 1, 1];
|
|
1134
|
+
return [clamp3(c[0] / l, 0, 2), clamp3(c[1] / l, 0, 2), clamp3(c[2] / l, 0, 2)];
|
|
1135
|
+
}
|
|
1136
|
+
function bodyLayer(optics, sample, ink, ambient, appear = 1) {
|
|
1137
|
+
const a = clamp3(appear, 0, 1);
|
|
1138
|
+
const body = withPresence(resolveBody(optics, sample, ink), optics);
|
|
1139
|
+
const hue = hueOf(ambient);
|
|
1140
|
+
const pickup = clamp3(optics.colorPickup, 0, 1);
|
|
1141
|
+
const density = clamp3(body.density * a, 0, 1);
|
|
1142
|
+
const matte = optics.legibility * MEDIUM.matteLift * a;
|
|
1143
|
+
const pull = MEDIUM.pull * a;
|
|
1144
|
+
const spill = optics.edgeLight * MEDIUM.ambientSpill * a;
|
|
1145
|
+
const lift = MEDIUM.concentrate * a;
|
|
1146
|
+
const alpha = 1 - (1 - lift) * (1 - pull) * (1 - density);
|
|
1147
|
+
const channel = (i) => {
|
|
1148
|
+
const tintHue = mix(1, hue[i], pickup);
|
|
1149
|
+
const added = (1 - pull) * (density * tintHue * body.tintLuma + matte * tintHue) + pull * hue[i] * MEDIUM.luma + ambient[i] * spill;
|
|
1150
|
+
return alpha > 1e-6 ? clamp3(((1 - lift) * added + lift) / alpha, 0, 1) : 0;
|
|
1075
1151
|
};
|
|
1152
|
+
return { r: channel(0), g: channel(1), b: channel(2), alpha };
|
|
1076
1153
|
}
|
|
1077
1154
|
|
|
1078
1155
|
// src/accessibility.ts
|
|
@@ -1202,7 +1279,14 @@ function concentricRadius(outerRadius, inset, minimum = 0) {
|
|
|
1202
1279
|
}
|
|
1203
1280
|
|
|
1204
1281
|
// src/dom/rim.ts
|
|
1205
|
-
var {
|
|
1282
|
+
var {
|
|
1283
|
+
lobeExponent: LOBE_EXPONENT,
|
|
1284
|
+
opposingArc: OPPOSING_ARC,
|
|
1285
|
+
darkEdge: DARK_EDGE,
|
|
1286
|
+
contour: CONTOUR,
|
|
1287
|
+
whiteShare: WHITE_SHARE,
|
|
1288
|
+
reflectanceRef: REFLECTANCE_REF
|
|
1289
|
+
} = RIM;
|
|
1206
1290
|
var STOPS = 48;
|
|
1207
1291
|
function lightConicAngle(light) {
|
|
1208
1292
|
const [lx, ly] = light;
|
|
@@ -1217,25 +1301,41 @@ function rimLobe(deltaDeg, specular) {
|
|
|
1217
1301
|
}
|
|
1218
1302
|
var clamp016 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
|
|
1219
1303
|
var to2552 = (v) => Math.round(clamp016(v) * 255);
|
|
1304
|
+
var mixTo = (a, b, t) => a + (b - a) * t;
|
|
1305
|
+
function smoothstep3(edge0, edge1, x) {
|
|
1306
|
+
const t = clamp016((x - edge0) / (edge1 - edge0));
|
|
1307
|
+
return t * t * (3 - 2 * t);
|
|
1308
|
+
}
|
|
1309
|
+
function ambientLuma(ambient) {
|
|
1310
|
+
return 0.2126 * ambient[0] + 0.7152 * ambient[1] + 0.0722 * ambient[2];
|
|
1311
|
+
}
|
|
1312
|
+
function rimStrength(luma3) {
|
|
1313
|
+
return mixTo(RIM.strengthDark, RIM.strengthLight, smoothstep3(RIM.ambientFrom, RIM.ambientTo, luma3));
|
|
1314
|
+
}
|
|
1315
|
+
function rimLineAlpha(deltaDeg, optics, luma3) {
|
|
1316
|
+
const reflect = Math.min(optics.fresnel / REFLECTANCE_REF, 1);
|
|
1317
|
+
const damping = optics.fresnel > 0 ? optics.specular / optics.fresnel : 0;
|
|
1318
|
+
const lobe = rimLobe(deltaDeg, damping);
|
|
1319
|
+
return clamp016(rimStrength(luma3) * reflect * (CONTOUR + (1 - CONTOUR) * lobe));
|
|
1320
|
+
}
|
|
1220
1321
|
function rimGradientCss(optics, ambient, light, appear = 1) {
|
|
1221
1322
|
const present = clamp016(appear);
|
|
1222
1323
|
const start = lightConicAngle(light);
|
|
1223
1324
|
const [ar, ag, ab] = ambient;
|
|
1224
|
-
const
|
|
1325
|
+
const luma3 = ambientLuma(ambient);
|
|
1326
|
+
const line = [];
|
|
1225
1327
|
for (let i = 0; i <= STOPS; i += 1) {
|
|
1226
1328
|
const angle = i / STOPS * 360;
|
|
1227
|
-
const key = rimLobe(angle, optics.specular);
|
|
1228
1329
|
const facing = Math.cos(angle * Math.PI / 180);
|
|
1229
1330
|
const fringe = facing < 0 ? optics.iridescence * OPPOSING_ARC : 0;
|
|
1230
|
-
const
|
|
1231
|
-
const
|
|
1232
|
-
const
|
|
1233
|
-
const
|
|
1234
|
-
|
|
1235
|
-
const colour = lift > 1e-3 ? `rgba(${to2552(r)},${to2552(g)},${to2552(b)},${alpha.toFixed(3)})` : `rgba(0,0,0,${alpha.toFixed(3)})`;
|
|
1236
|
-
stops.push(`${colour} ${angle.toFixed(1)}deg`);
|
|
1331
|
+
const r = ar + (1 - ar) * clamp016(WHITE_SHARE + fringe);
|
|
1332
|
+
const g = ag + (1 - ag) * WHITE_SHARE;
|
|
1333
|
+
const b = ab + (1 - ab) * clamp016(WHITE_SHARE - fringe);
|
|
1334
|
+
const alpha = rimLineAlpha(angle, optics, luma3) * present;
|
|
1335
|
+
line.push(`rgba(${to2552(r)},${to2552(g)},${to2552(b)},${alpha.toFixed(3)}) ${angle.toFixed(1)}deg`);
|
|
1237
1336
|
}
|
|
1238
|
-
|
|
1337
|
+
const dark = `rgba(0,0,0,${(DARK_EDGE * present).toFixed(3)})`;
|
|
1338
|
+
return `conic-gradient(from ${start.toFixed(1)}deg, ${line.join(", ")}), conic-gradient(${dark} 0deg, ${dark} 360deg)`;
|
|
1239
1339
|
}
|
|
1240
1340
|
var RIM_WIDTH_PX = RIM.widthPx;
|
|
1241
1341
|
function contrastRimCss(bodyLuma, rimLuma) {
|
|
@@ -1256,6 +1356,15 @@ function warnIfNested(el) {
|
|
|
1256
1356
|
`vireglass: glass inside glass \u2014 this element is a descendant of <${where}>, which is also glass. Its backdrop is the outer element's output, so the refraction is applied twice and the blurs multiply. Put the glass on one of the two.`
|
|
1257
1357
|
);
|
|
1258
1358
|
}
|
|
1359
|
+
|
|
1360
|
+
// src/dom/style-hold.ts
|
|
1361
|
+
function holdProperty(style, name) {
|
|
1362
|
+
const saved = style.getPropertyValue(name);
|
|
1363
|
+
return () => {
|
|
1364
|
+
if (saved) style.setProperty(name, saved);
|
|
1365
|
+
else style.removeProperty(name);
|
|
1366
|
+
};
|
|
1367
|
+
}
|
|
1259
1368
|
var REST_LIGHT = [-0.577, -0.817];
|
|
1260
1369
|
|
|
1261
1370
|
// src/touch-response.ts
|
|
@@ -1755,16 +1864,16 @@ var to2553 = (v) => Math.round(Math.min(Math.max(v, 0), 1) * 255);
|
|
|
1755
1864
|
function rgbCss(r, g, b) {
|
|
1756
1865
|
return `rgb(${to2553(r)} ${to2553(g)} ${to2553(b)})`;
|
|
1757
1866
|
}
|
|
1758
|
-
function bodyCss(optics, sample, ink, accent) {
|
|
1759
|
-
const body = withPresence(resolveBody(optics, sample, ink), optics, sample);
|
|
1867
|
+
function bodyCss(optics, sample, ink, accent, appear) {
|
|
1760
1868
|
if (accent) {
|
|
1761
|
-
const
|
|
1869
|
+
const settled = applyAppear(optics, appear);
|
|
1870
|
+
const body = withPresence(resolveBody(settled, sample, ink), settled);
|
|
1871
|
+
const [r, g, b] = accentTone(accent.color, sample.luma);
|
|
1762
1872
|
const amount = Math.max(accentAmount(accent), body.density);
|
|
1763
|
-
return `rgba(${to2553(
|
|
1873
|
+
return `rgba(${to2553(r)}, ${to2553(g)}, ${to2553(b)}, ${amount.toFixed(3)})`;
|
|
1764
1874
|
}
|
|
1765
|
-
const
|
|
1766
|
-
|
|
1767
|
-
return `rgba(${to2553(hue(r))}, ${to2553(hue(g))}, ${to2553(hue(b))}, ${body.density.toFixed(3)})`;
|
|
1875
|
+
const layer = bodyLayer(optics, sample, ink, ambientFrom(sample), appear);
|
|
1876
|
+
return `rgba(${to2553(layer.r)}, ${to2553(layer.g)}, ${to2553(layer.b)}, ${layer.alpha.toFixed(3)})`;
|
|
1768
1877
|
}
|
|
1769
1878
|
function attachGlass(el, opts = {}) {
|
|
1770
1879
|
if (typeof document === "undefined") {
|
|
@@ -1781,6 +1890,7 @@ function attachGlass(el, opts = {}) {
|
|
|
1781
1890
|
const onlyWhenTouched = opts.variant === "interactive";
|
|
1782
1891
|
let appear = onlyWhenTouched ? 0 : opts.appear ?? 1;
|
|
1783
1892
|
let accent = opts.accent;
|
|
1893
|
+
let supplied = opts.sample;
|
|
1784
1894
|
let a11y = systemAccessibility();
|
|
1785
1895
|
const stopWatchingA11y = watchAccessibility((next) => {
|
|
1786
1896
|
a11y = next;
|
|
@@ -1792,13 +1902,16 @@ function attachGlass(el, opts = {}) {
|
|
|
1792
1902
|
const host = hostFor(el);
|
|
1793
1903
|
ensureRimStyles(host);
|
|
1794
1904
|
el.setAttribute(GLASS_ATTR, "");
|
|
1905
|
+
const restoreBackground = holdProperty(el.style, "background-color");
|
|
1795
1906
|
const positionWasStatic = getComputedStyle(el).position === "static";
|
|
1796
1907
|
if (positionWasStatic) el.style.setProperty("position", "relative");
|
|
1797
|
-
function
|
|
1908
|
+
function settledOptics(patch) {
|
|
1798
1909
|
const base = resolveOptics(patch ?? opts.material);
|
|
1799
1910
|
const scaled = applyGlassScale(base, opts.scale ?? GLASS_SCALE_DEFAULT);
|
|
1800
|
-
|
|
1801
|
-
|
|
1911
|
+
return applyAccessibility(scaled, opts.accessibility ?? a11y);
|
|
1912
|
+
}
|
|
1913
|
+
function optics(patch) {
|
|
1914
|
+
return applyAppear(settledOptics(patch), appear);
|
|
1802
1915
|
}
|
|
1803
1916
|
function morphState() {
|
|
1804
1917
|
if (!morph) return {};
|
|
@@ -1813,7 +1926,10 @@ function attachGlass(el, opts = {}) {
|
|
|
1813
1926
|
if (destroyed) return;
|
|
1814
1927
|
const geometry = opts.geometry ?? measureGeometry(el);
|
|
1815
1928
|
const opticsNow = optics();
|
|
1816
|
-
const sample =
|
|
1929
|
+
const sample = supplied ?? probeBackdrop(el);
|
|
1930
|
+
const light = shouldInkBeLight(sample, wasLight);
|
|
1931
|
+
wasLight = light;
|
|
1932
|
+
const body = opts.body === false ? null : bodyCss(settledOptics(), sample, light ? 1 : 0, accent, appear);
|
|
1817
1933
|
if (svgSupported) {
|
|
1818
1934
|
const key = `a${appear.toFixed(3)}|m${morphKey()}|${geometry.width}x${geometry.height}r${geometry.cornerRadius}@${devicePixelRatio()}:${opticsNow.refraction}:${opticsNow.refractionScale}:${opticsNow.bevelDp}:${opticsNow.blur}`;
|
|
1819
1935
|
if (key !== mapKey || !filterEl) {
|
|
@@ -1831,10 +1947,8 @@ function attachGlass(el, opts = {}) {
|
|
|
1831
1947
|
} else {
|
|
1832
1948
|
el.style.setProperty("backdrop-filter", fallbackFilterCss(opticsNow));
|
|
1833
1949
|
el.style.setProperty("-webkit-backdrop-filter", fallbackFilterCss(opticsNow));
|
|
1834
|
-
el.style.backgroundColor = bodyCss(opticsNow, sample, wasLight ? 1 : 0, accent);
|
|
1835
1950
|
}
|
|
1836
|
-
|
|
1837
|
-
wasLight = light;
|
|
1951
|
+
if (body) el.style.backgroundColor = body;
|
|
1838
1952
|
const [tr, tg, tb] = ambientFrom(sample);
|
|
1839
1953
|
el.style.setProperty("--vireglass-ink", light ? "1" : "0");
|
|
1840
1954
|
el.style.setProperty("--vireglass-tint", `${tr} ${tg} ${tb}`);
|
|
@@ -1842,8 +1956,11 @@ function attachGlass(el, opts = {}) {
|
|
|
1842
1956
|
const inkLevel = Math.round((light ? INK_LIGHT : INK_DARK) * 255);
|
|
1843
1957
|
el.style.setProperty("--vireglass-ink-color", `rgb(${inkLevel} ${inkLevel} ${inkLevel})`);
|
|
1844
1958
|
el.style.setProperty("--vireglass-tint-color", rgbCss(tr, tg, tb));
|
|
1845
|
-
el.style.setProperty(
|
|
1846
|
-
|
|
1959
|
+
el.style.setProperty(
|
|
1960
|
+
"--vireglass-body-color",
|
|
1961
|
+
body ?? bodyCss(settledOptics(), sample, light ? 1 : 0, accent, appear)
|
|
1962
|
+
);
|
|
1963
|
+
const pole = withPresence(resolveBody(opticsNow, sample, light ? 1 : 0), opticsNow).tintLuma;
|
|
1847
1964
|
el.style.setProperty(
|
|
1848
1965
|
"--vireglass-rim",
|
|
1849
1966
|
(opts.accessibility ?? a11y).increaseContrast ? contrastRimCss(pole, contrastRimLuma(pole)) : rimGradientCss(opticsNow, [tr, tg, tb], opts.light ?? REST_LIGHT, appear)
|
|
@@ -1904,7 +2021,7 @@ function attachGlass(el, opts = {}) {
|
|
|
1904
2021
|
el.style.setProperty("--vireglass-glow-opacity", "0");
|
|
1905
2022
|
return;
|
|
1906
2023
|
}
|
|
1907
|
-
const [gr, gg, gb] = ambientFrom(
|
|
2024
|
+
const [gr, gg, gb] = ambientFrom(supplied ?? probeBackdrop(el));
|
|
1908
2025
|
const cx = (x + geometry.width / 2) / geometry.width * 100;
|
|
1909
2026
|
const cy = (y + geometry.height / 2) / geometry.height * 100;
|
|
1910
2027
|
const reach = halfMinDp(geometry) * TOUCH_RADIUS_FRACTION;
|
|
@@ -1994,7 +2111,7 @@ function attachGlass(el, opts = {}) {
|
|
|
1994
2111
|
mapKey = "";
|
|
1995
2112
|
el.style.removeProperty("backdrop-filter");
|
|
1996
2113
|
el.style.removeProperty("-webkit-backdrop-filter");
|
|
1997
|
-
|
|
2114
|
+
if (opts.body !== false) restoreBackground();
|
|
1998
2115
|
el.style.removeProperty("--vireglass-ink");
|
|
1999
2116
|
el.style.removeProperty("--vireglass-tint");
|
|
2000
2117
|
el.style.removeProperty("--vireglass-body-density");
|
|
@@ -2042,6 +2159,10 @@ function attachGlass(el, opts = {}) {
|
|
|
2042
2159
|
mapKey = "";
|
|
2043
2160
|
apply();
|
|
2044
2161
|
},
|
|
2162
|
+
setSample(next) {
|
|
2163
|
+
supplied = next ?? void 0;
|
|
2164
|
+
apply();
|
|
2165
|
+
},
|
|
2045
2166
|
destroy
|
|
2046
2167
|
};
|
|
2047
2168
|
attached.set(el, handle);
|
|
@@ -2049,8 +2170,10 @@ function attachGlass(el, opts = {}) {
|
|
|
2049
2170
|
}
|
|
2050
2171
|
|
|
2051
2172
|
exports.RIM_WIDTH_PX = RIM_WIDTH_PX;
|
|
2173
|
+
exports.ambientLuma = ambientLuma;
|
|
2052
2174
|
exports.attachGlass = attachGlass;
|
|
2053
2175
|
exports.attachScrollEdge = attachScrollEdge;
|
|
2176
|
+
exports.bodyLayer = bodyLayer;
|
|
2054
2177
|
exports.boxShadowCss = boxShadowCss;
|
|
2055
2178
|
exports.buildDisplacementMap = buildDisplacementMap;
|
|
2056
2179
|
exports.buildSpectralMap = buildSpectralMap;
|
|
@@ -2070,7 +2193,9 @@ exports.renderSpectralPixels = renderSpectralPixels;
|
|
|
2070
2193
|
exports.resetSupportCache = resetSupportCache;
|
|
2071
2194
|
exports.resolveBody = resolveBody;
|
|
2072
2195
|
exports.rimGradientCss = rimGradientCss;
|
|
2196
|
+
exports.rimLineAlpha = rimLineAlpha;
|
|
2073
2197
|
exports.rimLobe = rimLobe;
|
|
2198
|
+
exports.rimStrength = rimStrength;
|
|
2074
2199
|
exports.shadowAlphaFrom = shadowAlphaFrom;
|
|
2075
2200
|
exports.statsFromSamples = statsFromSamples;
|
|
2076
2201
|
exports.supportsBackdropFilter = supportsBackdropFilter;
|