@iamahmarfaraz/react-liquid-bg 1.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 ADDED
@@ -0,0 +1,161 @@
1
+ # react-liquid-bg
2
+
3
+ A high-performance WebGL liquid fluid background component for React.
4
+
5
+ Built and maintained by **Ahmar Faraz**.
6
+
7
+ `react-liquid-bg` provides a real-time, GPU-accelerated liquid simulation using WebGL and GLSL shaders.
8
+ It is designed for production React applications where visuals, performance, and clean architecture matter.
9
+
10
+ This is **not** a CSS animation or video background.
11
+ This is a real fluid simulation running entirely on the GPU.
12
+
13
+ ---
14
+
15
+ ## Features
16
+
17
+ - Real-time WebGL fluid simulation
18
+ - GPU-accelerated shader pipeline
19
+ - Interactive mouse-based fluid motion
20
+ - Full-screen responsive canvas
21
+ - Simple React component API
22
+ - Zero external animation libraries
23
+ - Production-grade architecture
24
+
25
+ ---
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ npm install react-liquid-bg
31
+ ```
32
+
33
+ or
34
+
35
+ ```bash
36
+ yarn add react-liquid-bg
37
+ ```
38
+
39
+ ---
40
+
41
+ ## Basic Usage
42
+
43
+ ```jsx
44
+ import LiquidBG from "react-liquid-bg";
45
+
46
+ function App() {
47
+ return (
48
+ <div className="relative min-h-screen">
49
+ <LiquidBG enabled={true} />
50
+ <div className="relative z-10">Your App Content</div>
51
+ </div>
52
+ );
53
+ }
54
+
55
+ export default App;
56
+ ```
57
+
58
+ ---
59
+
60
+ ## Conditional Usage
61
+
62
+ ```jsx
63
+ <LiquidBG enabled={tab === null} />
64
+ ```
65
+
66
+ The simulation starts when `enabled` is true and pauses when false.
67
+
68
+ ---
69
+
70
+ ## Props
71
+
72
+ | Prop | Type | Required | Description |
73
+ |-----|------|----------|-------------|
74
+ | enabled | boolean | Yes | Starts or pauses the fluid simulation |
75
+
76
+ ---
77
+
78
+ ## How It Works
79
+
80
+ The engine is a custom WebGL fluid solver using:
81
+
82
+ - Velocity advection
83
+ - Density advection
84
+ - Pressure solving
85
+ - Curl and vorticity forces
86
+ - Double framebuffer (ping-pong) rendering
87
+ - GLSL fragment shaders
88
+
89
+ All heavy computation is done on the GPU for maximum performance.
90
+
91
+ ---
92
+
93
+ ## Architecture Overview
94
+
95
+ ### React Layer
96
+ - Exposes `<LiquidBG />`
97
+ - Controls lifecycle and canvas mount
98
+ - No re-renders during simulation
99
+
100
+ ### Engine Layer
101
+ - WebGL context initialization
102
+ - Shader compilation and linking
103
+ - Framebuffer and texture management
104
+
105
+ ### Simulation Layer
106
+ - Velocity field updates
107
+ - Pressure correction
108
+ - Vorticity and curl
109
+ - Density transport
110
+
111
+ ### Rendering Layer
112
+ - Shader-based rendering
113
+ - Optional bloom and dithering
114
+ - Fullscreen adaptive scaling
115
+
116
+ ---
117
+
118
+ ## Interaction
119
+
120
+ - Mouse movement injects force
121
+ - Clicks generate splats
122
+ - Idle state keeps subtle motion
123
+ - Auto-resizes on window resize
124
+
125
+ ---
126
+
127
+ ## Performance
128
+
129
+ - Fully GPU-driven
130
+ - No React state updates per frame
131
+ - Optimized shaders and buffers
132
+ - Suitable for production apps
133
+
134
+ ---
135
+
136
+ ## Browser Support
137
+
138
+ - Chrome (recommended)
139
+ - Edge
140
+ - Firefox (WebGL enabled)
141
+ - Safari (WebGL enabled)
142
+
143
+ ---
144
+
145
+ ## License
146
+
147
+ MIT License
148
+
149
+ ---
150
+
151
+ ## Author
152
+
153
+ **Ahmar Faraz**
154
+ Software Engineer
155
+
156
+ GitHub: https://github.com/iamahmarfaraz
157
+ LinkedIn: https://www.linkedin.com/in/iamahmarfaraz/
158
+
159
+ ---
160
+
161
+ If you use this library in production, attribution is appreciated.
@@ -0,0 +1,403 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const re=require("react");var ee={exports:{}},V={};var oe;function ce(){if(oe)return V;oe=1;var f=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function r(i,v,n){var x=null;if(n!==void 0&&(x=""+n),v.key!==void 0&&(x=""+v.key),"key"in v){n={};for(var P in v)P!=="key"&&(n[P]=v[P])}else n=v;return v=n.ref,{$$typeof:f,type:i,key:x,ref:v!==void 0?v:null,props:n}}return V.Fragment=e,V.jsx=r,V.jsxs=r,V}var K={};var ae;function ve(){return ae||(ae=1,process.env.NODE_ENV!=="production"&&(function(){function f(t){if(t==null)return null;if(typeof t=="function")return t.$$typeof===w?null:t.displayName||t.name||null;if(typeof t=="string")return t;switch(t){case S:return"Fragment";case E:return"Profiler";case D:return"StrictMode";case C:return"Suspense";case b:return"SuspenseList";case Q:return"Activity"}if(typeof t=="object")switch(typeof t.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),t.$$typeof){case N:return"Portal";case Z:return t.displayName||"Context";case B:return(t._context.displayName||"Context")+".Consumer";case A:var m=t.render;return t=t.displayName,t||(t=m.displayName||m.name||"",t=t!==""?"ForwardRef("+t+")":"ForwardRef"),t;case j:return m=t.displayName||null,m!==null?m:f(t.type)||"Memo";case X:m=t._payload,t=t._init;try{return f(t(m))}catch{}}return null}function e(t){return""+t}function r(t){try{e(t);var m=!1}catch{m=!0}if(m){m=console;var o=m.error,a=typeof Symbol=="function"&&Symbol.toStringTag&&t[Symbol.toStringTag]||t.constructor.name||"Object";return o.call(m,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",a),e(t)}}function i(t){if(t===S)return"<>";if(typeof t=="object"&&t!==null&&t.$$typeof===X)return"<...>";try{var m=f(t);return m?"<"+m+">":"<...>"}catch{return"<...>"}}function v(){var t=Y.A;return t===null?null:t.getOwner()}function n(){return Error("react-stack-top-frame")}function x(t){if($.call(t,"key")){var m=Object.getOwnPropertyDescriptor(t,"key").get;if(m&&m.isReactWarning)return!1}return t.key!==void 0}function P(t,m){function o(){H||(H=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",m))}o.isReactWarning=!0,Object.defineProperty(t,"key",{get:o,configurable:!0})}function k(){var t=f(this.type);return O[t]||(O[t]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),t=this.props.ref,t!==void 0?t:null}function c(t,m,o,a,u,s){var l=o.ref;return t={$$typeof:F,type:t,key:m,props:o,_owner:a},(l!==void 0?l:null)!==null?Object.defineProperty(t,"ref",{enumerable:!1,get:k}):Object.defineProperty(t,"ref",{enumerable:!1,value:null}),t._store={},Object.defineProperty(t._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(t,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(t,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:u}),Object.defineProperty(t,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:s}),Object.freeze&&(Object.freeze(t.props),Object.freeze(t)),t}function U(t,m,o,a,u,s){var l=m.children;if(l!==void 0)if(a)if(te(l)){for(a=0;a<l.length;a++)J(l[a]);Object.freeze&&Object.freeze(l)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else J(l);if($.call(m,"key")){l=f(t);var g=Object.keys(m).filter(function(T){return T!=="key"});a=0<g.length?"{key: someKey, "+g.join(": ..., ")+": ...}":"{key: someKey}",G[l+a]||(g=0<g.length?"{"+g.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
2
+ let props = %s;
3
+ <%s {...props} />
4
+ React keys must be passed directly to JSX without using spread:
5
+ let props = %s;
6
+ <%s key={someKey} {...props} />`,a,l,g,l),G[l+a]=!0)}if(l=null,o!==void 0&&(r(o),l=""+o),x(m)&&(r(m.key),l=""+m.key),"key"in m){o={};for(var p in m)p!=="key"&&(o[p]=m[p])}else o=m;return l&&P(o,typeof t=="function"?t.displayName||t.name||"Unknown":t),c(t,l,o,v(),u,s)}function J(t){y(t)?t._store&&(t._store.validated=1):typeof t=="object"&&t!==null&&t.$$typeof===X&&(t._payload.status==="fulfilled"?y(t._payload.value)&&t._payload.value._store&&(t._payload.value._store.validated=1):t._store&&(t._store.validated=1))}function y(t){return typeof t=="object"&&t!==null&&t.$$typeof===F}var d=re,F=Symbol.for("react.transitional.element"),N=Symbol.for("react.portal"),S=Symbol.for("react.fragment"),D=Symbol.for("react.strict_mode"),E=Symbol.for("react.profiler"),B=Symbol.for("react.consumer"),Z=Symbol.for("react.context"),A=Symbol.for("react.forward_ref"),C=Symbol.for("react.suspense"),b=Symbol.for("react.suspense_list"),j=Symbol.for("react.memo"),X=Symbol.for("react.lazy"),Q=Symbol.for("react.activity"),w=Symbol.for("react.client.reference"),Y=d.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,$=Object.prototype.hasOwnProperty,te=Array.isArray,M=console.createTask?console.createTask:function(){return null};d={react_stack_bottom_frame:function(t){return t()}};var H,O={},L=d.react_stack_bottom_frame.bind(d,n)(),W=M(i(n)),G={};K.Fragment=S,K.jsx=function(t,m,o){var a=1e4>Y.recentlyCreatedOwnerStacks++;return U(t,m,o,!1,a?Error("react-stack-top-frame"):L,a?M(i(t)):W)},K.jsxs=function(t,m,o){var a=1e4>Y.recentlyCreatedOwnerStacks++;return U(t,m,o,!0,a?Error("react-stack-top-frame"):L,a?M(i(t)):W)}})()),K}var ne;function de(){return ne||(ne=1,process.env.NODE_ENV==="production"?ee.exports=ce():ee.exports=ve()),ee.exports}var ge=de();let q={sim_resolution:128,dye_resolution:512,paused:!1,clamp_values:!0,embedded_dither:!0,dissipation:.985,velocity:.995,pressure:.8,pressure_iteration:20,fluid_color:[[0,0,0],[.4,.2,0]],curl:15,emitter_size:.6,render_shaders:!0,multi_color:!0,render_bloom:!1,bloom_iterations:8,bloom_resolution:256,intensity:.8,threshold:.6,soft_knee:.7,background_color:{r:15,g:15,b:15},transparent:!0};const ie={alpha:!0,depth:!1,stencil:!1,antialias:!1,preserveDrawingBuffer:!1,powerPreference:"default"},_={vertex:`
7
+ precision highp float;
8
+
9
+ attribute vec2 aPosition;
10
+ varying vec2 vUv;
11
+ varying vec2 vL;
12
+ varying vec2 vR;
13
+ varying vec2 vT;
14
+ varying vec2 vB;
15
+ uniform vec2 texelSize;
16
+
17
+ void main () {
18
+ vUv = aPosition * 0.5 + 0.5;
19
+ vL = vUv - vec2(texelSize.x, 0.0);
20
+ vR = vUv + vec2(texelSize.x, 0.0);
21
+ vT = vUv + vec2(0.0, texelSize.y);
22
+ vB = vUv - vec2(0.0, texelSize.y);
23
+ gl_Position = vec4(aPosition, 0.0, 1.0);
24
+ }`,clear:`
25
+ precision mediump float;
26
+ precision mediump sampler2D;
27
+
28
+ varying highp vec2 vUv;
29
+ uniform sampler2D uTexture;
30
+ uniform float value;
31
+
32
+ void main () {
33
+ gl_FragColor = value * texture2D(uTexture, vUv);
34
+ }
35
+ `,color:`
36
+ precision mediump float;
37
+
38
+ uniform vec4 color;
39
+
40
+ void main () {
41
+ gl_FragColor = color;
42
+ }
43
+ `,background:`
44
+ void main() {
45
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
46
+ }
47
+ `,display:`
48
+ precision highp float;
49
+ precision highp sampler2D;
50
+
51
+ varying vec2 vUv;
52
+ uniform sampler2D uTexture;
53
+
54
+ void main () {
55
+ vec3 C = texture2D(uTexture, vUv).rgb;
56
+ float a = max(C.r, max(C.g, C.b));
57
+ gl_FragColor = vec4(C, a);
58
+ }
59
+ `,displayBloom:`
60
+ precision highp float;
61
+ precision highp sampler2D;
62
+
63
+ varying vec2 vUv;
64
+ uniform sampler2D uTexture;
65
+ uniform sampler2D uBloom;
66
+ uniform sampler2D uDithering;
67
+ uniform vec2 ditherScale;
68
+
69
+ void main () {
70
+ vec3 C = texture2D(uTexture, vUv).rgb;
71
+ vec3 bloom = texture2D(uBloom, vUv).rgb;
72
+ vec3 noise = texture2D(uDithering, vUv * ditherScale).rgb;
73
+ noise = noise * 2.0 - 1.0;
74
+ bloom += noise / 800.0;
75
+ bloom = pow(bloom.rgb, vec3(1.0 / 2.2));
76
+ C += bloom;
77
+ float a = max(C.r, max(C.g, C.b));
78
+ gl_FragColor = vec4(C, a);
79
+ }
80
+ `,displayShading:`
81
+ precision highp float;
82
+ precision highp sampler2D;
83
+
84
+ varying vec2 vUv;
85
+ varying vec2 vL;
86
+ varying vec2 vR;
87
+ varying vec2 vT;
88
+ varying vec2 vB;
89
+ uniform sampler2D uTexture;
90
+ uniform vec2 texelSize;
91
+
92
+ void main () {
93
+ vec3 L = texture2D(uTexture, vL).rgb;
94
+ vec3 R = texture2D(uTexture, vR).rgb;
95
+ vec3 T = texture2D(uTexture, vT).rgb;
96
+ vec3 B = texture2D(uTexture, vB).rgb;
97
+ vec3 C = texture2D(uTexture, vUv).rgb;
98
+
99
+ float dx = length(R) - length(L);
100
+ float dy = length(T) - length(B);
101
+
102
+ vec3 n = normalize(vec3(dx, dy, length(texelSize)));
103
+ vec3 l = vec3(0.0, 0.0, 1.0);
104
+
105
+ float diffuse = clamp(dot(n, l) + 0.7, 0.7, 1.0);
106
+ C.rgb *= diffuse;
107
+
108
+ float a = max(C.r, max(C.g, C.b));
109
+ gl_FragColor = vec4(C, a);
110
+ }
111
+ `,displayBloomShading:`
112
+ precision highp float;
113
+ precision highp sampler2D;
114
+
115
+ varying vec2 vUv;
116
+ varying vec2 vL;
117
+ varying vec2 vR;
118
+ varying vec2 vT;
119
+ varying vec2 vB;
120
+ uniform sampler2D uTexture;
121
+ uniform sampler2D uBloom;
122
+ uniform sampler2D uDithering;
123
+ uniform vec2 ditherScale;
124
+ uniform vec2 texelSize;
125
+
126
+ void main () {
127
+ vec3 L = texture2D(uTexture, vL).rgb;
128
+ vec3 R = texture2D(uTexture, vR).rgb;
129
+ vec3 T = texture2D(uTexture, vT).rgb;
130
+ vec3 B = texture2D(uTexture, vB).rgb;
131
+ vec3 C = texture2D(uTexture, vUv).rgb;
132
+
133
+ float dx = length(R) - length(L);
134
+ float dy = length(T) - length(B);
135
+
136
+ vec3 n = normalize(vec3(dx, dy, length(texelSize)));
137
+ vec3 l = vec3(0.0, 0.0, 1.0);
138
+
139
+ float diffuse = clamp(dot(n, l) + 0.7, 0.7, 1.0);
140
+ C *= diffuse;
141
+
142
+ vec3 bloom = texture2D(uBloom, vUv).rgb;
143
+ vec3 noise = texture2D(uDithering, vUv * ditherScale).rgb;
144
+ noise = noise * 2.0 - 1.0;
145
+ bloom += noise / 800.0;
146
+ bloom = pow(bloom.rgb, vec3(1.0 / 2.2));
147
+ C += bloom;
148
+
149
+ float a = max(C.r, max(C.g, C.b));
150
+ gl_FragColor = vec4(C, a);
151
+ }
152
+ `,bloomPreFilter:`
153
+ precision mediump float;
154
+ precision mediump sampler2D;
155
+
156
+ varying vec2 vUv;
157
+ uniform sampler2D uTexture;
158
+ uniform vec3 curve;
159
+ uniform float threshold;
160
+
161
+ void main () {
162
+ vec3 c = texture2D(uTexture, vUv).rgb;
163
+ float br = max(c.r, max(c.g, c.b));
164
+ float rq = clamp(br - curve.x, 0.0, curve.y);
165
+ rq = curve.z * rq * rq;
166
+ c *= max(rq, br - threshold) / max(br, 0.0001);
167
+ gl_FragColor = vec4(c, 0.0);
168
+ }
169
+ `,bloomBlur:`
170
+ precision mediump float;
171
+ precision mediump sampler2D;
172
+
173
+ varying vec2 vL;
174
+ varying vec2 vR;
175
+ varying vec2 vT;
176
+ varying vec2 vB;
177
+ uniform sampler2D uTexture;
178
+
179
+ void main () {
180
+ vec4 sum = vec4(0.0);
181
+ sum += texture2D(uTexture, vL);
182
+ sum += texture2D(uTexture, vR);
183
+ sum += texture2D(uTexture, vT);
184
+ sum += texture2D(uTexture, vB);
185
+ sum *= 0.25;
186
+ gl_FragColor = sum;
187
+ }
188
+ `,bloomFinal:`
189
+ precision mediump float;
190
+ precision mediump sampler2D;
191
+
192
+ varying vec2 vL;
193
+ varying vec2 vR;
194
+ varying vec2 vT;
195
+ varying vec2 vB;
196
+ uniform sampler2D uTexture;
197
+ uniform float intensity;
198
+
199
+ void main () {
200
+ vec4 sum = vec4(0.0);
201
+ sum += texture2D(uTexture, vL);
202
+ sum += texture2D(uTexture, vR);
203
+ sum += texture2D(uTexture, vT);
204
+ sum += texture2D(uTexture, vB);
205
+ sum *= 0.25;
206
+ gl_FragColor = sum * intensity;
207
+ }
208
+ `,splat:`
209
+ precision highp float;
210
+ precision highp sampler2D;
211
+
212
+ varying vec2 vUv;
213
+ uniform sampler2D uTarget;
214
+ uniform float aspectRatio;
215
+ uniform vec3 color;
216
+ uniform vec2 point;
217
+ uniform float radius;
218
+
219
+ void main () {
220
+ vec2 p = vUv - point.xy;
221
+ p.x *= aspectRatio;
222
+ vec3 splat = exp(-dot(p, p) / radius) * color;
223
+ vec3 base = texture2D(uTarget, vUv).xyz;
224
+ gl_FragColor = vec4(base + splat, 1.0);
225
+ }
226
+ `,advectionManualFiltering:`
227
+ precision highp float;
228
+ precision highp sampler2D;
229
+
230
+ varying vec2 vUv;
231
+ uniform sampler2D uVelocity;
232
+ uniform sampler2D uSource;
233
+ uniform vec2 texelSize;
234
+ uniform vec2 dyeTexelSize;
235
+ uniform float dt;
236
+ uniform float dissipation;
237
+
238
+ vec4 bilerp (sampler2D sam, vec2 uv, vec2 tsize) {
239
+ vec2 st = uv / tsize - 0.5;
240
+
241
+ vec2 iuv = floor(st);
242
+ vec2 fuv = fract(st);
243
+
244
+ vec4 a = texture2D(sam, (iuv + vec2(0.5, 0.5)) * tsize);
245
+ vec4 b = texture2D(sam, (iuv + vec2(1.5, 0.5)) * tsize);
246
+ vec4 c = texture2D(sam, (iuv + vec2(0.5, 1.5)) * tsize);
247
+ vec4 d = texture2D(sam, (iuv + vec2(1.5, 1.5)) * tsize);
248
+
249
+ return mix(mix(a, b, fuv.x), mix(c, d, fuv.x), fuv.y);
250
+ }
251
+
252
+ void main () {
253
+ vec2 coord = vUv - dt * bilerp(uVelocity, vUv, texelSize).xy * texelSize;
254
+ gl_FragColor = dissipation * bilerp(uSource, coord, dyeTexelSize);
255
+ gl_FragColor.a = 1.0;
256
+ }
257
+ `,advection:`
258
+ precision highp float;
259
+ precision highp sampler2D;
260
+
261
+ varying vec2 vUv;
262
+ uniform sampler2D uVelocity;
263
+ uniform sampler2D uSource;
264
+ uniform vec2 texelSize;
265
+ uniform float dt;
266
+ uniform float dissipation;
267
+
268
+ void main () {
269
+ vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;
270
+ gl_FragColor = dissipation * texture2D(uSource, coord);
271
+ gl_FragColor.a = 1.0;
272
+ }
273
+ `,divergence:`
274
+ precision mediump float;
275
+ precision mediump sampler2D;
276
+
277
+ varying highp vec2 vUv;
278
+ varying highp vec2 vL;
279
+ varying highp vec2 vR;
280
+ varying highp vec2 vT;
281
+ varying highp vec2 vB;
282
+ uniform sampler2D uVelocity;
283
+
284
+ void main () {
285
+ float L = texture2D(uVelocity, vL).x;
286
+ float R = texture2D(uVelocity, vR).x;
287
+ float T = texture2D(uVelocity, vT).y;
288
+ float B = texture2D(uVelocity, vB).y;
289
+
290
+ vec2 C = texture2D(uVelocity, vUv).xy;
291
+ if (vL.x < 0.0) { L = -C.x; }
292
+ if (vR.x > 1.0) { R = -C.x; }
293
+ if (vT.y > 1.0) { T = -C.y; }
294
+ if (vB.y < 0.0) { B = -C.y; }
295
+
296
+ float div = 0.5 * (R - L + T - B);
297
+ gl_FragColor = vec4(div, 0.0, 0.0, 1.0);
298
+ }
299
+ `,curl:`
300
+ precision mediump float;
301
+ precision mediump sampler2D;
302
+
303
+ varying highp vec2 vUv;
304
+ varying highp vec2 vL;
305
+ varying highp vec2 vR;
306
+ varying highp vec2 vT;
307
+ varying highp vec2 vB;
308
+ uniform sampler2D uVelocity;
309
+
310
+ void main () {
311
+ float L = texture2D(uVelocity, vL).y;
312
+ float R = texture2D(uVelocity, vR).y;
313
+ float T = texture2D(uVelocity, vT).x;
314
+ float B = texture2D(uVelocity, vB).x;
315
+ float vorticity = R - L - T + B;
316
+ gl_FragColor = vec4(0.5 * vorticity, 0.0, 0.0, 1.0);
317
+ }
318
+ `,vorticity:`
319
+ precision highp float;
320
+ precision highp sampler2D;
321
+
322
+ varying vec2 vUv;
323
+ varying vec2 vL;
324
+ varying vec2 vR;
325
+ varying vec2 vT;
326
+ varying vec2 vB;
327
+ uniform sampler2D uVelocity;
328
+ uniform sampler2D uCurl;
329
+ uniform float curl;
330
+ uniform float dt;
331
+
332
+ void main () {
333
+ float L = texture2D(uCurl, vL).x;
334
+ float R = texture2D(uCurl, vR).x;
335
+ float T = texture2D(uCurl, vT).x;
336
+ float B = texture2D(uCurl, vB).x;
337
+ float C = texture2D(uCurl, vUv).x;
338
+
339
+ vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));
340
+ force /= length(force) + 0.0001;
341
+ force *= curl * C;
342
+ force.y *= -1.0;
343
+
344
+ vec2 vel = texture2D(uVelocity, vUv).xy;
345
+ gl_FragColor = vec4(vel + force * dt, 0.0, 1.0);
346
+ }
347
+ `,pressure:`
348
+ precision mediump float;
349
+ precision mediump sampler2D;
350
+
351
+ varying highp vec2 vUv;
352
+ varying highp vec2 vL;
353
+ varying highp vec2 vR;
354
+ varying highp vec2 vT;
355
+ varying highp vec2 vB;
356
+ uniform sampler2D uPressure;
357
+ uniform sampler2D uDivergence;
358
+
359
+ vec2 boundary (vec2 uv) {
360
+ return uv;
361
+ // uncomment if you use wrap or repeat texture mode
362
+ // uv = min(max(uv, 0.0), 1.0);
363
+ // return uv;
364
+ }
365
+
366
+ void main () {
367
+ float L = texture2D(uPressure, boundary(vL)).x;
368
+ float R = texture2D(uPressure, boundary(vR)).x;
369
+ float T = texture2D(uPressure, boundary(vT)).x;
370
+ float B = texture2D(uPressure, boundary(vB)).x;
371
+ float C = texture2D(uPressure, vUv).x;
372
+ float divergence = texture2D(uDivergence, vUv).x;
373
+ float pressure = (L + R + B + T - divergence) * 0.25;
374
+ gl_FragColor = vec4(pressure, 0.0, 0.0, 1.0);
375
+ }
376
+ `,gradientSubtract:`
377
+ precision mediump float;
378
+ precision mediump sampler2D;
379
+
380
+ varying highp vec2 vUv;
381
+ varying highp vec2 vL;
382
+ varying highp vec2 vR;
383
+ varying highp vec2 vT;
384
+ varying highp vec2 vB;
385
+ uniform sampler2D uPressure;
386
+ uniform sampler2D uVelocity;
387
+
388
+ vec2 boundary (vec2 uv) {
389
+ return uv;
390
+ // uv = min(max(uv, 0.0), 1.0);
391
+ // return uv;
392
+ }
393
+
394
+ void main () {
395
+ float L = texture2D(uPressure, boundary(vL)).x;
396
+ float R = texture2D(uPressure, boundary(vR)).x;
397
+ float T = texture2D(uPressure, boundary(vT)).x;
398
+ float B = texture2D(uPressure, boundary(vB)).x;
399
+ vec2 velocity = texture2D(uVelocity, vUv).xy;
400
+ velocity.xy -= vec2(R - L, T - B);
401
+ gl_FragColor = vec4(velocity, 0.0, 1.0);
402
+ }
403
+ `};function he(f){Object.assign(q,f)}const ue="data:image/png;base64,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";let le=!1;function pe(f){let e=[];e.push(new se);let r=f.getContext("webgl2",ie);const i=!!r;i||(r=f.getContext("webgl",ie)||f.getContext("experimental-webgl",ie));let v=k();P()&&(q.render_shaders=!1),v.supportLinearFiltering||(q.render_shaders=!1,q.render_bloom=!1);const n={baseVertex:c(r.VERTEX_SHADER,_.vertex),clear:c(r.FRAGMENT_SHADER,_.clear),color:c(r.FRAGMENT_SHADER,_.color),background:c(r.FRAGMENT_SHADER,_.background),display:c(r.FRAGMENT_SHADER,_.display),displayBloom:c(r.FRAGMENT_SHADER,_.displayBloom),displayShading:c(r.FRAGMENT_SHADER,_.displayShading),displayBloomShading:c(r.FRAGMENT_SHADER,_.displayBloomShading),bloomPreFilter:c(r.FRAGMENT_SHADER,_.bloomPreFilter),bloomBlur:c(r.FRAGMENT_SHADER,_.bloomBlur),bloomFinal:c(r.FRAGMENT_SHADER,_.bloomFinal),splat:c(r.FRAGMENT_SHADER,_.splat),advectionManualFiltering:c(r.FRAGMENT_SHADER,_.advectionManualFiltering),advection:c(r.FRAGMENT_SHADER,_.advection),divergence:c(r.FRAGMENT_SHADER,_.divergence),curl:c(r.FRAGMENT_SHADER,_.curl),vorticity:c(r.FRAGMENT_SHADER,_.vorticity),pressure:c(r.FRAGMENT_SHADER,_.pressure),gradientSubtract:c(r.FRAGMENT_SHADER,_.gradientSubtract)};let x=U(v.supportLinearFiltering);function P(){return/Mobi|Android/i.test(navigator.userAgent)}function k(){let J,y,d,F,N;i?(r.getExtension("EXT_color_buffer_float"),N=r.getExtension("OES_texture_float_linear")):(F=r.getExtension("OES_texture_half_float"),N=r.getExtension("OES_texture_half_float_linear"));const S=i?r.HALF_FLOAT:F.HALF_FLOAT_OES;r.clearColor(0,0,0,1),i?(J=D(r.RGBA16F,r.RGBA,S),y=D(r.RG16F,r.RG,S),d=D(r.R16F,r.RED,S)):(J=D(r.RGBA,r.RGBA,S),y=D(r.RGBA,r.RGBA,S),d=D(r.RGBA,r.RGBA,S));function D(E,B,Z){let A,C=r.createTexture();r.bindTexture(r.TEXTURE_2D,C),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MIN_FILTER,r.NEAREST),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MAG_FILTER,r.NEAREST),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_S,r.CLAMP_TO_EDGE),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_T,r.CLAMP_TO_EDGE),r.texImage2D(r.TEXTURE_2D,0,E,4,4,0,B,Z,null);let b=r.createFramebuffer();if(r.bindFramebuffer(r.FRAMEBUFFER,b),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,C,0),A=r.checkFramebufferStatus(r.FRAMEBUFFER)===r.FRAMEBUFFER_COMPLETE,!A)switch(E){case r.R16F:return D(r.RG16F,r.RG,Z);case r.RG16F:return D(r.RGBA16F,r.RGBA,Z);default:return null}return{internalFormat:E,format:B}}return{formatRGBA:J,formatRG:y,formatR:d,halfFloatTexType:S,supportLinearFiltering:N}}function c(J,y){const d=r.createShader(J);if(r.shaderSource(d,y),r.compileShader(d),!r.getShaderParameter(d,r.COMPILE_STATUS))throw r.getShaderInfoLog(d);return d}function U(J){return{clearProgram:new R(n.baseVertex,n.clear,r),colorProgram:new R(n.baseVertex,n.color,r),backgroundProgram:new R(n.baseVertex,n.background,r),displayProgram:new R(n.baseVertex,n.display,r),displayBloomProgram:new R(n.baseVertex,n.displayBloom,r),displayShadingProgram:new R(n.baseVertex,n.displayShading,r),displayBloomShadingProgram:new R(n.baseVertex,n.displayBloomShading,r),bloomPreFilterProgram:new R(n.baseVertex,n.bloomPreFilter,r),bloomBlurProgram:new R(n.baseVertex,n.bloomBlur,r),bloomFinalProgram:new R(n.baseVertex,n.bloomFinal,r),splatProgram:new R(n.baseVertex,n.splat,r),advectionProgram:new R(n.baseVertex,J?n.advection:n.advectionManualFiltering,r),divergenceProgram:new R(n.baseVertex,n.divergence,r),curlProgram:new R(n.baseVertex,n.curl,r),vorticityProgram:new R(n.baseVertex,n.vorticity,r),pressureProgram:new R(n.baseVertex,n.pressure,r),gradientSubtractProgram:new R(n.baseVertex,n.gradientSubtract,r)}}return{programs:x,webGL:r,colorFormats:v,pointers:e}}function Te(f,e,r,i,v){if(le){let o=[];o.push(new se),v=o}le=!0;const n=q;let x=[],P=[],k,c,U,J,y,d,F,N,S,D;const E=(e.bindBuffer(e.ARRAY_BUFFER,e.createBuffer()),e.bufferData(e.ARRAY_BUFFER,new Float32Array([-1,-1,-1,1,1,1,1,-1]),e.STATIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,e.createBuffer()),e.bufferData(e.ELEMENT_ARRAY_BUFFER,new Uint16Array([0,1,2,0,2,3]),e.STATIC_DRAW),e.vertexAttribPointer(0,2,e.FLOAT,!1,0,0),e.enableVertexAttribArray(0),o=>{e.bindFramebuffer(e.FRAMEBUFFER,o),e.drawElements(e.TRIANGLES,6,e.UNSIGNED_SHORT,0)});let B=(n.embedded_dither,Q(ue));A(),O(Math.random()*20+5);let Z=Date.now();w();function A(){const o=r.halfFloatTexType,a=r.formatRGBA,u=r.formatRG,s=r.formatR,l=r.supportLinearFiltering?e.LINEAR:e.NEAREST;let g=t(n.sim_resolution),p=t(n.dye_resolution),T=t(n.bloom_resolution);k=g.width,c=g.height,U=p.width,J=p.height,y=y?j(y,U,J,a.internalFormat,a.format,o,l):C(U,J,a.internalFormat,a.format,o,l),d=d?j(d,k,c,u.internalFormat,u.format,o,l):C(k,c,u.internalFormat,u.format,o,l),D=b(T.width,T.height,a.internalFormat,a.format,o,l),F=b(k,c,s.internalFormat,s.format,o,e.NEAREST),N=b(k,c,s.internalFormat,s.format,o,e.NEAREST),S=C(k,c,s.internalFormat,s.format,o,e.NEAREST),x.length=0;for(let h=0;h<n.bloom_iterations;h++){let I=T.width>>h+1,z=T.height>>h+1;if(I<2||z<2)break;let fe=b(I,z,a.internalFormat,a.format,o,l);x.push(fe)}}function C(o,a,u,s,l,g){let p=b(o,a,u,s,l,g),T=b(o,a,u,s,l,g);return{get read(){return p},set read(h){p=h},get write(){return T},set write(h){T=h},swap(){let h=p;p=T,T=h}}}function b(o,a,u,s,l,g){e.activeTexture(e.TEXTURE0);let p=e.createTexture();e.bindTexture(e.TEXTURE_2D,p),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,g),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,g),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,u,o,a,0,s,l,null);let T=e.createFramebuffer();return e.bindFramebuffer(e.FRAMEBUFFER,T),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,p,0),e.viewport(0,0,o,a),e.clear(e.COLOR_BUFFER_BIT),{texture:p,fbo:T,width:o,height:a,attach(h){return e.activeTexture(e.TEXTURE0+h),e.bindTexture(e.TEXTURE_2D,p),h}}}function j(o,a,u,s,l,g,p){return o.read=X(o.read,a,u,s,l,g,p),o.write=b(a,u,s,l,g,p),o}function X(o,a,u,s,l,g,p){let T=b(a,u,s,l,g,p);return i.clearProgram.bind(),e.uniform1i(i.clearProgram.uniforms.uTexture,o.attach(0)),e.uniform1f(i.clearProgram.uniforms.value,1),E(T.fbo),T}function Q(o){let a=e.createTexture();e.bindTexture(e.TEXTURE_2D,a),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.REPEAT),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.REPEAT),e.texImage2D(e.TEXTURE_2D,0,e.RGB,1,1,0,e.RGB,e.UNSIGNED_BYTE,new Uint8Array([255,255,255]));let u={texture:a,width:1,height:1,attach(l){return e.activeTexture(e.TEXTURE0+l),e.bindTexture(e.TEXTURE_2D,a),l}},s=new Image;return s.src=o,s.onload=()=>{u.width=s.width,u.height=s.height,e.bindTexture(e.TEXTURE_2D,a),e.texImage2D(e.TEXTURE_2D,0,e.RGB,e.RGB,e.UNSIGNED_BYTE,s)},u}function w(){L(),Y(),n.paused||$(.016),te(null),requestAnimationFrame(w)}function Y(){P.length>0&&O(P.pop());for(let o=0;o<v.length;o++){const a=v[o];a.moved&&(H(a.x,a.y,a.dx,a.dy,a.color),o!==1&&(a.moved=!1))}if(n.multi_color){if(Z+100<Date.now()){Z=Date.now();for(let o=0;o<v.length;o++){const a=v[o];a.color=W()}}v[0]&&!v[0].moved&&H(f.width*.5,f.height*.5,0,0,{r:0,g:0,b:0})}}function $(o){e.disable(e.BLEND),e.viewport(0,0,k,c),i.curlProgram.bind(),e.uniform2f(i.curlProgram.uniforms.texelSize,1/k,1/c),e.uniform1i(i.curlProgram.uniforms.uVelocity,d.read.attach(0)),E(N.fbo),i.vorticityProgram.bind(),e.uniform2f(i.vorticityProgram.uniforms.texelSize,1/k,1/c),e.uniform1i(i.vorticityProgram.uniforms.uVelocity,d.read.attach(0)),e.uniform1i(i.vorticityProgram.uniforms.uCurl,N.attach(1)),e.uniform1f(i.vorticityProgram.uniforms.curl,n.curl),e.uniform1f(i.vorticityProgram.uniforms.dt,o),E(d.write.fbo),d.swap(),i.divergenceProgram.bind(),e.uniform2f(i.divergenceProgram.uniforms.texelSize,1/k,1/c),e.uniform1i(i.divergenceProgram.uniforms.uVelocity,d.read.attach(0)),E(F.fbo),i.clearProgram.bind(),e.uniform1i(i.clearProgram.uniforms.uTexture,S.read.attach(0)),e.uniform1f(i.clearProgram.uniforms.value,n.pressure),E(S.write.fbo),S.swap(),i.pressureProgram.bind(),e.uniform2f(i.pressureProgram.uniforms.texelSize,1/k,1/c),e.uniform1i(i.pressureProgram.uniforms.uDivergence,F.attach(0));for(let u=0;u<n.pressure_iteration;u++)e.uniform1i(i.pressureProgram.uniforms.uPressure,S.read.attach(1)),E(S.write.fbo),S.swap();i.gradientSubtractProgram.bind(),e.uniform2f(i.gradientSubtractProgram.uniforms.texelSize,1/k,1/c),e.uniform1i(i.gradientSubtractProgram.uniforms.uPressure,S.read.attach(0)),e.uniform1i(i.gradientSubtractProgram.uniforms.uVelocity,d.read.attach(1)),E(d.write.fbo),d.swap(),i.advectionProgram.bind(),e.uniform2f(i.advectionProgram.uniforms.texelSize,1/k,1/c),r.supportLinearFiltering||e.uniform2f(i.advectionProgram.uniforms.dyeTexelSize,1/k,1/c);let a=d.read.attach(0);e.uniform1i(i.advectionProgram.uniforms.uVelocity,a),e.uniform1i(i.advectionProgram.uniforms.uSource,a),e.uniform1f(i.advectionProgram.uniforms.dt,o),e.uniform1f(i.advectionProgram.uniforms.dissipation,n.velocity),E(d.write.fbo),d.swap(),e.viewport(0,0,U,J),r.supportLinearFiltering||e.uniform2f(i.advectionProgram.uniforms.dyeTexelSize,1/U,1/J),e.uniform1i(i.advectionProgram.uniforms.uVelocity,d.read.attach(0)),e.uniform1i(i.advectionProgram.uniforms.uSource,y.read.attach(1)),e.uniform1f(i.advectionProgram.uniforms.dissipation,n.dissipation),E(y.write.fbo),y.swap()}function te(o){n.render_bloom&&M(y.read,D),e.blendFunc(e.ONE,e.ONE_MINUS_SRC_ALPHA),e.enable(e.BLEND);let a=e.drawingBufferWidth,u=e.drawingBufferHeight;if(e.viewport(0,0,a,u),!n.transparent){i.colorProgram.bind();let s=n.background_color;e.uniform4f(i.colorProgram.uniforms.color,s.r/255,s.g/255,s.b/255,1),E(o)}if(n.transparent&&(i.backgroundProgram.bind(),e.uniform1f(i.backgroundProgram.uniforms.aspectRatio,f.width/f.height),E(null)),n.render_shaders){let s=n.render_bloom?i.displayBloomShadingProgram:i.displayShadingProgram;if(s.bind(),e.uniform2f(s.uniforms.texelSize,1/a,1/u),e.uniform1i(s.uniforms.uTexture,y.read.attach(0)),n.render_bloom){e.uniform1i(s.uniforms.uBloom,D.attach(1)),e.uniform1i(s.uniforms.uDithering,B.attach(2));let l=m(B,a,u);e.uniform2f(s.uniforms.ditherScale,l.x,l.y)}}else{let s=n.render_bloom?i.displayBloomProgram:i.displayProgram;if(s.bind(),e.uniform1i(s.uniforms.uTexture,y.read.attach(0)),n.render_bloom){e.uniform1i(s.uniforms.uBloom,D.attach(1)),e.uniform1i(s.uniforms.uDithering,B.attach(2));let l=m(B,a,u);e.uniform2f(s.uniforms.ditherScale,l.x,l.y)}}E(o)}function M(o,a){if(x.length<2)return;let u=a;e.disable(e.BLEND),i.bloomPreFilterProgram.bind();let s=n.threshold*n.soft_knee+1e-4,l=n.threshold-s,g=s*2,p=.25/s;e.uniform3f(i.bloomPreFilterProgram.uniforms.curve,l,g,p),e.uniform1f(i.bloomPreFilterProgram.uniforms.threshold,n.threshold),e.uniform1i(i.bloomPreFilterProgram.uniforms.uTexture,o.attach(0)),e.viewport(0,0,u.width,u.height),E(u.fbo),i.bloomBlurProgram.bind();for(let T=0;T<x.length;T++){let h=x[T];e.uniform2f(i.bloomBlurProgram.uniforms.texelSize,1/u.width,1/u.height),e.uniform1i(i.bloomBlurProgram.uniforms.uTexture,u.attach(0)),e.viewport(0,0,h.width,h.height),E(h.fbo),u=h}e.blendFunc(e.ONE,e.ONE),e.enable(e.BLEND);for(let T=x.length-2;T>=0;T--){let h=x[T];e.uniform2f(i.bloomBlurProgram.uniforms.texelSize,1/u.width,1/u.height),e.uniform1i(i.bloomBlurProgram.uniforms.uTexture,u.attach(0)),e.viewport(0,0,h.width,h.height),E(h.fbo),u=h}e.disable(e.BLEND),i.bloomFinalProgram.bind(),e.uniform2f(i.bloomFinalProgram.uniforms.texelSize,1/u.width,1/u.height),e.uniform1i(i.bloomFinalProgram.uniforms.uTexture,u.attach(0)),e.uniform1f(i.bloomFinalProgram.uniforms.intensity,n.intensity),e.viewport(0,0,a.width,a.height),E(a.fbo)}function H(o,a,u,s,l){e.viewport(0,0,k,c),i.splatProgram.bind(),e.uniform1i(i.splatProgram.uniforms.uTarget,d.read.attach(0)),e.uniform1f(i.splatProgram.uniforms.aspectRatio,f.width/f.height),e.uniform2f(i.splatProgram.uniforms.point,o/f.width,1-a/f.height),e.uniform3f(i.splatProgram.uniforms.color,u,-s,1),e.uniform1f(i.splatProgram.uniforms.radius,n.emitter_size/100),E(d.write.fbo),d.swap(),e.viewport(0,0,U,J),e.uniform1i(i.splatProgram.uniforms.uTarget,y.read.attach(0)),e.uniform3f(i.splatProgram.uniforms.color,l.r,l.g,l.b),E(y.write.fbo),y.swap()}function O(o){for(let a=0;a<o;a++){const u=Math.random()*f.width,s=Math.random()*f.height,l=(Math.random()-.5)*600,g=(Math.random()-.5)*600,p=W();H(u,s,l,g,p)}}function L(){(f.width!=f.clientWidth||f.height!=f.clientHeight)&&(f.width=f.clientWidth,f.height=f.clientHeight,A())}function W(){let o=G(Math.random(),1,1);return o.r*=.15,o.g*=.15,o.b*=.15,o}function G(o,a,u){let s,l,g,p,T,h,I,z;switch(p=Math.floor(o*6),T=o*6-p,h=u*(1-a),I=u*(1-T*a),z=u*(1-(1-T)*a),p%6){case 0:s=u,l=z,g=h;break;case 1:s=I,l=u,g=h;break;case 2:s=h,l=u,g=z;break;case 3:s=h,l=I,g=u;break;case 4:s=z,l=h,g=u;break;case 5:s=u,l=h,g=I;break}return{r:s,g:l,b:g}}function t(o){let a=e.drawingBufferWidth/e.drawingBufferHeight;a<1&&(a=1/a);let u=Math.round(o*a),s=Math.round(o);return e.drawingBufferWidth>e.drawingBufferHeight?{width:u,height:s}:{width:s,height:u}}function m(o,a,u){return{x:a/o.width,y:u/o.height}}window.addEventListener("mousemove",o=>{const a=f.getBoundingClientRect(),u=o.clientX-a.left,s=o.clientY-a.top;if(u<0||s<0||u>a.width||s>a.height)return;const l=v[0];l.down=!0,l.moved=!0,l.dx=(u-l.x)*5,l.dy=(s-l.y)*5,l.x=u,l.y=s}),f.addEventListener("mousedown",()=>{v[0].down=!0,v[0].color=W()}),window.addEventListener("mouseup",()=>{v[0].down=!1}),window.addEventListener("keydown",o=>{o.code==="KeyP"&&(n.paused=!n.paused),o.key===" "&&P.push(parseInt(Math.random()*20)+5)})}class R{constructor(e,r,i){if(this.uniforms={},this.webGL=i,this.program=i.createProgram(),i.attachShader(this.program,e),i.attachShader(this.program,r),i.linkProgram(this.program),!i.getProgramParameter(this.program,i.LINK_STATUS))throw i.getProgramInfoLog(this.program);const v=i.getProgramParameter(this.program,i.ACTIVE_UNIFORMS);for(let n=0;n<v;n++){const x=i.getActiveUniform(this.program,n).name;this.uniforms[x]=i.getUniformLocation(this.program,x)}}bind(){this.webGL.useProgram(this.program)}}class se{constructor(){this.id=-1,this.x=0,this.y=0,this.dx=0,this.dy=0,this.down=!1,this.moved=!1,this.color=[30,0,300]}}class Ee{constructor(e){this.canvas=e,this.webGL=null,this.programs=null,this.colorFormats=null,this.pointers=null,this.active=!1,this._started=!1}start(){if(!this.active){if(!this._started){const{webGL:e,programs:r,colorFormats:i,pointers:v}=pe(this.canvas);this.webGL=e,this.programs=r,this.colorFormats=i,this.pointers=v,Te(this.canvas,this.webGL,this.colorFormats,this.programs,this.pointers),this._started=!0}this.active=!0}}pause(){this.active&&(this.active=!1,this.webGL&&this.webGL.clear(this.webGL.COLOR_BUFFER_BIT))}destroy(){this.active=!1,this.webGL=null,this.programs=null,this.colorFormats=null,this.pointers=null,this._started=!1}}function me({enabled:f=!0,style:e={},className:r="",pointerEvents:i=!0}){const v=re.useRef(null),n=re.useRef(null);return re.useEffect(()=>{if(!v.current)return;n.current||(n.current=new Ee(v.current));const x=n.current;return f?x.start():x.pause(),()=>{n.current&&(n.current.destroy?.(),n.current=null)}},[f]),ge.jsx("canvas",{ref:v,className:r,style:{position:"fixed",inset:0,width:"100vw",height:"100vh",zIndex:0,pointerEvents:i?"auto":"none",...e}})}exports.LiquidBG=me;exports.default=me;exports.setBehaviors=he;