vireglass 3.1.1 → 3.2.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 +5 -1
- package/dist/dom.cjs +41 -16
- package/dist/dom.cjs.map +1 -1
- package/dist/dom.d.cts +6 -1
- package/dist/dom.d.ts +6 -1
- package/dist/dom.js +42 -18
- package/dist/dom.js.map +1 -1
- package/package.json +1 -1
- package/src/dom/displacement.ts +9 -2
- package/src/dom/index.ts +46 -16
package/dist/dom.d.cts
CHANGED
|
@@ -73,6 +73,11 @@ type DisplacementState = {
|
|
|
73
73
|
* caller that only ever had two does not have to change. */
|
|
74
74
|
morphs?: readonly MorphShape[];
|
|
75
75
|
};
|
|
76
|
+
/**
|
|
77
|
+
* The `feDisplacementMap` scale for these optics. The map's pixels are a fraction of it and do not
|
|
78
|
+
* depend on it, so a change of strength alone, such as appear, is this attribute and not a bake.
|
|
79
|
+
*/
|
|
80
|
+
declare function displacementScale(optics: VireGlassOptics, geometry: VireGlassGeometry): number;
|
|
76
81
|
/**
|
|
77
82
|
* The raw pixel buffer, with no canvas involved — the part actually worth unit-testing.
|
|
78
83
|
* `buildDisplacementMap` below is a thin DOM wrapper around this.
|
|
@@ -437,4 +442,4 @@ type GlassHandle = {
|
|
|
437
442
|
};
|
|
438
443
|
declare function attachGlass(el: HTMLElement, opts?: AttachGlassOptions): GlassHandle;
|
|
439
444
|
|
|
440
|
-
export { type AttachGlassOptions, type BodyBackdrop, type BodyLayer, type DisplacementMap, type DisplacementState, type EdgePaint, type GlassBody, type GlassGroupHandle, type GlassGroupOptions, type GlassHandle, type GlassMorph, type GroupEntry, type ProbeOptions, RIM_WIDTH_PX, type RenderStats, type RgbColor, type RimAmbient, type ScrollEdgeHandle, type ScrollEdgeOptions, type SpectralMap, ambientLuma, attachGlass, attachScrollEdge, bodyLayer, boxShadowCss, buildDisplacementMap, buildSpectralMap, cached, clearMapCache, compositeLayers, contrastRimCss, createGlassGroup, hasSpectralEdge, lightConicAngle, mapCacheSize, paintFor, parseColor, probeBackdrop, renderDisplacementPixels, renderSpectralPixels, renderStats, resetRenderStats, resetSupportCache, resolveBody, rimGradientCss, rimLineAlpha, rimLobe, rimStrength, shadowAlphaFrom, statsFromSamples, supportsBackdropFilter, supportsSvgBackdropFilter, systemAccessibility, watchAccessibility, withPresence };
|
|
445
|
+
export { type AttachGlassOptions, type BodyBackdrop, type BodyLayer, type DisplacementMap, type DisplacementState, type EdgePaint, type GlassBody, type GlassGroupHandle, type GlassGroupOptions, type GlassHandle, type GlassMorph, type GroupEntry, type ProbeOptions, RIM_WIDTH_PX, type RenderStats, type RgbColor, type RimAmbient, type ScrollEdgeHandle, type ScrollEdgeOptions, type SpectralMap, ambientLuma, attachGlass, attachScrollEdge, bodyLayer, boxShadowCss, buildDisplacementMap, buildSpectralMap, cached, clearMapCache, compositeLayers, contrastRimCss, createGlassGroup, displacementScale, hasSpectralEdge, lightConicAngle, mapCacheSize, paintFor, parseColor, probeBackdrop, renderDisplacementPixels, renderSpectralPixels, renderStats, resetRenderStats, resetSupportCache, resolveBody, rimGradientCss, rimLineAlpha, rimLobe, rimStrength, shadowAlphaFrom, statsFromSamples, supportsBackdropFilter, supportsSvgBackdropFilter, systemAccessibility, watchAccessibility, withPresence };
|
package/dist/dom.d.ts
CHANGED
|
@@ -73,6 +73,11 @@ type DisplacementState = {
|
|
|
73
73
|
* caller that only ever had two does not have to change. */
|
|
74
74
|
morphs?: readonly MorphShape[];
|
|
75
75
|
};
|
|
76
|
+
/**
|
|
77
|
+
* The `feDisplacementMap` scale for these optics. The map's pixels are a fraction of it and do not
|
|
78
|
+
* depend on it, so a change of strength alone, such as appear, is this attribute and not a bake.
|
|
79
|
+
*/
|
|
80
|
+
declare function displacementScale(optics: VireGlassOptics, geometry: VireGlassGeometry): number;
|
|
76
81
|
/**
|
|
77
82
|
* The raw pixel buffer, with no canvas involved — the part actually worth unit-testing.
|
|
78
83
|
* `buildDisplacementMap` below is a thin DOM wrapper around this.
|
|
@@ -437,4 +442,4 @@ type GlassHandle = {
|
|
|
437
442
|
};
|
|
438
443
|
declare function attachGlass(el: HTMLElement, opts?: AttachGlassOptions): GlassHandle;
|
|
439
444
|
|
|
440
|
-
export { type AttachGlassOptions, type BodyBackdrop, type BodyLayer, type DisplacementMap, type DisplacementState, type EdgePaint, type GlassBody, type GlassGroupHandle, type GlassGroupOptions, type GlassHandle, type GlassMorph, type GroupEntry, type ProbeOptions, RIM_WIDTH_PX, type RenderStats, type RgbColor, type RimAmbient, type ScrollEdgeHandle, type ScrollEdgeOptions, type SpectralMap, ambientLuma, attachGlass, attachScrollEdge, bodyLayer, boxShadowCss, buildDisplacementMap, buildSpectralMap, cached, clearMapCache, compositeLayers, contrastRimCss, createGlassGroup, hasSpectralEdge, lightConicAngle, mapCacheSize, paintFor, parseColor, probeBackdrop, renderDisplacementPixels, renderSpectralPixels, renderStats, resetRenderStats, resetSupportCache, resolveBody, rimGradientCss, rimLineAlpha, rimLobe, rimStrength, shadowAlphaFrom, statsFromSamples, supportsBackdropFilter, supportsSvgBackdropFilter, systemAccessibility, watchAccessibility, withPresence };
|
|
445
|
+
export { type AttachGlassOptions, type BodyBackdrop, type BodyLayer, type DisplacementMap, type DisplacementState, type EdgePaint, type GlassBody, type GlassGroupHandle, type GlassGroupOptions, type GlassHandle, type GlassMorph, type GroupEntry, type ProbeOptions, RIM_WIDTH_PX, type RenderStats, type RgbColor, type RimAmbient, type ScrollEdgeHandle, type ScrollEdgeOptions, type SpectralMap, ambientLuma, attachGlass, attachScrollEdge, bodyLayer, boxShadowCss, buildDisplacementMap, buildSpectralMap, cached, clearMapCache, compositeLayers, contrastRimCss, createGlassGroup, displacementScale, hasSpectralEdge, lightConicAngle, mapCacheSize, paintFor, parseColor, probeBackdrop, renderDisplacementPixels, renderSpectralPixels, renderStats, resetRenderStats, resetSupportCache, resolveBody, rimGradientCss, rimLineAlpha, rimLobe, rimStrength, shadowAlphaFrom, statsFromSamples, supportsBackdropFilter, supportsSvgBackdropFilter, systemAccessibility, watchAccessibility, withPresence };
|
package/dist/dom.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { shadowTint, NO_ACCESSIBILITY, createGroupState, createDeform, elasticAllowed, contrastRimLuma, concentricRadius, scrollEdgeStrength, scrollEdgeStyle, applyAppear, accentTone, accentAmount, applyGlassScale, GLASS_SCALE_DEFAULT, applyAccessibility, raiseIntoGlass } from './chunk-VLDD655U.js';
|
|
2
2
|
import { ambientFrom, shouldInkBeLight, INK_LIGHT, INK_DARK } from './chunk-JNRZNMJJ.js';
|
|
3
3
|
import { touchWarp, sceneDistance, sceneGradient, sdfRoundedRect, VIREGLASS_MATERIAL, REST_LIGHT, resolveOptics, refractionStrength } from './chunk-YAN2OK4H.js';
|
|
4
|
-
import { shadowOpacity,
|
|
4
|
+
import { shadowOpacity, thicknessDp, bevelDp, rimDp, shadowOpacityFrom, shadowReachDp, halfMinDp, MAX_STRETCH, roundedRectGeometry } from './chunk-Z4FKYY47.js';
|
|
5
5
|
import { LENS, BODY, RIM, TOUCH, SHADOW, SHADOW_GAP, MEDIUM, SCROLL_EDGE, BEVEL, SPECTRAL, DISPERSION } from './chunk-CPSIY2DZ.js';
|
|
6
6
|
|
|
7
7
|
// src/dom/displacement.ts
|
|
@@ -21,13 +21,15 @@ function bevelProfile(t) {
|
|
|
21
21
|
const raw = Math.min(t / Math.sqrt(Math.max(1 - t * t * BEVEL.sphere, BEVEL.floor)), BEVEL.slopeMax);
|
|
22
22
|
return raw / BEVEL.slopeMax;
|
|
23
23
|
}
|
|
24
|
+
function displacementScale(optics, geometry) {
|
|
25
|
+
return Math.min(optics.refraction * thicknessDp(geometry, optics) * SCALE_GAIN, MAX_SCALE);
|
|
26
|
+
}
|
|
24
27
|
function renderDisplacementPixels(optics, geometry, dpr, state = {}) {
|
|
25
28
|
const bevel = bevelDp(geometry, optics);
|
|
26
29
|
const density = mapDensity(geometry, bevel, dpr);
|
|
27
30
|
const width = Math.max(1, Math.round(geometry.width * density));
|
|
28
31
|
const height = Math.max(1, Math.round(geometry.height * density));
|
|
29
|
-
const
|
|
30
|
-
const scale = Math.min(rawScale, MAX_SCALE);
|
|
32
|
+
const scale = displacementScale(optics, geometry);
|
|
31
33
|
const smoothing = state.smoothing ?? 0;
|
|
32
34
|
const shapes = [state.morph, state.morph2, ...state.morphs ?? []];
|
|
33
35
|
const data = new Uint8ClampedArray(width * height * 4);
|
|
@@ -799,6 +801,9 @@ function getFilterHost(host) {
|
|
|
799
801
|
(host instanceof ShadowRoot ? host : host.body).appendChild(svg);
|
|
800
802
|
return svg;
|
|
801
803
|
}
|
|
804
|
+
function writeAttr(node, name, value) {
|
|
805
|
+
if (node.getAttribute(name) !== value) node.setAttribute(name, value);
|
|
806
|
+
}
|
|
802
807
|
function buildFilterElement(id, mapUrl, optics, scale, spectral) {
|
|
803
808
|
const filter = document.createElementNS(SVG_NS, "filter");
|
|
804
809
|
filter.setAttribute("id", id);
|
|
@@ -884,6 +889,7 @@ function withSpectral(filter, spectral) {
|
|
|
884
889
|
product.setAttribute("in2", "hue");
|
|
885
890
|
product.setAttribute("operator", "arithmetic");
|
|
886
891
|
product.setAttribute("k1", String(spectral.headroom));
|
|
892
|
+
product.setAttribute("data-vireglass-headroom", String(spectral.headroom));
|
|
887
893
|
product.setAttribute("k2", "0");
|
|
888
894
|
product.setAttribute("k3", "0");
|
|
889
895
|
product.setAttribute("k4", "0");
|
|
@@ -941,6 +947,7 @@ function attachGlass(el, opts = {}) {
|
|
|
941
947
|
let filterEl = null;
|
|
942
948
|
let destroyed = false;
|
|
943
949
|
let mapKey = "";
|
|
950
|
+
let shownGeometry = null;
|
|
944
951
|
let interim = false;
|
|
945
952
|
let settling = false;
|
|
946
953
|
let lastSample = null;
|
|
@@ -1003,31 +1010,46 @@ function attachGlass(el, opts = {}) {
|
|
|
1003
1010
|
settling = true;
|
|
1004
1011
|
apply();
|
|
1005
1012
|
}
|
|
1006
|
-
function retarget(f, map, hue) {
|
|
1013
|
+
function retarget(f, map, hue, geometry) {
|
|
1007
1014
|
const images = f.querySelectorAll("feImage");
|
|
1008
1015
|
images[0]?.setAttribute("href", map.url);
|
|
1009
1016
|
if (hue) images[1]?.setAttribute("href", hue.url);
|
|
1017
|
+
shownGeometry = geometry;
|
|
1018
|
+
present(f);
|
|
1019
|
+
}
|
|
1020
|
+
function present(f) {
|
|
1021
|
+
if (!shownGeometry) return;
|
|
1022
|
+
const o = optics();
|
|
1023
|
+
const scale = displacementScale(o, shownGeometry);
|
|
1010
1024
|
for (const pass of f.querySelectorAll("feDisplacementMap")) {
|
|
1011
1025
|
const ratio = Number(pass.getAttribute("data-vireglass-ratio") ?? 1);
|
|
1012
|
-
pass
|
|
1026
|
+
writeAttr(pass, "scale", String(scale * (Number.isFinite(ratio) ? ratio : 1)));
|
|
1027
|
+
}
|
|
1028
|
+
const frost = f.querySelector("feGaussianBlur");
|
|
1029
|
+
if (frost) writeAttr(frost, "stdDeviation", String(Math.max(o.blur, 0)));
|
|
1030
|
+
const hue = f.querySelector('feComposite[in2="hue"]');
|
|
1031
|
+
if (hue) {
|
|
1032
|
+
const headroom = Number(hue.getAttribute("data-vireglass-headroom") ?? 1);
|
|
1033
|
+
writeAttr(hue, "k1", String(headroom * appear));
|
|
1034
|
+
writeAttr(hue, "k2", String(1 - appear));
|
|
1013
1035
|
}
|
|
1014
1036
|
}
|
|
1015
1037
|
function requestInterimMap() {
|
|
1016
1038
|
if (!svgSupported || !filterEl || destroyed) return;
|
|
1017
1039
|
const geometry = opts.geometry ?? measureGeometry(el);
|
|
1018
1040
|
if (isEmpty(geometry)) return;
|
|
1019
|
-
const
|
|
1041
|
+
const full = settledOptics();
|
|
1020
1042
|
const key = interimKey(
|
|
1021
1043
|
geometry.width,
|
|
1022
1044
|
geometry.height,
|
|
1023
1045
|
geometry.cornerRadius,
|
|
1024
1046
|
JSON.stringify([morph?.smoothing, morph?.shape, morph?.shape2, morph?.shapes]),
|
|
1025
|
-
|
|
1047
|
+
`${full.refraction}:${full.refractionScale}:${full.bevelDp}`
|
|
1026
1048
|
);
|
|
1027
1049
|
let rec = interimMaps.get(key);
|
|
1028
1050
|
if (!rec) {
|
|
1029
1051
|
bump("reducedBakes");
|
|
1030
|
-
rec = { map: buildDisplacementMap(
|
|
1052
|
+
rec = { map: buildDisplacementMap(full, geometry, Math.min(1, devicePixelRatio()), morphState()), ready: false, geometry };
|
|
1031
1053
|
interimMaps.set(key, rec);
|
|
1032
1054
|
}
|
|
1033
1055
|
const mine = seq += 1;
|
|
@@ -1036,7 +1058,7 @@ function attachGlass(el, opts = {}) {
|
|
|
1036
1058
|
const show = () => {
|
|
1037
1059
|
if (destroyed || filterEl !== forFilter || mine <= shownSeq) return;
|
|
1038
1060
|
shownSeq = mine;
|
|
1039
|
-
retarget(forFilter, record.map, null);
|
|
1061
|
+
retarget(forFilter, record.map, null, record.geometry);
|
|
1040
1062
|
};
|
|
1041
1063
|
if (record.ready) {
|
|
1042
1064
|
show();
|
|
@@ -1058,17 +1080,18 @@ function attachGlass(el, opts = {}) {
|
|
|
1058
1080
|
wasLight = light;
|
|
1059
1081
|
const body = opts.body === false ? null : bodyCss(settledOptics(), sample, light ? 1 : 0, accent, appear);
|
|
1060
1082
|
if (svgSupported) {
|
|
1061
|
-
const
|
|
1083
|
+
const full = settledOptics();
|
|
1084
|
+
const key = `m${morphKey()}|${geometry.width}x${geometry.height}r${geometry.cornerRadius}@${devicePixelRatio()}:${full.refraction}:${full.refractionScale}:${full.bevelDp}:${full.blur}`;
|
|
1062
1085
|
if (interim && filterEl) ; else if (isEmpty(geometry)) ; else if (key !== mapKey || !filterEl) {
|
|
1063
1086
|
const map = cached(`d|${key}`, () => {
|
|
1064
1087
|
bump("fullBakes");
|
|
1065
|
-
return buildDisplacementMap(
|
|
1088
|
+
return buildDisplacementMap(full, geometry, devicePixelRatio(), morphState());
|
|
1066
1089
|
});
|
|
1067
|
-
const hue = hasSpectralEdge(
|
|
1090
|
+
const hue = hasSpectralEdge(full) ? cached(`h|${key}`, () => {
|
|
1068
1091
|
bump("fullBakes");
|
|
1069
|
-
return buildSpectralMap(
|
|
1092
|
+
return buildSpectralMap(full, geometry, devicePixelRatio());
|
|
1070
1093
|
}) : null;
|
|
1071
|
-
const signature = filterSignature(
|
|
1094
|
+
const signature = filterSignature(full.blur, full.ior, full.iorSpread, !!hue);
|
|
1072
1095
|
if (settling && filterEl?.getAttribute("data-vireglass-signature") === signature) {
|
|
1073
1096
|
settling = false;
|
|
1074
1097
|
const mine = seq += 1;
|
|
@@ -1077,21 +1100,23 @@ function attachGlass(el, opts = {}) {
|
|
|
1077
1100
|
void Promise.all([decoded(map.url), hue ? decoded(hue.url) : void 0]).then(() => {
|
|
1078
1101
|
if (destroyed || filterEl !== forFilter || mapKey !== forKey || mine <= shownSeq) return;
|
|
1079
1102
|
shownSeq = mine;
|
|
1080
|
-
retarget(forFilter, map, hue);
|
|
1103
|
+
retarget(forFilter, map, hue, geometry);
|
|
1081
1104
|
});
|
|
1082
1105
|
} else {
|
|
1083
1106
|
settling = false;
|
|
1084
1107
|
invalidate();
|
|
1085
1108
|
const defs = getFilterHost(host).querySelector("defs");
|
|
1086
|
-
const next = buildFilterElement(id, map.url,
|
|
1109
|
+
const next = buildFilterElement(id, map.url, full, map.scale, hue);
|
|
1087
1110
|
next.setAttribute("data-vireglass-signature", signature);
|
|
1088
1111
|
if (filterEl?.parentNode) defs.replaceChild(next, filterEl);
|
|
1089
1112
|
else defs.appendChild(next);
|
|
1090
1113
|
bump("filterSwaps");
|
|
1091
1114
|
filterEl = next;
|
|
1115
|
+
shownGeometry = geometry;
|
|
1092
1116
|
}
|
|
1093
1117
|
mapKey = key;
|
|
1094
1118
|
}
|
|
1119
|
+
if (filterEl) present(filterEl);
|
|
1095
1120
|
el.style.setProperty("backdrop-filter", `url(#${id})`);
|
|
1096
1121
|
el.style.setProperty("-webkit-backdrop-filter", `url(#${id})`);
|
|
1097
1122
|
} else {
|
|
@@ -1292,7 +1317,6 @@ function attachGlass(el, opts = {}) {
|
|
|
1292
1317
|
if (next === appear) return;
|
|
1293
1318
|
appear = next;
|
|
1294
1319
|
apply();
|
|
1295
|
-
if (interim) requestInterimMap();
|
|
1296
1320
|
},
|
|
1297
1321
|
setAccent(next) {
|
|
1298
1322
|
accent = next ?? void 0;
|
|
@@ -1342,6 +1366,6 @@ function attachGlass(el, opts = {}) {
|
|
|
1342
1366
|
return handle;
|
|
1343
1367
|
}
|
|
1344
1368
|
|
|
1345
|
-
export { RIM_WIDTH_PX, ambientLuma, attachGlass, attachScrollEdge, bodyLayer, boxShadowCss, buildDisplacementMap, buildSpectralMap, cached, clearMapCache, compositeLayers, contrastRimCss, createGlassGroup, hasSpectralEdge, lightConicAngle, mapCacheSize, paintFor, parseColor, probeBackdrop, renderDisplacementPixels, renderSpectralPixels, renderStats, resetRenderStats, resetSupportCache, resolveBody, rimGradientCss, rimLineAlpha, rimLobe, rimStrength, shadowAlphaFrom, statsFromSamples, supportsBackdropFilter, supportsSvgBackdropFilter, systemAccessibility, watchAccessibility, withPresence };
|
|
1369
|
+
export { RIM_WIDTH_PX, ambientLuma, attachGlass, attachScrollEdge, bodyLayer, boxShadowCss, buildDisplacementMap, buildSpectralMap, cached, clearMapCache, compositeLayers, contrastRimCss, createGlassGroup, displacementScale, hasSpectralEdge, lightConicAngle, mapCacheSize, paintFor, parseColor, probeBackdrop, renderDisplacementPixels, renderSpectralPixels, renderStats, resetRenderStats, resetSupportCache, resolveBody, rimGradientCss, rimLineAlpha, rimLobe, rimStrength, shadowAlphaFrom, statsFromSamples, supportsBackdropFilter, supportsSvgBackdropFilter, systemAccessibility, watchAccessibility, withPresence };
|
|
1346
1370
|
//# sourceMappingURL=dom.js.map
|
|
1347
1371
|
//# sourceMappingURL=dom.js.map
|