stickyflow 0.6.0 → 0.8.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/binding/index.cjs +9 -9
  3. package/dist/binding/index.d.cts +4 -4
  4. package/dist/binding/index.d.ts +4 -4
  5. package/dist/binding/index.js +3 -3
  6. package/dist/{chunk-MFNUJA26.js → chunk-CZW3ARXQ.js} +156 -23
  7. package/dist/chunk-CZW3ARXQ.js.map +1 -0
  8. package/dist/{chunk-WRDVNMFS.js → chunk-EDOPENSE.js} +848 -38
  9. package/dist/chunk-EDOPENSE.js.map +1 -0
  10. package/dist/{chunk-4LENHH6C.cjs → chunk-FQ7GMLCM.cjs} +15 -15
  11. package/dist/{chunk-4LENHH6C.cjs.map → chunk-FQ7GMLCM.cjs.map} +1 -1
  12. package/dist/{chunk-4G2R7PEL.js → chunk-GLZVHUSW.js} +220 -12
  13. package/dist/chunk-GLZVHUSW.js.map +1 -0
  14. package/dist/{chunk-KTNCDNDB.cjs → chunk-IR2T47NW.cjs} +876 -66
  15. package/dist/chunk-IR2T47NW.cjs.map +1 -0
  16. package/dist/{chunk-ULQZ6CZW.js → chunk-LFEGZJWC.js} +3 -3
  17. package/dist/{chunk-ULQZ6CZW.js.map → chunk-LFEGZJWC.js.map} +1 -1
  18. package/dist/{chunk-XJ4W6TW4.cjs → chunk-LNW5VIEA.cjs} +225 -11
  19. package/dist/chunk-LNW5VIEA.cjs.map +1 -0
  20. package/dist/{chunk-FVHVOJS2.js → chunk-MAPNY7MJ.js} +872 -174
  21. package/dist/chunk-MAPNY7MJ.js.map +1 -0
  22. package/dist/{chunk-WQRT5PVT.cjs → chunk-VOYX6JMW.cjs} +1479 -780
  23. package/dist/chunk-VOYX6JMW.cjs.map +1 -0
  24. package/dist/{chunk-JIJMZMGY.cjs → chunk-XPM3E7NV.cjs} +170 -37
  25. package/dist/chunk-XPM3E7NV.cjs.map +1 -0
  26. package/dist/index.cjs +42 -34
  27. package/dist/index.d.cts +34 -6
  28. package/dist/index.d.ts +34 -6
  29. package/dist/index.js +5 -5
  30. package/dist/interaction/index.cjs +266 -235
  31. package/dist/interaction/index.cjs.map +1 -1
  32. package/dist/interaction/index.d.cts +2 -2
  33. package/dist/interaction/index.d.ts +2 -2
  34. package/dist/interaction/index.js +42 -11
  35. package/dist/interaction/index.js.map +1 -1
  36. package/dist/{render-Db0eSz_s.d.cts → render-Bp2FLEzv.d.cts} +14 -1
  37. package/dist/{render-Db0eSz_s.d.ts → render-Bp2FLEzv.d.ts} +14 -1
  38. package/dist/{runtime-n2yG-_j-.d.ts → runtime-CWIGxRcL.d.ts} +2 -2
  39. package/dist/{runtime-BhivvBeL.d.cts → runtime-DIag-XBa.d.cts} +2 -2
  40. package/dist/{runtimeTypes-DnI7mRF5.d.ts → runtimeTypes-BYODuxHk.d.cts} +2 -1
  41. package/dist/{runtimeTypes-CrkMHvVi.d.cts → runtimeTypes-C7sSLfOK.d.ts} +2 -1
  42. package/dist/stickyflow-diagram.global.js +490 -36
  43. package/dist/stickyflow-diagram.global.js.map +1 -1
  44. package/dist/{types-D4cH4f1a.d.ts → types-B9QM_H3R.d.ts} +1 -1
  45. package/dist/{types-BHfUKT4s.d.cts → types-D2w6D_wG.d.cts} +1 -1
  46. package/dist/viewer/index.cjs +9 -9
  47. package/dist/viewer/index.d.cts +5 -4
  48. package/dist/viewer/index.d.ts +5 -4
  49. package/dist/viewer/index.js +4 -4
  50. package/dist/web-component/index.cjs +6 -6
  51. package/dist/web-component/index.d.cts +2 -2
  52. package/dist/web-component/index.d.ts +2 -2
  53. package/dist/web-component/index.js +4 -4
  54. package/package.json +1 -1
  55. package/dist/chunk-4G2R7PEL.js.map +0 -1
  56. package/dist/chunk-FVHVOJS2.js.map +0 -1
  57. package/dist/chunk-JIJMZMGY.cjs.map +0 -1
  58. package/dist/chunk-KTNCDNDB.cjs.map +0 -1
  59. package/dist/chunk-MFNUJA26.js.map +0 -1
  60. package/dist/chunk-WQRT5PVT.cjs.map +0 -1
  61. package/dist/chunk-WRDVNMFS.js.map +0 -1
  62. package/dist/chunk-XJ4W6TW4.cjs.map +0 -1
@@ -1,6 +1,6 @@
1
- import { render } from './chunk-FVHVOJS2.js';
2
- import { parseContractVersion, isContractCompatible, Emitter, resolveOwner, CHANGE_COLOR, findOwnerNode, isPrimary, linkSelectionOverlay, pathSelectionOverlay, isometricSelectionOverlay, shapeSelectionOverlay, DERIVED_HEIGHT_ROLES, quickDuplicateBubbles, isCameraGesture, linkChangeOverlay, shapeChangeOverlay, startChangeFade, REDUCED_MOTION_DURATION_MS, FLASH_DURATION_MS } from './chunk-ULQZ6CZW.js';
3
- import { formatRollingNumber, DEFAULT_ROLLING_NUMBER_STYLE } from './chunk-4G2R7PEL.js';
1
+ import { render } from './chunk-MAPNY7MJ.js';
2
+ import { parseContractVersion, isContractCompatible, Emitter, resolveOwner, CHANGE_COLOR, findOwnerNode, isPrimary, linkSelectionOverlay, pathSelectionOverlay, isometricSelectionOverlay, shapeSelectionOverlay, DERIVED_HEIGHT_ROLES, quickDuplicateBubbles, isCameraGesture, linkChangeOverlay, shapeChangeOverlay, startChangeFade, REDUCED_MOTION_DURATION_MS, FLASH_DURATION_MS } from './chunk-LFEGZJWC.js';
3
+ import { getComponentDescriptor, formatRollingNumber, DEFAULT_ROLLING_NUMBER_STYLE } from './chunk-GLZVHUSW.js';
4
4
 
5
5
  // src/runtime/viewer/components/rollingNumberDom.ts
6
6
  var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
@@ -1765,10 +1765,136 @@ var glassRefractionProgram = {
1765
1765
  usesBackdrop: true
1766
1766
  };
1767
1767
 
1768
- // src/runtime/viewer/shaders/builtins/halftoneHalo.ts
1768
+ // src/runtime/viewer/shaders/builtins/glowCard.ts
1769
1769
  var fragmentSource8 = `
1770
1770
  precision highp float;
1771
1771
 
1772
+ uniform vec2 uResolution;
1773
+ uniform float uTime;
1774
+ uniform float uSpeed;
1775
+ uniform float uIntensity;
1776
+ uniform float uGlowHeight;
1777
+ uniform float uGlowSpread;
1778
+ uniform float uCore;
1779
+ uniform float uRim;
1780
+ uniform float uGrain;
1781
+ uniform float uWarp;
1782
+ uniform float uAngle;
1783
+ uniform float uCornerRadius;
1784
+ uniform vec3 uBaseColor;
1785
+ uniform vec3 uColorA;
1786
+ uniform vec3 uColorB;
1787
+ uniform vec3 uColorC;
1788
+ varying vec2 vUv;
1789
+
1790
+ float hash(vec2 p) {
1791
+ return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);
1792
+ }
1793
+
1794
+ float blob(vec2 p, vec2 center, vec2 size) {
1795
+ vec2 d = (p - center) / size;
1796
+ return exp(-dot(d, d));
1797
+ }
1798
+
1799
+ float noise(vec2 p) {
1800
+ vec2 i = floor(p);
1801
+ vec2 f = fract(p);
1802
+ vec2 u = f * f * (3.0 - 2.0 * f);
1803
+ return mix(mix(hash(i), hash(i + vec2(1.0, 0.0)), u.x), mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), u.x), u.y);
1804
+ }
1805
+
1806
+ float fbm(vec2 p) {
1807
+ return 0.5 * noise(p) + 0.25 * noise(p * 2.03 + 3.1) + 0.125 * noise(p * 4.01 + 7.7);
1808
+ }
1809
+
1810
+ void main() {
1811
+ vec2 size = max(uResolution, vec2(1.0));
1812
+ float radius = uCornerRadius * min(size.x, size.y);
1813
+ vec2 q = abs(vUv * size - size * 0.5) - size * 0.5 + radius;
1814
+ float distance = length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius;
1815
+ float shape = 1.0 - smoothstep(-1.0, 1.0, distance);
1816
+ if (shape <= 0.0) discard;
1817
+
1818
+ // The light comes from one side. Angle 0 is the bottom edge, and it turns clockwise: 90 is the left, 180 the top, 270 the right.
1819
+ // depth is 0 at the edge the light comes from and 1 at the far side, side runs along that edge.
1820
+ float turn = radians(uAngle);
1821
+ vec2 toward = vec2(-sin(turn), -cos(turn));
1822
+ vec2 across = vec2(-toward.y, toward.x);
1823
+ vec2 offset = (vUv - 0.5) * size;
1824
+ float reachAlong = 0.5 * (abs(toward.x) * size.x + abs(toward.y) * size.y);
1825
+ float reachAcross = 0.5 * (abs(across.x) * size.x + abs(across.y) * size.y);
1826
+ float depth = clamp(0.5 - dot(offset, toward) / (2.0 * reachAlong), 0.0, 1.0);
1827
+ float side = clamp(0.5 + dot(offset, across) / (2.0 * reachAcross), 0.0, 1.0);
1828
+ float aspect = reachAcross / reachAlong;
1829
+
1830
+ float t = uTime * max(uSpeed, 0.0);
1831
+ float height = clamp(uGlowHeight, 0.05, 1.0);
1832
+ float spread = max(uGlowSpread, 0.05);
1833
+ // The body is the base color with a faint lift toward the far side, like glass that catches the light.
1834
+ vec3 color = uBaseColor + vec3(0.035) * smoothstep(0.55, 1.0, 1.0 - depth);
1835
+
1836
+ // Three soft lights sit low in the card and drift slowly; the middle one is the broadest.
1837
+ vec2 p = vec2(side * aspect, depth);
1838
+ // The lights are bent by slow noise, so their edges curl like smoke instead of staying round.
1839
+ vec2 bend = vec2(fbm(p * 2.6 + vec2(t * 0.6, 0.0)), fbm(p * 2.6 + vec2(5.2, -t * 0.5))) - 0.35;
1840
+ p += bend * max(uWarp, 0.0) * 0.45;
1841
+ float wander = 0.05 * sin(t);
1842
+ float a = blob(p, vec2((0.18 + wander) * aspect, 0.0), vec2(0.5 * spread * aspect, 0.42 * height));
1843
+ float b = blob(p, vec2((0.52 - wander) * aspect, -0.04), vec2(0.62 * spread * aspect, 0.5 * height));
1844
+ float c = blob(p, vec2((0.86 + wander * 0.6) * aspect, 0.02), vec2(0.5 * spread * aspect, 0.44 * height));
1845
+ // Each light is thicker in some places than in others, so the colors mix unevenly.
1846
+ float patchy = fbm(p * 4.0 + 11.0);
1847
+ a *= 0.55 + 0.9 * patchy;
1848
+ b *= 0.55 + 0.9 * (1.0 - patchy);
1849
+ c *= 0.55 + 0.9 * fbm(p * 4.0 + 23.0);
1850
+ vec3 glow = uColorA * a + uColorB * b + uColorC * c;
1851
+
1852
+ // A haze reaches higher than the lights, so the color fades out into the body.
1853
+ float haze = smoothstep(height, 0.0, depth);
1854
+ glow += mix(uColorB, uColorA, side) * haze * haze * 0.35;
1855
+ color += glow * max(uIntensity, 0.0);
1856
+
1857
+ // Near the exit edge the lights are so strong that they turn white.
1858
+ float hot = smoothstep(height * 0.38, 0.0, depth) * (a + b + c) * clamp(uCore, 0.0, 1.0);
1859
+ color = mix(color, vec3(0.93, 0.95, 1.0), clamp(hot, 0.0, 1.0));
1860
+
1861
+ // A thin rim along the edge, strongest on the side away from the light.
1862
+ float rim = (1.0 - smoothstep(0.0, 1.6, -distance)) * smoothstep(0.0, 1.0, -distance + 1.0);
1863
+ color += vec3(0.62, 0.66, 0.78) * rim * max(uRim, 0.0) * (0.35 + 0.65 * smoothstep(0.2, 1.0, 1.0 - depth));
1864
+
1865
+ // The grit sits in the lit parts and fades in the dark body, as on film.
1866
+ float lit = clamp(dot(glow, vec3(0.45)) * max(uIntensity, 0.0) + hot, 0.0, 1.0);
1867
+ float grit = hash(gl_FragCoord.xy) - 0.5;
1868
+ grit += 0.5 * (hash(floor(gl_FragCoord.xy * 0.5) + 17.0) - 0.5);
1869
+ color += grit * max(uGrain, 0.0) * (0.3 + 2.2 * lit * (1.0 - 0.5 * lit));
1870
+ gl_FragColor = vec4(clamp(color, 0.0, 1.0), shape);
1871
+ }
1872
+ `;
1873
+ var glowCardProgram = {
1874
+ name: "glowCard",
1875
+ fragmentSource: fragmentSource8,
1876
+ defaultParameters: {
1877
+ speed: 0.12,
1878
+ intensity: 1,
1879
+ glowHeight: 0.55,
1880
+ glowSpread: 1,
1881
+ core: 0.7,
1882
+ rim: 0.55,
1883
+ grain: 0.12,
1884
+ warp: 1,
1885
+ angle: 0,
1886
+ cornerRadius: 0.08,
1887
+ baseColor: "#0b0b12",
1888
+ colorA: "#2f6bff",
1889
+ colorB: "#9d5cff",
1890
+ colorC: "#34d3c4"
1891
+ }
1892
+ };
1893
+
1894
+ // src/runtime/viewer/shaders/builtins/halftoneHalo.ts
1895
+ var fragmentSource9 = `
1896
+ precision highp float;
1897
+
1772
1898
  uniform vec2 uResolution;
1773
1899
  uniform float uTime;
1774
1900
  uniform float uSpeed;
@@ -1845,11 +1971,11 @@ void main() {
1845
1971
  `;
1846
1972
  var halftoneHaloProgram = {
1847
1973
  name: "halftoneHalo",
1848
- fragmentSource: fragmentSource8
1974
+ fragmentSource: fragmentSource9
1849
1975
  };
1850
1976
 
1851
1977
  // src/runtime/viewer/shaders/builtins/halo.ts
1852
- var fragmentSource9 = `
1978
+ var fragmentSource10 = `
1853
1979
  precision highp float;
1854
1980
 
1855
1981
  uniform vec2 uResolution;
@@ -1924,11 +2050,235 @@ void main() {
1924
2050
  `;
1925
2051
  var haloProgram = {
1926
2052
  name: "halo",
1927
- fragmentSource: fragmentSource9
2053
+ fragmentSource: fragmentSource10
2054
+ };
2055
+
2056
+ // src/runtime/viewer/shaders/builtins/ledMatrix.ts
2057
+ var fragmentSource11 = `
2058
+ precision highp float;
2059
+
2060
+ uniform vec2 uResolution;
2061
+ uniform float uTime;
2062
+ uniform float uSpeed;
2063
+ uniform float uIntensity;
2064
+ uniform float uColumns;
2065
+ uniform float uCellAspect;
2066
+ uniform float uGap;
2067
+ uniform float uGlow;
2068
+ uniform float uDepth;
2069
+ uniform float uGrain;
2070
+ uniform float uRotation;
2071
+ uniform float uRipple;
2072
+ uniform float uWave;
2073
+ uniform float uVariation;
2074
+ uniform float uFade;
2075
+ uniform float uOriginX;
2076
+ uniform float uOriginY;
2077
+ uniform float uSpread;
2078
+ uniform float uDrift;
2079
+ uniform float uReaction;
2080
+ uniform float uPointerSize;
2081
+ uniform float uHover;
2082
+ uniform vec2 uPointer;
2083
+ uniform vec3 uWake[16];
2084
+ uniform float uCornerRadius;
2085
+ uniform vec3 uBaseColor;
2086
+ uniform vec3 uOffColor;
2087
+ uniform vec3 uColor;
2088
+ uniform vec3 uHotColor;
2089
+ varying vec2 vUv;
2090
+
2091
+ float boxMask(vec2 uv) {
2092
+ vec2 halfBox = uResolution * 0.5;
2093
+ float radius = uCornerRadius * min(uResolution.x, uResolution.y);
2094
+ vec2 q = abs(uv * uResolution - halfBox) - halfBox + radius;
2095
+ float d = length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius;
2096
+ return 1.0 - smoothstep(-1.0, 1.0, d);
2097
+ }
2098
+
2099
+ float roundedBox(vec2 point, vec2 halfSize, float radius) {
2100
+ vec2 q = abs(point) - halfSize + radius;
2101
+ return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius;
2102
+ }
2103
+
2104
+ float hash(vec2 p) {
2105
+ return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);
2106
+ }
2107
+
2108
+ void main() {
2109
+ float shape = boxMask(vUv);
2110
+ if (shape <= 0.0) discard;
2111
+
2112
+ float time = uTime * max(uSpeed, 0.0);
2113
+ float columns = max(uColumns, 2.0);
2114
+ vec2 cellPx = vec2(uResolution.x / columns);
2115
+ cellPx.y *= max(uCellAspect, 0.2);
2116
+ vec2 rows = uResolution / cellPx;
2117
+
2118
+ // The grid can be turned around the middle of the surface.
2119
+ float angle = radians(uRotation);
2120
+ vec2 centered = (vUv - 0.5) * uResolution;
2121
+ vec2 turned = vec2(cos(angle) * centered.x - sin(angle) * centered.y, sin(angle) * centered.x + cos(angle) * centered.y);
2122
+ vec2 turnedUv = turned / uResolution + 0.5;
2123
+ vec2 grid = vec2(turnedUv.x, 1.0 - turnedUv.y) * rows;
2124
+ vec2 cell = floor(grid);
2125
+ vec2 local = (fract(grid) - 0.5) * cellPx;
2126
+ vec2 center = (cell + 0.5) / rows;
2127
+
2128
+ // The light of the surface sits at its origin, sways to the sides, and falls off with the spread. A spread of 0 puts it out.
2129
+ float spread = max(uSpread, 0.05);
2130
+ float lit = smoothstep(0.0, 0.05, uSpread);
2131
+ vec2 p = vec2(center.x, 1.0 - center.y);
2132
+ vec2 origin = vec2(uOriginX + uDrift * sin(time * 0.7), uOriginY);
2133
+ float aspect = uResolution.x / uResolution.y;
2134
+ float blob = exp(-pow(length((p - origin) * vec2(1.0, 1.55)) / spread, 2.0) * 5.5) * lit;
2135
+ float wave = 0.5 + 0.5 * sin(p.x * 5.0 + time * 1.3 + sin(p.y * 3.0 - time));
2136
+ float rise = pow(max(1.0 - abs(p.y - uOriginY) / spread, 0.0), 3.0) * (1.0 - 0.7 * uWave + 0.7 * uWave * wave) * lit;
2137
+ float glowLevel = blob * 1.15 + rise * 0.5 + 0.03;
2138
+
2139
+ // Rings that run outward from the light, and a different brightness for every light.
2140
+ float rings = 1.0 + uRipple * 0.5 * sin(length((p - origin) * vec2(1.0, 1.55)) * 16.0 - time * 2.5);
2141
+ float jitter = 1.0 - uVariation * 0.55 * hash(cell);
2142
+ float vignette = 1.0 - clamp(uFade, 0.0, 1.0) * smoothstep(0.3, 0.8, length(p - 0.5) * 1.3);
2143
+
2144
+ // The lights near the pointer glow up while it is over the surface, and the places it has been dim down one after the other.
2145
+ float near = exp(-pow(length((p - uPointer) * vec2(aspect, 1.0)) / max(uPointerSize, 0.01), 2.0)) * uHover;
2146
+ float wake = 0.0;
2147
+ for (int i = 0; i < 16; i++) {
2148
+ wake += uWake[i].z * exp(-pow(length((p - uWake[i].xy) * vec2(aspect, 1.0)) / max(uPointerSize * 0.88, 0.01), 2.0));
2149
+ }
2150
+ float touch = min(near + wake, 1.3) * max(uReaction, 0.0);
2151
+ float level = clamp(glowLevel * rings * jitter * vignette * max(uIntensity, 0.0) + touch * 1.1, 0.0, 1.0);
2152
+
2153
+ vec3 tint = mix(uOffColor, uColor, smoothstep(0.0, 0.6, level));
2154
+ tint = mix(tint, uHotColor, smoothstep(0.55, 1.0, level));
2155
+
2156
+ vec2 halfSize = cellPx * 0.5 * (1.0 - clamp(uGap, 0.0, 0.8));
2157
+ float d = roundedBox(local, halfSize, min(halfSize.x, halfSize.y));
2158
+ float body = 1.0 - smoothstep(-0.9, 0.9, d);
2159
+ // Depth shades a light like a small bulb: bright in the upper part, darker at the rim.
2160
+ float sheen = 1.0 - smoothstep(0.0, halfSize.y * 1.2, abs(local.y + halfSize.y * 0.35));
2161
+ float rim = smoothstep(-halfSize.x * 0.7, 0.0, d);
2162
+ float depth = clamp(uDepth, 0.0, 1.0);
2163
+ vec3 cellColor = tint * (1.0 - 0.4 * depth + 0.4 * depth * sheen) * (1.0 - 0.35 * depth * rim);
2164
+
2165
+ vec3 color = uBaseColor + tint * level * max(uGlow, 0.0) * 0.18;
2166
+ color = mix(color, cellColor, body);
2167
+ color += (hash(gl_FragCoord.xy) - 0.5) * max(uGrain, 0.0) * 0.2;
2168
+ gl_FragColor = vec4(clamp(color, 0.0, 1.0), shape);
2169
+ }
2170
+ `;
2171
+ var ledMatrixProgram = {
2172
+ name: "ledMatrix",
2173
+ fragmentSource: fragmentSource11,
2174
+ defaultParameters: {
2175
+ speed: 0.25,
2176
+ intensity: 1,
2177
+ columns: 44,
2178
+ cellAspect: 1.7,
2179
+ gap: 0.3,
2180
+ originX: 0.42,
2181
+ originY: 0.04,
2182
+ spread: 1,
2183
+ drift: 0.2,
2184
+ depth: 0.5,
2185
+ glow: 1,
2186
+ grain: 0.2,
2187
+ rotation: 0,
2188
+ ripple: 0.3,
2189
+ wave: 1,
2190
+ variation: 0.2,
2191
+ fade: 0.3,
2192
+ reaction: 1,
2193
+ pointerSize: 0.17,
2194
+ trail: 1.4,
2195
+ cornerRadius: 0.025,
2196
+ baseColor: "#050505",
2197
+ offColor: "#262626",
2198
+ color: "#a3a3a3",
2199
+ hotColor: "#ffffff"
2200
+ }
2201
+ };
2202
+
2203
+ // src/runtime/viewer/shaders/builtins/lightBand.ts
2204
+ var fragmentSource12 = `
2205
+ precision highp float;
2206
+
2207
+ uniform vec2 uResolution;
2208
+ uniform float uTime;
2209
+ uniform float uSpeed;
2210
+ uniform float uIntensity;
2211
+ uniform float uThickness;
2212
+ uniform float uBloom;
2213
+ uniform float uWave;
2214
+ uniform float uGrain;
2215
+ uniform float uCornerRadius;
2216
+ uniform vec3 uBaseColor;
2217
+ uniform vec3 uColorA;
2218
+ uniform vec3 uColorB;
2219
+ uniform vec3 uColorC;
2220
+ varying vec2 vUv;
2221
+
2222
+ float boxMask(vec2 uv) {
2223
+ vec2 halfBox = uResolution * 0.5;
2224
+ float radius = uCornerRadius * min(uResolution.x, uResolution.y);
2225
+ vec2 q = abs(uv * uResolution - halfBox) - halfBox + radius;
2226
+ float d = length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius;
2227
+ return 1.0 - smoothstep(-1.0, 1.0, d);
2228
+ }
2229
+
2230
+ float hash(vec2 p) {
2231
+ return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);
2232
+ }
2233
+
2234
+ void main() {
2235
+ float shape = boxMask(vUv);
2236
+ if (shape <= 0.0) discard;
2237
+
2238
+ float t = uTime * max(uSpeed, 0.0);
2239
+ float aspect = uResolution.x / uResolution.y;
2240
+ vec2 p = vec2(vUv.x, 1.0 - vUv.y);
2241
+
2242
+ // The middle of the band wanders across the surface, and its width breathes along the way.
2243
+ float middle = 0.5 + uWave * (0.11 * sin(p.x * 3.4 + t) + 0.05 * sin(p.x * 7.1 - t * 1.4));
2244
+ float width = max(uThickness, 0.002) * (0.65 + 0.35 * sin(p.x * 2.4 + t * 0.6));
2245
+ float offset = (p.y - middle) * aspect * 0.6;
2246
+ float core = exp(-pow(offset / width, 2.0));
2247
+ float halo = exp(-pow(offset / (width * (2.5 + uBloom * 5.0)), 2.0));
2248
+
2249
+ // Blue at one end, pink at the other, and the colors drift a little.
2250
+ float along = clamp(p.x + 0.12 * sin(t * 0.8), 0.0, 1.0);
2251
+ vec3 tint = along < 0.5 ? mix(uColorA, uColorB, along * 2.0) : mix(uColorB, uColorC, along * 2.0 - 1.0);
2252
+ float pulse = 0.6 + 0.4 * sin(p.x * 6.0 - t * 2.0);
2253
+
2254
+ vec3 color = uBaseColor;
2255
+ color += tint * halo * 0.55 * pulse * max(uBloom, 0.0);
2256
+ color += mix(tint, vec3(1.0), 0.55) * core * (0.55 + 0.45 * pulse);
2257
+ color *= max(uIntensity, 0.0);
2258
+ color += (hash(gl_FragCoord.xy + t) - 0.5) * max(uGrain, 0.0);
2259
+ gl_FragColor = vec4(clamp(color, 0.0, 1.0), shape);
2260
+ }
2261
+ `;
2262
+ var lightBandProgram = {
2263
+ name: "lightBand",
2264
+ fragmentSource: fragmentSource12,
2265
+ defaultParameters: {
2266
+ speed: 0.3,
2267
+ intensity: 1,
2268
+ thickness: 0.035,
2269
+ bloom: 1,
2270
+ wave: 1,
2271
+ grain: 0.02,
2272
+ cornerRadius: 0.02,
2273
+ baseColor: "#0f0e14",
2274
+ colorA: "#7ea8ff",
2275
+ colorB: "#c13fd6",
2276
+ colorC: "#ff6fb8"
2277
+ }
1928
2278
  };
1929
2279
 
1930
2280
  // src/runtime/viewer/shaders/builtins/lumenPortal.ts
1931
- var fragmentSource10 = `
2281
+ var fragmentSource13 = `
1932
2282
  precision highp float;
1933
2283
 
1934
2284
  uniform float uTime;
@@ -1986,11 +2336,11 @@ void main() {
1986
2336
  `;
1987
2337
  var lumenPortalProgram = {
1988
2338
  name: "lumenPortal",
1989
- fragmentSource: fragmentSource10
2339
+ fragmentSource: fragmentSource13
1990
2340
  };
1991
2341
 
1992
2342
  // src/runtime/viewer/shaders/builtins/lumenPortalLight.ts
1993
- var fragmentSource11 = `
2343
+ var fragmentSource14 = `
1994
2344
  precision highp float;
1995
2345
 
1996
2346
  uniform float uTime;
@@ -2049,11 +2399,11 @@ void main() {
2049
2399
  `;
2050
2400
  var lumenPortalLightProgram = {
2051
2401
  name: "lumenPortalLight",
2052
- fragmentSource: fragmentSource11
2402
+ fragmentSource: fragmentSource14
2053
2403
  };
2054
2404
 
2055
2405
  // src/runtime/viewer/shaders/builtins/orb.ts
2056
- var fragmentSource12 = `
2406
+ var fragmentSource15 = `
2057
2407
  precision highp float;
2058
2408
 
2059
2409
  uniform vec2 uResolution;
@@ -2089,11 +2439,11 @@ void main() {
2089
2439
  `;
2090
2440
  var orbProgram = {
2091
2441
  name: "orb",
2092
- fragmentSource: fragmentSource12
2442
+ fragmentSource: fragmentSource15
2093
2443
  };
2094
2444
 
2095
2445
  // src/runtime/viewer/shaders/builtins/pixelConstellation.ts
2096
- var fragmentSource13 = `
2446
+ var fragmentSource16 = `
2097
2447
  precision highp float;
2098
2448
 
2099
2449
  uniform float uTime;
@@ -2193,11 +2543,11 @@ void main() {
2193
2543
  `;
2194
2544
  var pixelConstellationProgram = {
2195
2545
  name: "pixelConstellation",
2196
- fragmentSource: fragmentSource13
2546
+ fragmentSource: fragmentSource16
2197
2547
  };
2198
2548
 
2199
2549
  // src/runtime/viewer/shaders/builtins/plasmaGauge.ts
2200
- var fragmentSource14 = `
2550
+ var fragmentSource17 = `
2201
2551
  precision highp float;
2202
2552
 
2203
2553
  uniform vec2 uResolution;
@@ -2299,12 +2649,12 @@ void main() {
2299
2649
  `;
2300
2650
  var plasmaGaugeProgram = {
2301
2651
  name: "plasmaGauge",
2302
- fragmentSource: fragmentSource14,
2652
+ fragmentSource: fragmentSource17,
2303
2653
  replacesBaseFill: true
2304
2654
  };
2305
2655
 
2306
2656
  // src/runtime/viewer/shaders/builtins/prismSlats.ts
2307
- var fragmentSource15 = `
2657
+ var fragmentSource18 = `
2308
2658
  precision highp float;
2309
2659
 
2310
2660
  uniform vec2 uResolution;
@@ -2379,11 +2729,136 @@ void main() {
2379
2729
  `;
2380
2730
  var prismSlatsProgram = {
2381
2731
  name: "prismSlats",
2382
- fragmentSource: fragmentSource15
2732
+ fragmentSource: fragmentSource18
2733
+ };
2734
+
2735
+ // src/runtime/viewer/shaders/builtins/reactivePanel.ts
2736
+ var fragmentSource19 = `
2737
+ precision highp float;
2738
+
2739
+ uniform float uTime;
2740
+ uniform float uSpeed;
2741
+ uniform float uIntensity;
2742
+ uniform float uEmission;
2743
+ uniform float uReception;
2744
+ uniform float uEmitterFill;
2745
+ uniform float uGrain;
2746
+ uniform float uGrainScale;
2747
+ uniform float uCornerRadius;
2748
+ uniform float uBorderWidth;
2749
+ uniform float uGlowRadius;
2750
+ uniform float uSurfacePadding;
2751
+ uniform float uLightX;
2752
+ uniform float uLightY;
2753
+ uniform float uLightStrength;
2754
+ uniform float uPixelScale;
2755
+ uniform vec2 uResolution;
2756
+ uniform vec3 uShapeColor;
2757
+ uniform vec3 uBaseColor;
2758
+ uniform vec3 uEdgeColor;
2759
+ uniform vec3 uLightColor;
2760
+ varying vec2 vUv;
2761
+
2762
+ float roundedBoxDistance(vec2 point, vec2 halfSize, float radius) {
2763
+ vec2 offset = abs(point) - halfSize + radius;
2764
+ return min(max(offset.x, offset.y), 0.0) + length(max(offset, 0.0)) - radius;
2765
+ }
2766
+
2767
+ float random(vec2 point) {
2768
+ vec3 value = fract(vec3(point.xyx) * 0.1031);
2769
+ value += dot(value, value.yzx + 33.33);
2770
+ return fract((value.x + value.y) * value.z);
2771
+ }
2772
+
2773
+ void main() {
2774
+ vec2 pixel = vUv * uResolution;
2775
+ float pixelScale = max(uPixelScale, 0.0001);
2776
+ float padding = clamp(uSurfacePadding * pixelScale, 0.0, min(uResolution.x, uResolution.y) * 0.45);
2777
+ vec2 panelHalfSize = max(vec2(1.0), uResolution * 0.5 - padding);
2778
+ vec2 panelPoint = pixel - uResolution * 0.5;
2779
+ float radius = min(max(uCornerRadius * pixelScale, 0.0), min(panelHalfSize.x, panelHalfSize.y));
2780
+ float distance = roundedBoxDistance(panelPoint, panelHalfSize, radius);
2781
+ float body = 1.0 - smoothstep(-1.25, 0.75, distance);
2782
+ float borderWidth = max(uBorderWidth * pixelScale, 0.5);
2783
+ float edge = exp(-pow(distance / borderWidth, 2.0));
2784
+ float innerEdge = exp(-pow((distance + borderWidth * 2.25) / (borderWidth * 2.2), 2.0)) * body;
2785
+
2786
+ vec2 lightPosition = vec2(uLightX, 1.0 - uLightY) * uResolution;
2787
+ float lightDistance = length(pixel - lightPosition);
2788
+ float lightRadius = max(uGlowRadius * pixelScale, 1.0);
2789
+ float receivedLight = exp(-pow(lightDistance / lightRadius, 2.0));
2790
+ receivedLight *= max(uReception, 0.0) * max(uLightStrength, 0.0);
2791
+
2792
+ float speed = max(uSpeed, 0.0);
2793
+ float breath = 0.88 + 0.12 * sin(uTime * speed * 6.2831853);
2794
+ float emittedLight = max(uEmission, 0.0) * breath;
2795
+ float outsideFalloff = exp(-max(distance, 0.0) / max(lightRadius * 0.22, 1.0));
2796
+ float outsideGlow = outsideFalloff * (emittedLight * 1.35 + receivedLight * 0.9);
2797
+ float frameDistance = min(min(pixel.x, uResolution.x - pixel.x), min(pixel.y, uResolution.y - pixel.y));
2798
+ float frameFade = smoothstep(0.0, max(padding * 0.65, 1.0), frameDistance);
2799
+ outsideGlow *= frameFade;
2800
+
2801
+ vec3 baseColor = dot(uBaseColor, uBaseColor) > 0.0 ? uBaseColor : uShapeColor;
2802
+ vec3 edgeColor = dot(uEdgeColor, uEdgeColor) > 0.0 ? uEdgeColor : vec3(0.22, 0.72, 1.0);
2803
+ vec3 lightColor = dot(uLightColor, uLightColor) > 0.0 ? uLightColor : edgeColor;
2804
+ vec3 color = baseColor * (0.82 + receivedLight * 0.42);
2805
+
2806
+ // Emission lights the material itself instead of leaving a dark cutout behind.
2807
+ // A soft centre bias keeps the fill dimensional while the edge remains crisp.
2808
+ vec2 normalizedPoint = panelPoint / max(panelHalfSize, vec2(1.0));
2809
+ float centreLight = 1.0 - smoothstep(0.05, 1.25, length(normalizedPoint));
2810
+ float fillLight = clamp(emittedLight * max(uEmitterFill, 0.0), 0.0, 1.0) * body;
2811
+ vec3 illuminatedFill = mix(edgeColor, lightColor, 0.62 + centreLight * 0.28);
2812
+ color = mix(color, illuminatedFill * (0.72 + centreLight * 0.62), fillLight);
2813
+
2814
+ // Fine object-space luminance grain. It is intentionally emission-gated so
2815
+ // receiver panels stay clean and the texture stays fixed on the active tile.
2816
+ float grainScale = max(uGrainScale * pixelScale, 0.75);
2817
+ vec2 grainCell = floor(pixel / grainScale);
2818
+ float grainValue = random(grainCell);
2819
+ float grainLight = (grainValue - 0.36) * max(uGrain, 0.0) * fillLight;
2820
+ color += lightColor * grainLight * (0.5 + centreLight * 0.75);
2821
+
2822
+ color += edgeColor * edge * (0.42 + emittedLight * 1.7);
2823
+ color += lightColor * edge * receivedLight * 2.5;
2824
+ color += lightColor * innerEdge * receivedLight * 1.25;
2825
+
2826
+ float intensity = max(uIntensity, 0.0);
2827
+ float halo = outsideGlow * (1.0 - body) * 0.9 * intensity;
2828
+ float alpha = body + halo;
2829
+ if (alpha < 0.002) discard;
2830
+
2831
+ vec3 haloColor = mix(edgeColor, lightColor, clamp(receivedLight * 1.5, 0.0, 1.0));
2832
+ vec3 premultiplied = color * body * intensity + haloColor * halo;
2833
+ gl_FragColor = vec4(clamp(premultiplied, 0.0, 1.0), clamp(alpha, 0.0, 1.0));
2834
+ }
2835
+ `;
2836
+ var reactivePanelProgram = {
2837
+ name: "reactivePanel",
2838
+ fragmentSource: fragmentSource19,
2839
+ defaultParameters: {
2840
+ intensity: 0.5,
2841
+ speed: 0.18,
2842
+ emission: 0,
2843
+ reception: 0.85,
2844
+ emitterFill: 0,
2845
+ grain: 0,
2846
+ grainScale: 1.5,
2847
+ cornerRadius: 18,
2848
+ borderWidth: 2,
2849
+ glowRadius: 90,
2850
+ lightX: 0.5,
2851
+ lightY: 0.5,
2852
+ lightStrength: 0,
2853
+ baseColor: "#09101c",
2854
+ edgeColor: "#33b8ff",
2855
+ lightColor: "#59d1ff"
2856
+ },
2857
+ replacesBaseFill: true
2383
2858
  };
2384
2859
 
2385
2860
  // src/runtime/viewer/shaders/builtins/ruler.ts
2386
- var fragmentSource16 = `
2861
+ var fragmentSource20 = `
2387
2862
  precision highp float;
2388
2863
 
2389
2864
  uniform vec2 uResolution;
@@ -2488,12 +2963,120 @@ void main() {
2488
2963
  `;
2489
2964
  var rulerProgram = {
2490
2965
  name: "ruler",
2491
- fragmentSource: fragmentSource16,
2966
+ fragmentSource: fragmentSource20,
2492
2967
  replacesBaseFill: true
2493
2968
  };
2494
2969
 
2970
+ // src/runtime/viewer/shaders/builtins/silkFolds.ts
2971
+ var fragmentSource21 = `
2972
+ precision highp float;
2973
+
2974
+ uniform vec2 uResolution;
2975
+ uniform float uTime;
2976
+ uniform float uSpeed;
2977
+ uniform float uIntensity;
2978
+ uniform float uScale;
2979
+ uniform float uSharpness;
2980
+ uniform float uDepth;
2981
+ uniform float uGlow;
2982
+ uniform float uGrain;
2983
+ uniform float uRotation;
2984
+ uniform float uRipple;
2985
+ uniform float uWave;
2986
+ uniform float uVariation;
2987
+ uniform float uFade;
2988
+ uniform float uReaction;
2989
+ uniform float uHover;
2990
+ uniform vec2 uPointer;
2991
+ uniform float uCornerRadius;
2992
+ uniform vec3 uBaseColor;
2993
+ uniform vec3 uColor;
2994
+ uniform vec3 uHighlightColor;
2995
+ varying vec2 vUv;
2996
+
2997
+ float boxMask(vec2 uv) {
2998
+ vec2 halfBox = uResolution * 0.5;
2999
+ float radius = uCornerRadius * min(uResolution.x, uResolution.y);
3000
+ vec2 q = abs(uv * uResolution - halfBox) - halfBox + radius;
3001
+ float d = length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius;
3002
+ return 1.0 - smoothstep(-1.0, 1.0, d);
3003
+ }
3004
+
3005
+ float hash(vec2 p) {
3006
+ return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);
3007
+ }
3008
+
3009
+ vec2 turn(vec2 point, float angle) {
3010
+ float c = cos(angle);
3011
+ float s = sin(angle);
3012
+ return vec2(c * point.x - s * point.y, s * point.x + c * point.y);
3013
+ }
3014
+
3015
+ void main() {
3016
+ float shape = boxMask(vUv);
3017
+ if (shape <= 0.0) discard;
3018
+
3019
+ float t = uTime * max(uSpeed, 0.0);
3020
+ float aspect = uResolution.x / uResolution.y;
3021
+ float angle = radians(uRotation);
3022
+ float zoom = max(uScale, 0.2) * 2.0;
3023
+ vec2 p = turn((vUv - 0.5) * vec2(aspect, 1.0), angle) * zoom;
3024
+
3025
+ // An irregular, slow bend of the whole cloth, so no two folds are alike.
3026
+ p += uVariation * 1.3 * vec2(sin(p.y * 0.37 + 3.1), cos(p.x * 0.41 + 1.7));
3027
+
3028
+ // Bend the plane a few times, then lay a wave over it: the crests of the wave are the folds of the cloth.
3029
+ for (int i = 0; i < 3; i++) {
3030
+ float k = float(i);
3031
+ p += 0.22 * uWave * vec2(sin(p.y * 1.7 + t * 0.6 + k * 1.3), cos(p.x * 1.5 - t * 0.5 + k * 1.9));
3032
+ }
3033
+
3034
+ // The cloth lifts where the pointer is over it.
3035
+ vec2 touch = turn((uPointer - 0.5) * vec2(aspect, 1.0), angle) * zoom;
3036
+ float lift = exp(-pow(length(p - touch) * 0.55, 2.0)) * uHover * max(uReaction, 0.0);
3037
+
3038
+ float phase = p.x * 0.8 + p.y * 2.2 + 1.2 * sin(p.y * 0.9 - t * 0.3) + 0.8 * sin(p.x * 1.3 + t * 0.2) + lift * 2.4;
3039
+ phase += uRipple * 0.35 * sin(p.x * 7.0 + p.y * 5.0 + t * 1.1);
3040
+ float wave = 0.5 + 0.5 * sin(phase);
3041
+
3042
+ float crest = pow(wave, max(uSharpness, 0.5));
3043
+ float body = pow(wave, mix(1.0, 3.2, clamp(uDepth, 0.0, 1.0)));
3044
+ float bloom = pow(wave, 1.3) * max(uGlow, 0.0);
3045
+
3046
+ vec3 color = mix(uBaseColor, uColor, body * 0.9);
3047
+ color += uHighlightColor * (crest * (0.65 + 0.35 * lift) + bloom * 0.28);
3048
+ color *= max(uIntensity, 0.0);
3049
+ color *= 1.0 - clamp(uFade, 0.0, 1.0) * smoothstep(0.3, 0.78, length(vUv - 0.5) * 1.35);
3050
+ color += (hash(gl_FragCoord.xy) - 0.5) * max(uGrain, 0.0);
3051
+ gl_FragColor = vec4(clamp(color, 0.0, 1.0), shape);
3052
+ }
3053
+ `;
3054
+ var silkFoldsProgram = {
3055
+ name: "silkFolds",
3056
+ fragmentSource: fragmentSource21,
3057
+ defaultParameters: {
3058
+ speed: 0.2,
3059
+ intensity: 1,
3060
+ scale: 2.2,
3061
+ sharpness: 5,
3062
+ depth: 0.5,
3063
+ glow: 0.3,
3064
+ grain: 0.08,
3065
+ rotation: 0,
3066
+ ripple: 0.3,
3067
+ wave: 1,
3068
+ variation: 0,
3069
+ fade: 0.3,
3070
+ reaction: 1,
3071
+ cornerRadius: 0.02,
3072
+ baseColor: "#030303",
3073
+ color: "#4d4d4d",
3074
+ highlightColor: "#ffffff"
3075
+ }
3076
+ };
3077
+
2495
3078
  // src/runtime/viewer/shaders/builtins/smearOrb.ts
2496
- var fragmentSource17 = `
3079
+ var fragmentSource22 = `
2497
3080
  precision highp float;
2498
3081
 
2499
3082
  uniform vec2 uResolution;
@@ -2569,12 +3152,12 @@ void main() {
2569
3152
  `;
2570
3153
  var smearOrbProgram = {
2571
3154
  name: "smearOrb",
2572
- fragmentSource: fragmentSource17,
3155
+ fragmentSource: fragmentSource22,
2573
3156
  replacesBaseFill: true
2574
3157
  };
2575
3158
 
2576
3159
  // src/runtime/viewer/shaders/builtins/tickScale.ts
2577
- var fragmentSource18 = `
3160
+ var fragmentSource23 = `
2578
3161
  precision highp float;
2579
3162
 
2580
3163
  uniform vec2 uResolution;
@@ -2633,12 +3216,12 @@ void main() {
2633
3216
  `;
2634
3217
  var tickScaleProgram = {
2635
3218
  name: "tickScale",
2636
- fragmentSource: fragmentSource18,
3219
+ fragmentSource: fragmentSource23,
2637
3220
  replacesBaseFill: true
2638
3221
  };
2639
3222
 
2640
3223
  // src/runtime/viewer/shaders/builtins/violetGlass.ts
2641
- var fragmentSource19 = `
3224
+ var fragmentSource24 = `
2642
3225
  precision highp float;
2643
3226
 
2644
3227
  uniform float uTime;
@@ -2718,11 +3301,11 @@ void main() {
2718
3301
  `;
2719
3302
  var violetGlassProgram = {
2720
3303
  name: "violetGlass",
2721
- fragmentSource: fragmentSource19
3304
+ fragmentSource: fragmentSource24
2722
3305
  };
2723
3306
 
2724
3307
  // src/runtime/viewer/shaders/builtins/violetGlassLight.ts
2725
- var fragmentSource20 = `
3308
+ var fragmentSource25 = `
2726
3309
  precision highp float;
2727
3310
 
2728
3311
  uniform float uTime;
@@ -2792,7 +3375,7 @@ void main() {
2792
3375
  `;
2793
3376
  var violetGlassLightProgram = {
2794
3377
  name: "violetGlassLight",
2795
- fragmentSource: fragmentSource20
3378
+ fragmentSource: fragmentSource25
2796
3379
  };
2797
3380
 
2798
3381
  // src/runtime/viewer/shaders/programs.ts
@@ -2816,7 +3399,12 @@ var builtins = [
2816
3399
  violetGlassProgram,
2817
3400
  violetGlassLightProgram,
2818
3401
  lumenPortalProgram,
2819
- lumenPortalLightProgram
3402
+ lumenPortalLightProgram,
3403
+ reactivePanelProgram,
3404
+ ledMatrixProgram,
3405
+ lightBandProgram,
3406
+ silkFoldsProgram,
3407
+ glowCardProgram
2820
3408
  ];
2821
3409
  var programs = new Map(builtins.map((program) => [program.name, program]));
2822
3410
  function registerShaderProgram(program) {
@@ -2930,8 +3518,8 @@ function uniform2f(surface, name, value) {
2930
3518
  surface.gl.uniform2f(location, ...value);
2931
3519
  }
2932
3520
  }
2933
- function uniformName(parameter) {
2934
- return `u${parameter.charAt(0).toUpperCase()}${parameter.slice(1)}`;
3521
+ function uniformName(parameter2) {
3522
+ return `u${parameter2.charAt(0).toUpperCase()}${parameter2.slice(1)}`;
2935
3523
  }
2936
3524
  function enumParameter(name, value) {
2937
3525
  const values = {
@@ -2997,9 +3585,9 @@ function compile(gl, type, source) {
2997
3585
  }
2998
3586
  return shader;
2999
3587
  }
3000
- function linkProgram(gl, fragmentSource21) {
3588
+ function linkProgram(gl, fragmentSource26) {
3001
3589
  const vertex = compile(gl, gl.VERTEX_SHADER, VERTEX_SOURCE);
3002
- const fragment = compile(gl, gl.FRAGMENT_SHADER, fragmentSource21);
3590
+ const fragment = compile(gl, gl.FRAGMENT_SHADER, fragmentSource26);
3003
3591
  if (!vertex || !fragment) {
3004
3592
  if (vertex) {
3005
3593
  gl.deleteShader(vertex);
@@ -3049,6 +3637,10 @@ function parametersOf(owner) {
3049
3637
  return {};
3050
3638
  }
3051
3639
  }
3640
+ function surfacePaddingOf(owner) {
3641
+ const padding = Number(owner.getAttribute("data-sf-shader-padding"));
3642
+ return Number.isFinite(padding) ? Math.max(0, padding) : 0;
3643
+ }
3052
3644
  function bindFullScreenQuad(gl, program) {
3053
3645
  const buffer = gl.createBuffer();
3054
3646
  if (!buffer) {
@@ -3101,8 +3693,13 @@ function createSurface(canvas) {
3101
3693
  gl,
3102
3694
  program,
3103
3695
  buffer,
3104
- parameters: parametersOf(owner),
3696
+ parameters: { ...definition.defaultParameters, ...parametersOf(owner) },
3697
+ surfacePadding: surfacePaddingOf(owner),
3105
3698
  smoothed: /* @__PURE__ */ new Map(),
3699
+ pointer: { x: 0.5, y: 0.5 },
3700
+ hovering: false,
3701
+ hover: 0,
3702
+ trail: [],
3106
3703
  backdropTexture: usesBackdrop ? transparentTexture(gl) : void 0,
3107
3704
  backdropOrigin: [0, 0],
3108
3705
  backdropScale: [1, 1],
@@ -3128,6 +3725,108 @@ function releaseSurface(surface) {
3128
3725
  }
3129
3726
  }
3130
3727
 
3728
+ // src/runtime/viewer/shaders/reactiveLightField.ts
3729
+ function geometryOf(surface) {
3730
+ const x = Number(surface.owner.getAttribute("x"));
3731
+ const y = Number(surface.owner.getAttribute("y"));
3732
+ const width = Number(surface.owner.getAttribute("width"));
3733
+ const height = Number(surface.owner.getAttribute("height"));
3734
+ if (![x, y, width, height].every(Number.isFinite) || width <= 0 || height <= 0) {
3735
+ return void 0;
3736
+ }
3737
+ const matrix = surface.owner.getCTM?.();
3738
+ const a = matrix?.a ?? 1;
3739
+ const b = matrix?.b ?? 0;
3740
+ const c = matrix?.c ?? 0;
3741
+ const d = matrix?.d ?? 1;
3742
+ const e = matrix?.e ?? 0;
3743
+ const f = matrix?.f ?? 0;
3744
+ const determinant = a * d - b * c;
3745
+ const centerX = a * (x + width / 2) + c * (y + height / 2) + e;
3746
+ const centerY = b * (x + width / 2) + d * (y + height / 2) + f;
3747
+ const localPoint = (worldX, worldY) => {
3748
+ if (Math.abs(determinant) < 1e-6) {
3749
+ return [worldX, worldY];
3750
+ }
3751
+ const translatedX = worldX - e;
3752
+ const translatedY = worldY - f;
3753
+ return [(d * translatedX - c * translatedY) / determinant, (-b * translatedX + a * translatedY) / determinant];
3754
+ };
3755
+ return { width, height, centerX, centerY, localPoint };
3756
+ }
3757
+ function parameter(parameters3, key, fallback) {
3758
+ return number(parameters3[key], fallback);
3759
+ }
3760
+ function normalizedLightPosition(sourceX, sourceY, receiverX, receiverY, receiverWidth, receiverHeight) {
3761
+ return [(sourceX - receiverX) / receiverWidth, (sourceY - receiverY) / receiverHeight];
3762
+ }
3763
+ function updateReactiveLightFields(surfaces) {
3764
+ const reactive = surfaces.filter((surface) => surface.owner.getAttribute("data-sf-shader") === "reactivePanel").flatMap((surface) => {
3765
+ const geometry = geometryOf(surface);
3766
+ return geometry ? [{ surface, geometry }] : [];
3767
+ });
3768
+ for (const receiver of reactive) {
3769
+ const sources = [];
3770
+ for (const candidate of reactive) {
3771
+ if (candidate.surface === receiver.surface) {
3772
+ continue;
3773
+ }
3774
+ const emission = Math.max(
3775
+ 0,
3776
+ candidate.surface.smoothed.get("emission") ?? parameter(candidate.surface.parameters, "emission", 0)
3777
+ );
3778
+ if (emission <= 1e-4) {
3779
+ continue;
3780
+ }
3781
+ const distance = Math.hypot(
3782
+ candidate.geometry.centerX - receiver.geometry.centerX,
3783
+ candidate.geometry.centerY - receiver.geometry.centerY
3784
+ );
3785
+ sources.push({ candidate, emission, weight: emission / Math.max(distance, 1) });
3786
+ }
3787
+ const totalWeight = sources.reduce((sum, source) => sum + source.weight, 0);
3788
+ if (totalWeight <= 0) {
3789
+ receiver.surface.reactiveLight = void 0;
3790
+ continue;
3791
+ }
3792
+ let worldX = 0;
3793
+ let worldY = 0;
3794
+ let sourceEmission = 0;
3795
+ let radius = 0;
3796
+ const lightColor = [0, 0, 0];
3797
+ for (const source of sources) {
3798
+ const influence = source.weight / totalWeight;
3799
+ worldX += source.candidate.geometry.centerX * influence;
3800
+ worldY += source.candidate.geometry.centerY * influence;
3801
+ sourceEmission += source.emission;
3802
+ radius += Math.max(1, parameter(source.candidate.surface.parameters, "glowRadius", 90)) * influence;
3803
+ const sourceColor = color(source.candidate.surface.parameters.lightColor, [0.35, 0.82, 1]);
3804
+ lightColor[0] += sourceColor[0] * influence;
3805
+ lightColor[1] += sourceColor[1] * influence;
3806
+ lightColor[2] += sourceColor[2] * influence;
3807
+ }
3808
+ const receiverStrength = Math.max(0, parameter(receiver.surface.parameters, "lightStrength", 1));
3809
+ const [sourceX, sourceY] = receiver.geometry.localPoint(worldX, worldY);
3810
+ const receiverX = Number(receiver.surface.owner.getAttribute("x"));
3811
+ const receiverY = Number(receiver.surface.owner.getAttribute("y"));
3812
+ const [lightX, lightY] = normalizedLightPosition(
3813
+ sourceX,
3814
+ sourceY,
3815
+ receiverX,
3816
+ receiverY,
3817
+ receiver.geometry.width,
3818
+ receiver.geometry.height
3819
+ );
3820
+ receiver.surface.reactiveLight = {
3821
+ x: lightX,
3822
+ y: lightY,
3823
+ strength: sourceEmission * receiverStrength * 1.8,
3824
+ radius,
3825
+ color: lightColor
3826
+ };
3827
+ }
3828
+ }
3829
+
3131
3830
  // src/runtime/viewer/shaders/renderSurface.ts
3132
3831
  function syncBackdropBounds(surface) {
3133
3832
  const svg = surface.canvas.closest("svg");
@@ -3156,6 +3855,7 @@ function applyBackdrop(surface, backdrop) {
3156
3855
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, backdrop.image);
3157
3856
  }
3158
3857
  var MAX_SURFACE_PIXELS = 2560;
3858
+ var TRAIL_LENGTH = 16;
3159
3859
  function renderSurface(surface, seconds) {
3160
3860
  const { canvas, gl, parameters: parameters3 } = surface;
3161
3861
  const shown = canvas.getBoundingClientRect();
@@ -3175,6 +3875,12 @@ function renderSurface(surface, seconds) {
3175
3875
  if (resolution) {
3176
3876
  gl.uniform2f(resolution, width, height);
3177
3877
  }
3878
+ const logicalWidth = Number(surface.owner.getAttribute("width"));
3879
+ uniform1f(
3880
+ surface,
3881
+ "uPixelScale",
3882
+ Number.isFinite(logicalWidth) && logicalWidth > 0 ? width / logicalWidth : density * fit
3883
+ );
3178
3884
  uniform1f(surface, "uTime", seconds);
3179
3885
  if (surface.backdropTexture) {
3180
3886
  syncBackdropBounds(surface);
@@ -3197,6 +3903,28 @@ function renderSurface(surface, seconds) {
3197
3903
  const elapsed = surface.lastSeconds === void 0 ? 0 : Math.max(0, Math.min(seconds - surface.lastSeconds, 0.1));
3198
3904
  surface.lastSeconds = seconds;
3199
3905
  applyParameters(surface, elapsed);
3906
+ surface.hover += ((surface.hovering ? 1 : 0) - surface.hover) * (1 - Math.exp(-elapsed / 0.18));
3907
+ uniform2f(surface, "uPointer", [surface.pointer.x, surface.pointer.y]);
3908
+ uniform1f(surface, "uHover", surface.hover);
3909
+ const fade = number(parameters3.trail, 0);
3910
+ const places = new Float32Array(TRAIL_LENGTH * 3);
3911
+ if (fade > 0) {
3912
+ surface.trail.slice(-TRAIL_LENGTH).forEach((place, index) => {
3913
+ places.set([place.x, place.y, Math.exp(-Math.max(seconds - place.at, 0) / fade)], index * 3);
3914
+ });
3915
+ }
3916
+ const trail = gl.getUniformLocation(surface.program, "uWake[0]");
3917
+ if (trail) {
3918
+ gl.uniform3fv(trail, places);
3919
+ }
3920
+ if (surface.reactiveLight) {
3921
+ uniform1f(surface, "uLightX", surface.reactiveLight.x);
3922
+ uniform1f(surface, "uLightY", surface.reactiveLight.y);
3923
+ uniform1f(surface, "uLightStrength", surface.reactiveLight.strength);
3924
+ uniform1f(surface, "uGlowRadius", surface.reactiveLight.radius);
3925
+ uniform3f(surface, "uLightColor", surface.reactiveLight.color);
3926
+ }
3927
+ uniform1f(surface, "uSurfacePadding", surface.surfacePadding);
3200
3928
  gl.drawArrays(gl.TRIANGLES, 0, 6);
3201
3929
  }
3202
3930
 
@@ -3222,6 +3950,8 @@ function createSurfaceClock(view) {
3222
3950
 
3223
3951
  // src/runtime/viewer/shaders/surface.ts
3224
3952
  var RECAPTURE_DELAY_MS = 120;
3953
+ var TRAIL_SPACING = 0.055;
3954
+ var TRAIL_LENGTH2 = 16;
3225
3955
  function capturePngs(svg, surfaces, seconds) {
3226
3956
  const surfaceByCanvas = new Map(surfaces.map((surface) => [surface.canvas, surface]));
3227
3957
  return [...svg.querySelectorAll("canvas[data-sf-shader-canvas]")].map((canvas) => {
@@ -3245,9 +3975,14 @@ function updateParameters(surfaces, ownerId, parameters3, seconds) {
3245
3975
  }
3246
3976
  Object.assign(surface.parameters, parameters3);
3247
3977
  surface.owner.setAttribute("data-sf-shader-params", JSON.stringify(surface.parameters));
3248
- renderSurface(surface, seconds);
3249
3978
  changed = true;
3250
3979
  }
3980
+ if (changed) {
3981
+ updateReactiveLightFields(surfaces);
3982
+ for (const surface of surfaces) {
3983
+ renderSurface(surface, seconds);
3984
+ }
3985
+ }
3251
3986
  return changed;
3252
3987
  }
3253
3988
  function watchSvgChanges(svg, view, onChange) {
@@ -3272,6 +4007,7 @@ function mountShaderSurfaces(svg) {
3272
4007
  const clock = createSurfaceClock(view);
3273
4008
  const draw = (milliseconds) => {
3274
4009
  if (!clock.paused()) {
4010
+ updateReactiveLightFields(surfaces);
3275
4011
  for (const surface of surfaces) {
3276
4012
  renderSurface(surface, milliseconds / 1e3 - clock.spent());
3277
4013
  }
@@ -3315,12 +4051,41 @@ function mountShaderSurfaces(svg) {
3315
4051
  frame = view.requestAnimationFrame(draw);
3316
4052
  };
3317
4053
  const refresh = () => {
4054
+ const previousState = new Map(
4055
+ surfaces.flatMap((surface) => {
4056
+ const ownerId = surface.owner.getAttribute("data-sf-id");
4057
+ return ownerId ? [
4058
+ [
4059
+ ownerId,
4060
+ {
4061
+ smoothed: new Map(surface.smoothed),
4062
+ reactiveLight: surface.reactiveLight,
4063
+ pointer: surface.pointer,
4064
+ hover: surface.hover,
4065
+ hovering: surface.hovering,
4066
+ trail: surface.trail
4067
+ }
4068
+ ]
4069
+ ] : [];
4070
+ })
4071
+ );
3318
4072
  stop();
3319
4073
  const generation = ++backdropGeneration;
3320
4074
  surfaces = [...svg.querySelectorAll("canvas[data-sf-shader-canvas]")].flatMap((canvas) => {
3321
4075
  const surface = createSurface(canvas);
4076
+ const ownerId = surface?.owner.getAttribute("data-sf-id");
4077
+ const previous = ownerId ? previousState.get(ownerId) : void 0;
4078
+ if (surface && previous) {
4079
+ surface.smoothed = previous.smoothed;
4080
+ surface.reactiveLight = previous.reactiveLight;
4081
+ surface.pointer = previous.pointer;
4082
+ surface.hover = previous.hover;
4083
+ surface.hovering = previous.hovering;
4084
+ surface.trail = previous.trail;
4085
+ }
3322
4086
  return surface ? [surface] : [];
3323
4087
  });
4088
+ updateReactiveLightFields(surfaces);
3324
4089
  captureBackdrops(generation);
3325
4090
  if (surfaces.length > 0) {
3326
4091
  startFrames();
@@ -3336,10 +4101,37 @@ function mountShaderSurfaces(svg) {
3336
4101
  }, RECAPTURE_DELAY_MS);
3337
4102
  };
3338
4103
  const unwatch = watchSvgChanges(svg, view, scheduleRecapture);
4104
+ const track = (event) => {
4105
+ for (const surface of surfaces) {
4106
+ const box = surface.canvas.getBoundingClientRect();
4107
+ const inside = box.width > 0 && box.height > 0 && event.clientX >= box.left && event.clientX <= box.right && event.clientY >= box.top && event.clientY <= box.bottom;
4108
+ surface.hovering = inside;
4109
+ if (inside) {
4110
+ surface.pointer = { x: (event.clientX - box.left) / box.width, y: 1 - (event.clientY - box.top) / box.height };
4111
+ const now = clock.now();
4112
+ const last = surface.trail[surface.trail.length - 1];
4113
+ if (!last || now - last.at >= TRAIL_SPACING) {
4114
+ surface.trail.push({ ...surface.pointer, at: now });
4115
+ if (surface.trail.length > TRAIL_LENGTH2) {
4116
+ surface.trail.shift();
4117
+ }
4118
+ }
4119
+ }
4120
+ }
4121
+ };
4122
+ const leave = () => {
4123
+ for (const surface of surfaces) {
4124
+ surface.hovering = false;
4125
+ }
4126
+ };
4127
+ svg.addEventListener("pointermove", track);
4128
+ svg.addEventListener("pointerleave", leave);
3339
4129
  refresh();
3340
4130
  const destroy = () => {
3341
4131
  backdropGeneration += 1;
3342
4132
  unwatch();
4133
+ svg.removeEventListener("pointermove", track);
4134
+ svg.removeEventListener("pointerleave", leave);
3343
4135
  if (recapture !== void 0) {
3344
4136
  view?.clearTimeout(recapture);
3345
4137
  }
@@ -3602,6 +4394,22 @@ function trackScales(wiring, event) {
3602
4394
  }
3603
4395
  }
3604
4396
  }
4397
+ function driveValue(wiring, id, event) {
4398
+ const { runtime, svg } = wiring;
4399
+ const kind = getComponentDescriptor(runtime.graph.elements.get(id)?.componentType)?.interaction;
4400
+ if (kind !== "slide" && kind !== "pick" && kind !== "turn" && kind !== "range") {
4401
+ return;
4402
+ }
4403
+ const node = svg.querySelector(`[data-sf-primary][data-sf-id="${CSS.escape(id)}"]`);
4404
+ if (!node) {
4405
+ return;
4406
+ }
4407
+ const box = node.getBoundingClientRect();
4408
+ if (box.width > 0 && box.height > 0) {
4409
+ const within = (value) => Math.min(1, Math.max(0, value));
4410
+ runtime.slide(id, within((event.clientX - box.left) / box.width), within((event.clientY - box.top) / box.height));
4411
+ }
4412
+ }
3605
4413
  function updateHover(wiring, event) {
3606
4414
  const { runtime, svg, options, session } = wiring;
3607
4415
  const over = options.enabled?.() === false ? null : hit(svg, runtime.interactive.pressable, event.clientX, event.clientY);
@@ -3633,6 +4441,7 @@ function pressStart(wiring, event) {
3633
4441
  session.active = id;
3634
4442
  trackScales(wiring, event);
3635
4443
  runtime.press(id);
4444
+ driveValue(wiring, id, event);
3636
4445
  runtime.drag(id);
3637
4446
  }
3638
4447
  function pressMove(wiring, event) {
@@ -3642,6 +4451,7 @@ function pressMove(wiring, event) {
3642
4451
  return;
3643
4452
  }
3644
4453
  trackScales(wiring, event);
4454
+ driveValue(wiring, session.active, event);
3645
4455
  runtime.drag(session.active);
3646
4456
  }
3647
4457
  function pressEnd(wiring, event, tapOnElement) {
@@ -3721,5 +4531,5 @@ function createViewer(options) {
3721
4531
  }
3722
4532
 
3723
4533
  export { SHADER_DEFAULTS, connectInteraction, createViewer, registerShaderProgram, shaderProgram };
3724
- //# sourceMappingURL=chunk-WRDVNMFS.js.map
3725
- //# sourceMappingURL=chunk-WRDVNMFS.js.map
4534
+ //# sourceMappingURL=chunk-EDOPENSE.js.map
4535
+ //# sourceMappingURL=chunk-EDOPENSE.js.map