react-smokey-fluid-cursor 2.0.0 → 2.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 CHANGED
@@ -81,6 +81,12 @@ bun add react-smokey-fluid-cursor
81
81
 
82
82
  **Peer dependencies:** `react >= 17`, `react-dom >= 17`.
83
83
 
84
+ The WebGL engine comes from
85
+ [`smokey-fluid-cursor`](https://github.com/faraasat/smokey-fluid-cursor), which
86
+ is installed automatically as a dependency. This package is the React binding
87
+ for it — everything that package exports (`initFluid`, `presets`, the types) is
88
+ re-exported here, so you never need to import both.
89
+
84
90
  ## Quick start
85
91
 
86
92
  ```tsx
@@ -211,6 +217,44 @@ main { position: relative; z-index: 1; }
211
217
  In development the package detects this and warns in the console rather than
212
218
  leaving you with a blank screen.
213
219
 
220
+ ## Presets
221
+
222
+ 100 ready-made looks ship with the package — every colour palette crossed with
223
+ every motion character, named `"<Palette> <Character>"`:
224
+
225
+ ```tsx
226
+ import { presets } from "react-smokey-fluid-cursor";
227
+
228
+ <SmokeyFluidCursor config={presets["Ocean Swirl"]} />
229
+ ```
230
+
231
+ | | |
232
+ | --- | --- |
233
+ | **Palettes** (20) | Spectrum, Sunset, Ocean, Mono, Aurora, Ember, Lagoon, Candy, Toxic, Royal, Sakura, Mint, Copper, Ultraviolet, Ice, Magma, Forest, Dusk, Cyber, Pastel |
234
+ | **Characters** (5) | Calm, Flow, Swirl, Storm, Wisp |
235
+
236
+ So `"Magma Storm"` is the magma palette at storm intensity, `"Ice Wisp"` is
237
+ pale and sparse, and so on.
238
+
239
+ Presets only set **appearance and physics** — never mounting or placement — so
240
+ they compose with your own `container`, `zIndex` and the rest:
241
+
242
+ ```tsx
243
+ initFluid({ ...presets["Cyber Swirl"], container: "#hero", position: "absolute" });
244
+ ```
245
+
246
+ Browse all 100 on the [live demo](https://faraasat.github.io/react-smokey-fluid-cursor/).
247
+
248
+ ### Helpers
249
+
250
+ | Export | Type | Description |
251
+ | --- | --- | --- |
252
+ | `presets` | `Record<PresetName, Preset>` | Every preset, keyed by name. |
253
+ | `presetNames` | `PresetName[]` | All 100 names, in order. |
254
+ | `paletteNames` | `PaletteName[]` | The 20 palettes. |
255
+ | `characterNames` | `CharacterName[]` | The 5 motion characters. |
256
+ | `getPreset(name)` | `Preset \| undefined` | Safe lookup for a user-supplied name. |
257
+
214
258
  ## Configuration
215
259
 
216
260
  Every option is optional.
package/dist/index.d.mts CHANGED
@@ -1,271 +1,6 @@
1
1
  import React from 'react';
2
-
3
- /**
4
- * This file defines the foundational TypeScript interfaces
5
- * and type aliases used throughout the Smokey Fluid simulation engine.
6
- *
7
- * It abstracts WebGL object types (FBOs, textures, uniforms, etc.)
8
- * to provide clear, type-safe contracts for interacting with GPU resources.
9
- *
10
- * Developers integrating or extending this package should primarily
11
- * adjust configuration options defined in `ISmokeyFluidConfig`.
12
- */
13
- /**
14
- * Generic alias for either WebGL1 or WebGL2 rendering contexts.
15
- *
16
- * - WebGLRenderingContext → legacy WebGL1 API
17
- * - WebGL2RenderingContext → modern API with extended texture formats and MRT support
18
- *
19
- * This alias allows code to remain compatible across both WebGL versions.
20
- */
21
- type GL = WebGLRenderingContext | WebGL2RenderingContext;
22
- /**
23
- * Describes a format pair used for texture or renderbuffer configuration.
24
- *
25
- * - `internalFormat`: how GPU stores the texture internally (e.g., RGBA16F)
26
- * - `format`: how the data is laid out when uploading pixels (e.g., RGBA)
27
- *
28
- * Used for compatibility mapping between WebGL1 and WebGL2.
29
- */
30
- interface GLFormat {
31
- internalFormat: number;
32
- format: number;
33
- }
34
- /**
35
- * Represents detected WebGL extension and format capabilities
36
- * for the current context. This allows the engine to dynamically
37
- * choose the optimal texture formats and filtering modes.
38
- *
39
- * Usually populated at initialization after checking for extensions like:
40
- * - OES_texture_half_float
41
- * - OES_texture_float_linear
42
- * - EXT_color_buffer_float
43
- */
44
- interface GLExtInfo {
45
- /** Supported RGBA floating-point texture format */
46
- formatRGBA: GLFormat | null;
47
- /** Supported RG (two-channel) texture format (WebGL2 only) */
48
- formatRG: GLFormat | null;
49
- /** Supported R (single-channel) texture format (WebGL2 only) */
50
- formatR: GLFormat | null;
51
- /** GL constant for HALF_FLOAT type (e.g., gl.HALF_FLOAT_OES) */
52
- halfFloatTexType: number;
53
- /** Whether linear filtering (smooth interpolation) for float textures is available */
54
- supportLinearFiltering: boolean;
55
- /** True if running on WebGL2 (vs WebGL1 + extensions) */
56
- isWebGL2: boolean;
57
- }
58
- /**
59
- * Framebuffer Object (FBO) descriptor — wraps a texture and its framebuffer target.
60
- *
61
- * Each FBO represents a GPU render target that can store color or data fields
62
- * (such as velocity, pressure, or density in fluid simulation).
63
- */
64
- interface FBO {
65
- /** GPU texture attached to the framebuffer */
66
- texture: WebGLTexture | null;
67
- /** The framebuffer object itself */
68
- fbo: WebGLFramebuffer | null;
69
- /** Width of the texture in pixels */
70
- width: number;
71
- /** Height of the texture in pixels */
72
- height: number;
73
- /** Normalized texel size (1 / width) */
74
- texelSizeX: number;
75
- /** Normalized texel size (1 / height) */
76
- texelSizeY: number;
77
- /**
78
- * Binds this FBO's texture to a given texture unit (slot).
79
- * Returns the bound texture unit index for convenience.
80
- *
81
- * Example:
82
- * ```ts
83
- * const unit = velocityFBO.attach(0); // binds to TEXTURE0
84
- * gl.uniform1i(uniforms.uVelocity, unit);
85
- * ```
86
- */
87
- attach(id: number): number;
88
- }
89
- /**
90
- * Represents a double-buffered framebuffer system.
91
- *
92
- * Used heavily in fluid simulations to "ping-pong" between two framebuffers:
93
- * - One for reading previous state
94
- * - One for writing the next frame
95
- *
96
- * After each simulation step, `swap()` is called to exchange them.
97
- */
98
- interface DoubleFBO {
99
- /** Buffer width in pixels */
100
- width: number;
101
- /** Buffer height in pixels */
102
- height: number;
103
- /** Normalized texel size (1 / width) */
104
- texelSizeX: number;
105
- /** Normalized texel size (1 / height) */
106
- texelSizeY: number;
107
- /** Framebuffer currently used for reading */
108
- read: FBO;
109
- /** Framebuffer currently used for writing */
110
- write: FBO;
111
- /** Swaps read/write buffers for next iteration */
112
- swap(): void;
113
- }
114
- /**
115
- * ---------------------------------------------------------
116
- * 🔧 Smokey Fluid Configuration
117
- * ---------------------------------------------------------
118
- *
119
- * This interface defines **all configurable simulation parameters**
120
- * that can be customized externally (e.g., by UI, app settings, or user code).
121
- *
122
- * Each property controls a different aspect of the fluid’s physics,
123
- * rendering behavior, or visual appearance.
124
- */
125
- interface ISmokeyFluidConfig {
126
- /** Simulation grid resolution for velocity/pressure fields (lower = faster but coarser) */
127
- simResolution: number;
128
- /** Visual color/dye buffer resolution (affects rendering detail) */
129
- dyeResolution: number;
130
- /** Resolution used for high-quality screenshots or recording */
131
- captureResolution: number;
132
- /** Rate at which color fades from the fluid (higher = faster fade) */
133
- densityDissipation: number;
134
- /** Rate at which velocity energy dissipates (higher = faster slowdown) */
135
- velocityDissipation: number;
136
- /** Initial pressure clear multiplier (affects stability of solver) */
137
- pressure: number;
138
- /** Number of Jacobi iterations when solving pressure (higher = more accurate but slower) */
139
- pressureIteration: number;
140
- /** Strength of vorticity confinement (adds swirling, curl-like motion) */
141
- curl: number;
142
- /** Base normalized radius of user splats (0–1 range relative to screen size) */
143
- splatRadius: number;
144
- /** Force multiplier applied when user interacts (e.g., mouse/touch input) */
145
- splatForce: number;
146
- /** Enable or disable lighting/shading effects for visual depth */
147
- shading: boolean;
148
- /** Speed at which the dynamic color palette rotates during simulation */
149
- colorUpdateSpeed: number;
150
- /** If true, pauses the main simulation loop (used for debugging or static rendering) */
151
- paused: boolean;
152
- /**
153
- * Canvas background color (can be in 0–1 normalized range or 0–255)
154
- * Example: `{ r: 0, g: 0, b: 0 }` for black.
155
- */
156
- backColor: {
157
- r: number;
158
- g: number;
159
- b: number;
160
- };
161
- /**
162
- * Determines whether the canvas should preserve alpha transparency.
163
- * If `true`, blending with HTML backgrounds is allowed.
164
- */
165
- transparent: boolean;
166
- /**
167
- * ID assigned to the canvas element.
168
- * Default is "smokey-fluid-canvas".
169
- */
170
- id: string;
171
- /**
172
- * An existing canvas to render into — an element, or a CSS selector.
173
- *
174
- * Takes precedence over `id` and `container`. Use this when the canvas is
175
- * already part of your markup or managed by a framework.
176
- */
177
- canvas?: HTMLCanvasElement | string | null;
178
- /**
179
- * Element (or CSS selector) to create the canvas inside, when no canvas
180
- * matches `canvas`/`id` yet.
181
- *
182
- * Defaults to `document.body`, which with `position: "fixed"` gives the
183
- * classic full-viewport effect. Point it at a section to scope the effect
184
- * to just that area.
185
- */
186
- container?: HTMLElement | string | null;
187
- /**
188
- * CSS position for the canvas. Use `"absolute"` to confine the effect to a
189
- * positioned container; `"fixed"` covers the viewport. Default `"fixed"`.
190
- */
191
- position: "fixed" | "absolute" | "static" | "relative";
192
- /** Stacking order of the canvas. Default `-9999` (behind page content). */
193
- zIndex: number;
194
- /**
195
- * Whether the canvas receives pointer events. Default `false`, so clicks
196
- * pass straight through to your UI.
197
- */
198
- pointerEvents: boolean;
199
- /** Extra class name applied to the canvas element. */
200
- className?: string;
201
- /**
202
- * Upper bound on the device pixel ratio used for the render buffers.
203
- *
204
- * Default `2`. Uncapped, a 3x phone renders nine times the pixels of a 1x
205
- * display for a purely decorative effect, which drains battery and drops
206
- * frame rate.
207
- */
208
- maxDpr: number;
209
- /**
210
- * Pause the simulation while the page is hidden (background tab). Default
211
- * `true` — an invisible animation should not burn CPU or battery.
212
- */
213
- pauseOnHidden: boolean;
214
- /**
215
- * Honour the `prefers-reduced-motion` media query. When the visitor has
216
- * asked for reduced motion the simulation starts paused. Default `true`.
217
- */
218
- respectReducedMotion: boolean;
219
- /**
220
- * Colour palette for the fluid, as CSS hex strings (e.g. `["#ff4ecd"]`).
221
- *
222
- * When omitted, colours are generated randomly across the full hue range,
223
- * which is the original behaviour.
224
- */
225
- palette?: string[] | null;
226
- /**
227
- * Brightness multiplier applied to generated colours. Default `0.15`;
228
- * raise it for a more saturated, higher-contrast trail.
229
- */
230
- colorIntensity: number;
231
- }
232
- /**
233
- * Controls returned by {@link initFluid}.
234
- */
235
- interface FluidHandle {
236
- /** Stop the render loop, detach listeners and release the GL context. */
237
- dispose(): void;
238
- /** Pause the simulation, leaving the canvas in place. */
239
- pause(): void;
240
- /** Resume after {@link FluidHandle.pause}. */
241
- resume(): void;
242
- /** Whether the simulation is currently paused. */
243
- isPaused(): boolean;
244
- /**
245
- * Update tunable options in place, without tearing the simulation down.
246
- *
247
- * Resolution options (`simResolution`, `dyeResolution`) reallocate the
248
- * framebuffers; everything else applies on the next frame.
249
- */
250
- setConfig(partial: Partial<ISmokeyFluidConfig>): void;
251
- /**
252
- * Inject a splash at a point, in CSS pixels relative to the canvas.
253
- * Useful for driving the effect from something other than the pointer.
254
- */
255
- splat(x: number, y: number, color?: {
256
- r: number;
257
- g: number;
258
- b: number;
259
- }): void;
260
- /** The canvas being rendered into. */
261
- readonly canvas: HTMLCanvasElement | null;
262
- }
263
-
264
- /**
265
- * Initializes and starts the fluid simulation
266
- * @param incomingConfig - Partial configuration object to override default settings
267
- */
268
- declare const initFluid: (incomingConfig?: Partial<ISmokeyFluidConfig>) => FluidHandle;
2
+ import { ISmokeyFluidConfig, FluidHandle } from 'smokey-fluid-cursor';
3
+ export { CharacterName, DoubleFBO, FBO, FluidHandle, GL, GLExtInfo, ISmokeyFluidConfig, PaletteName, Preset, PresetName, characterNames, getPreset, initFluid, paletteNames, presetNames, presets } from 'smokey-fluid-cursor';
269
4
 
270
5
  interface SmokeyFluidCursorProps {
271
6
  /** Simulation options. See ISmokeyFluidConfig. */
@@ -298,4 +33,4 @@ declare function useSmokeyFluidCursor(config?: Partial<ISmokeyFluidConfig>, cont
298
33
  */
299
34
  declare const SmokeyFluidCursor: React.ForwardRefExoticComponent<SmokeyFluidCursorProps & React.RefAttributes<FluidHandle>>;
300
35
 
301
- export { type DoubleFBO, type FBO, type FluidHandle, type GL, type GLExtInfo, type ISmokeyFluidConfig, SmokeyFluidCursor, type SmokeyFluidCursorProps, initFluid, useSmokeyFluidCursor };
36
+ export { SmokeyFluidCursor, type SmokeyFluidCursorProps, useSmokeyFluidCursor };
package/dist/index.d.ts CHANGED
@@ -1,271 +1,6 @@
1
1
  import React from 'react';
2
-
3
- /**
4
- * This file defines the foundational TypeScript interfaces
5
- * and type aliases used throughout the Smokey Fluid simulation engine.
6
- *
7
- * It abstracts WebGL object types (FBOs, textures, uniforms, etc.)
8
- * to provide clear, type-safe contracts for interacting with GPU resources.
9
- *
10
- * Developers integrating or extending this package should primarily
11
- * adjust configuration options defined in `ISmokeyFluidConfig`.
12
- */
13
- /**
14
- * Generic alias for either WebGL1 or WebGL2 rendering contexts.
15
- *
16
- * - WebGLRenderingContext → legacy WebGL1 API
17
- * - WebGL2RenderingContext → modern API with extended texture formats and MRT support
18
- *
19
- * This alias allows code to remain compatible across both WebGL versions.
20
- */
21
- type GL = WebGLRenderingContext | WebGL2RenderingContext;
22
- /**
23
- * Describes a format pair used for texture or renderbuffer configuration.
24
- *
25
- * - `internalFormat`: how GPU stores the texture internally (e.g., RGBA16F)
26
- * - `format`: how the data is laid out when uploading pixels (e.g., RGBA)
27
- *
28
- * Used for compatibility mapping between WebGL1 and WebGL2.
29
- */
30
- interface GLFormat {
31
- internalFormat: number;
32
- format: number;
33
- }
34
- /**
35
- * Represents detected WebGL extension and format capabilities
36
- * for the current context. This allows the engine to dynamically
37
- * choose the optimal texture formats and filtering modes.
38
- *
39
- * Usually populated at initialization after checking for extensions like:
40
- * - OES_texture_half_float
41
- * - OES_texture_float_linear
42
- * - EXT_color_buffer_float
43
- */
44
- interface GLExtInfo {
45
- /** Supported RGBA floating-point texture format */
46
- formatRGBA: GLFormat | null;
47
- /** Supported RG (two-channel) texture format (WebGL2 only) */
48
- formatRG: GLFormat | null;
49
- /** Supported R (single-channel) texture format (WebGL2 only) */
50
- formatR: GLFormat | null;
51
- /** GL constant for HALF_FLOAT type (e.g., gl.HALF_FLOAT_OES) */
52
- halfFloatTexType: number;
53
- /** Whether linear filtering (smooth interpolation) for float textures is available */
54
- supportLinearFiltering: boolean;
55
- /** True if running on WebGL2 (vs WebGL1 + extensions) */
56
- isWebGL2: boolean;
57
- }
58
- /**
59
- * Framebuffer Object (FBO) descriptor — wraps a texture and its framebuffer target.
60
- *
61
- * Each FBO represents a GPU render target that can store color or data fields
62
- * (such as velocity, pressure, or density in fluid simulation).
63
- */
64
- interface FBO {
65
- /** GPU texture attached to the framebuffer */
66
- texture: WebGLTexture | null;
67
- /** The framebuffer object itself */
68
- fbo: WebGLFramebuffer | null;
69
- /** Width of the texture in pixels */
70
- width: number;
71
- /** Height of the texture in pixels */
72
- height: number;
73
- /** Normalized texel size (1 / width) */
74
- texelSizeX: number;
75
- /** Normalized texel size (1 / height) */
76
- texelSizeY: number;
77
- /**
78
- * Binds this FBO's texture to a given texture unit (slot).
79
- * Returns the bound texture unit index for convenience.
80
- *
81
- * Example:
82
- * ```ts
83
- * const unit = velocityFBO.attach(0); // binds to TEXTURE0
84
- * gl.uniform1i(uniforms.uVelocity, unit);
85
- * ```
86
- */
87
- attach(id: number): number;
88
- }
89
- /**
90
- * Represents a double-buffered framebuffer system.
91
- *
92
- * Used heavily in fluid simulations to "ping-pong" between two framebuffers:
93
- * - One for reading previous state
94
- * - One for writing the next frame
95
- *
96
- * After each simulation step, `swap()` is called to exchange them.
97
- */
98
- interface DoubleFBO {
99
- /** Buffer width in pixels */
100
- width: number;
101
- /** Buffer height in pixels */
102
- height: number;
103
- /** Normalized texel size (1 / width) */
104
- texelSizeX: number;
105
- /** Normalized texel size (1 / height) */
106
- texelSizeY: number;
107
- /** Framebuffer currently used for reading */
108
- read: FBO;
109
- /** Framebuffer currently used for writing */
110
- write: FBO;
111
- /** Swaps read/write buffers for next iteration */
112
- swap(): void;
113
- }
114
- /**
115
- * ---------------------------------------------------------
116
- * 🔧 Smokey Fluid Configuration
117
- * ---------------------------------------------------------
118
- *
119
- * This interface defines **all configurable simulation parameters**
120
- * that can be customized externally (e.g., by UI, app settings, or user code).
121
- *
122
- * Each property controls a different aspect of the fluid’s physics,
123
- * rendering behavior, or visual appearance.
124
- */
125
- interface ISmokeyFluidConfig {
126
- /** Simulation grid resolution for velocity/pressure fields (lower = faster but coarser) */
127
- simResolution: number;
128
- /** Visual color/dye buffer resolution (affects rendering detail) */
129
- dyeResolution: number;
130
- /** Resolution used for high-quality screenshots or recording */
131
- captureResolution: number;
132
- /** Rate at which color fades from the fluid (higher = faster fade) */
133
- densityDissipation: number;
134
- /** Rate at which velocity energy dissipates (higher = faster slowdown) */
135
- velocityDissipation: number;
136
- /** Initial pressure clear multiplier (affects stability of solver) */
137
- pressure: number;
138
- /** Number of Jacobi iterations when solving pressure (higher = more accurate but slower) */
139
- pressureIteration: number;
140
- /** Strength of vorticity confinement (adds swirling, curl-like motion) */
141
- curl: number;
142
- /** Base normalized radius of user splats (0–1 range relative to screen size) */
143
- splatRadius: number;
144
- /** Force multiplier applied when user interacts (e.g., mouse/touch input) */
145
- splatForce: number;
146
- /** Enable or disable lighting/shading effects for visual depth */
147
- shading: boolean;
148
- /** Speed at which the dynamic color palette rotates during simulation */
149
- colorUpdateSpeed: number;
150
- /** If true, pauses the main simulation loop (used for debugging or static rendering) */
151
- paused: boolean;
152
- /**
153
- * Canvas background color (can be in 0–1 normalized range or 0–255)
154
- * Example: `{ r: 0, g: 0, b: 0 }` for black.
155
- */
156
- backColor: {
157
- r: number;
158
- g: number;
159
- b: number;
160
- };
161
- /**
162
- * Determines whether the canvas should preserve alpha transparency.
163
- * If `true`, blending with HTML backgrounds is allowed.
164
- */
165
- transparent: boolean;
166
- /**
167
- * ID assigned to the canvas element.
168
- * Default is "smokey-fluid-canvas".
169
- */
170
- id: string;
171
- /**
172
- * An existing canvas to render into — an element, or a CSS selector.
173
- *
174
- * Takes precedence over `id` and `container`. Use this when the canvas is
175
- * already part of your markup or managed by a framework.
176
- */
177
- canvas?: HTMLCanvasElement | string | null;
178
- /**
179
- * Element (or CSS selector) to create the canvas inside, when no canvas
180
- * matches `canvas`/`id` yet.
181
- *
182
- * Defaults to `document.body`, which with `position: "fixed"` gives the
183
- * classic full-viewport effect. Point it at a section to scope the effect
184
- * to just that area.
185
- */
186
- container?: HTMLElement | string | null;
187
- /**
188
- * CSS position for the canvas. Use `"absolute"` to confine the effect to a
189
- * positioned container; `"fixed"` covers the viewport. Default `"fixed"`.
190
- */
191
- position: "fixed" | "absolute" | "static" | "relative";
192
- /** Stacking order of the canvas. Default `-9999` (behind page content). */
193
- zIndex: number;
194
- /**
195
- * Whether the canvas receives pointer events. Default `false`, so clicks
196
- * pass straight through to your UI.
197
- */
198
- pointerEvents: boolean;
199
- /** Extra class name applied to the canvas element. */
200
- className?: string;
201
- /**
202
- * Upper bound on the device pixel ratio used for the render buffers.
203
- *
204
- * Default `2`. Uncapped, a 3x phone renders nine times the pixels of a 1x
205
- * display for a purely decorative effect, which drains battery and drops
206
- * frame rate.
207
- */
208
- maxDpr: number;
209
- /**
210
- * Pause the simulation while the page is hidden (background tab). Default
211
- * `true` — an invisible animation should not burn CPU or battery.
212
- */
213
- pauseOnHidden: boolean;
214
- /**
215
- * Honour the `prefers-reduced-motion` media query. When the visitor has
216
- * asked for reduced motion the simulation starts paused. Default `true`.
217
- */
218
- respectReducedMotion: boolean;
219
- /**
220
- * Colour palette for the fluid, as CSS hex strings (e.g. `["#ff4ecd"]`).
221
- *
222
- * When omitted, colours are generated randomly across the full hue range,
223
- * which is the original behaviour.
224
- */
225
- palette?: string[] | null;
226
- /**
227
- * Brightness multiplier applied to generated colours. Default `0.15`;
228
- * raise it for a more saturated, higher-contrast trail.
229
- */
230
- colorIntensity: number;
231
- }
232
- /**
233
- * Controls returned by {@link initFluid}.
234
- */
235
- interface FluidHandle {
236
- /** Stop the render loop, detach listeners and release the GL context. */
237
- dispose(): void;
238
- /** Pause the simulation, leaving the canvas in place. */
239
- pause(): void;
240
- /** Resume after {@link FluidHandle.pause}. */
241
- resume(): void;
242
- /** Whether the simulation is currently paused. */
243
- isPaused(): boolean;
244
- /**
245
- * Update tunable options in place, without tearing the simulation down.
246
- *
247
- * Resolution options (`simResolution`, `dyeResolution`) reallocate the
248
- * framebuffers; everything else applies on the next frame.
249
- */
250
- setConfig(partial: Partial<ISmokeyFluidConfig>): void;
251
- /**
252
- * Inject a splash at a point, in CSS pixels relative to the canvas.
253
- * Useful for driving the effect from something other than the pointer.
254
- */
255
- splat(x: number, y: number, color?: {
256
- r: number;
257
- g: number;
258
- b: number;
259
- }): void;
260
- /** The canvas being rendered into. */
261
- readonly canvas: HTMLCanvasElement | null;
262
- }
263
-
264
- /**
265
- * Initializes and starts the fluid simulation
266
- * @param incomingConfig - Partial configuration object to override default settings
267
- */
268
- declare const initFluid: (incomingConfig?: Partial<ISmokeyFluidConfig>) => FluidHandle;
2
+ import { ISmokeyFluidConfig, FluidHandle } from 'smokey-fluid-cursor';
3
+ export { CharacterName, DoubleFBO, FBO, FluidHandle, GL, GLExtInfo, ISmokeyFluidConfig, PaletteName, Preset, PresetName, characterNames, getPreset, initFluid, paletteNames, presetNames, presets } from 'smokey-fluid-cursor';
269
4
 
270
5
  interface SmokeyFluidCursorProps {
271
6
  /** Simulation options. See ISmokeyFluidConfig. */
@@ -298,4 +33,4 @@ declare function useSmokeyFluidCursor(config?: Partial<ISmokeyFluidConfig>, cont
298
33
  */
299
34
  declare const SmokeyFluidCursor: React.ForwardRefExoticComponent<SmokeyFluidCursorProps & React.RefAttributes<FluidHandle>>;
300
35
 
301
- export { type DoubleFBO, type FBO, type FluidHandle, type GL, type GLExtInfo, type ISmokeyFluidConfig, SmokeyFluidCursor, type SmokeyFluidCursorProps, initFluid, useSmokeyFluidCursor };
36
+ export { SmokeyFluidCursor, type SmokeyFluidCursorProps, useSmokeyFluidCursor };
package/dist/index.js CHANGED
@@ -1,195 +1,2 @@
1
1
  "use client";
2
- "use strict";var ct=Object.create;var K=Object.defineProperty;var lt=Object.getOwnPropertyDescriptor;var dt=Object.getOwnPropertyNames;var ft=Object.getPrototypeOf,mt=Object.prototype.hasOwnProperty;var vt=(s,i)=>{for(var m in i)K(s,m,{get:i[m],enumerable:!0})},Ae=(s,i,m,a)=>{if(i&&typeof i=="object"||typeof i=="function")for(let F of dt(i))!mt.call(s,F)&&F!==m&&K(s,F,{get:()=>i[F],enumerable:!(a=lt(i,F))||a.enumerable});return s};var ht=(s,i,m)=>(m=s!=null?ct(ft(s)):{},Ae(i||!s||!s.__esModule?K(m,"default",{value:s,enumerable:!0}):m,s)),pt=s=>Ae(K({},"__esModule",{value:!0}),s);var Ft={};vt(Ft,{SmokeyFluidCursor:()=>yt,initFluid:()=>ae,useSmokeyFluidCursor:()=>Ue});module.exports=pt(Ft);var P=ht(require("react"));var xt={simResolution:128,dyeResolution:1440,captureResolution:512,densityDissipation:3.5,velocityDissipation:2,pressure:.1,pressureIteration:20,curl:10,splatRadius:.5,splatForce:6e3,shading:!0,colorUpdateSpeed:10,paused:!1,backColor:{r:0,g:0,b:0},transparent:!0,id:"smokey-fluid-canvas",position:"fixed",zIndex:-9999,pointerEvents:!1,maxDpr:2,pauseOnHidden:!0,respectReducedMotion:!0,palette:null,colorIntensity:.15},Pe=s=>{var i;return s?typeof s!="string"?s:(i=document.querySelector(s))!=null?i:document.getElementById(s):null},gt=s=>{let i=s.trim().replace(/^#/,"");return i.length===3&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]),/^[0-9a-f]{6}$/i.test(i)?{r:parseInt(i.slice(0,2),16)/255,g:parseInt(i.slice(2,4),16)/255,b:parseInt(i.slice(4,6),16)/255}:null},bt=s=>{var a;if(s>=0||typeof document=="undefined"||typeof process!="undefined"&&((a=process.env)==null?void 0:a.NODE_ENV)==="production")return;let i=window.getComputedStyle(document.body).backgroundColor;i&&i!=="transparent"&&!/rgba\(\s*0\s*,\s*0\s*,\s*0\s*,\s*0\s*\)/.test(i)&&console.warn("[smokey-fluid-cursor] <body> has an opaque background ("+i+") and the canvas sits at z-index "+s+`, so the effect will be painted over and stay invisible.
3
- Move the background to <html>, or give the canvas a zIndex above your background.`)},Rt=()=>typeof window!="undefined"&&typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches,se={dispose:()=>{},pause:()=>{},resume:()=>{},isPaused:()=>!0,setConfig:()=>{},splat:()=>{},canvas:null},ae=(s={})=>{var _e,Be,Ce;let i={...xt,...s};if(typeof document=="undefined")return se;let m=!1,a=(_e=Pe(i.canvas))!=null?_e:document.getElementById(i.id);if(!a){let e=(Be=Pe(i.container))!=null?Be:document.body;if(!e)return se;a=document.createElement("canvas"),a.id=i.id,e.appendChild(a),m=!0}i.className&&a.classList.add(...i.className.split(/\s+/));let F=i.position==="fixed"||i.position==="absolute";Object.assign(a.style,{position:i.position,...F?{top:"0",left:"0",width:"100%",height:"100%"}:{},display:"block",pointerEvents:i.pointerEvents?"auto":"none",zIndex:String(i.zIndex)}),bt(i.zIndex),I();class w{constructor(){this.id=-1;this.texcoordX=0;this.texcoordY=0;this.prevTexcoordX=0;this.prevTexcoordY=0;this.deltaX=0;this.deltaY=0;this.down=!1;this.moved=!1;this.color=[30,0,300]}}let b=[];b.push(new w);let t,p;try{({gl:t,ext:p}=v(a))}catch(e){typeof console!="undefined"&&console.warn("[smokey-fluid-cursor] WebGL is unavailable; the cursor effect is disabled.",e);let r=a,n=m;return{...se,dispose:()=>{n&&r.remove()},setConfig:o=>{o.zIndex!==void 0&&(r.style.zIndex=String(o.zIndex)),o.pointerEvents!==void 0&&(r.style.pointerEvents=o.pointerEvents?"auto":"none")},get canvas(){return r}}}p.supportLinearFiltering||(i.dyeResolution=512,i.shading=!1);function v(e){let r={alpha:!0,depth:!1,stencil:!1,antialias:!1,preserveDrawingBuffer:!1},n=e.getContext("webgl2",r),o=!!n;if(o||(n=e.getContext("webgl",r)||e.getContext("experimental-webgl",r)),!n)throw new Error("WebGL not supported");let u=null,l,c;if(o){let f=n;f.getExtension("EXT_color_buffer_float"),l=!!f.getExtension("OES_texture_float_linear"),c=f.HALF_FLOAT}else{let f=n;if(u=f.getExtension("OES_texture_half_float"),l=!!f.getExtension("OES_texture_half_float_linear"),!u)throw new Error("OES_texture_half_float not supported on WebGL1");c=u.HALF_FLOAT_OES}n.clearColor(0,0,0,1);let h=null,g=null,B=null;if(o){let f=n;h=x(f,f.RGBA16F,f.RGBA,c),g=x(f,f.RG16F,f.RG,c),B=x(f,f.R16F,f.RED,c)}else{let f=n;h=x(f,f.RGBA,f.RGBA,c),g=x(f,f.RGBA,f.RGBA,c),B=x(f,f.RGBA,f.RGBA,c)}return{gl:n,ext:{formatRGBA:h,formatRG:g,formatR:B,halfFloatTexType:c,supportLinearFiltering:l,isWebGL2:o}}}function x(e,r,n,o){if(!j(e,r,n,o)){if(e.RGBA16F!==void 0){let u=e;switch(r){case u.R16F:return x(u,u.RG16F,u.RG,o);case u.RG16F:return x(u,u.RGBA16F,u.RGBA,o);default:return null}}return null}return{internalFormat:r,format:n}}function j(e,r,n,o){let u=e.createTexture();if(!u)return!1;e.bindTexture(e.TEXTURE_2D,u),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),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,r,4,4,0,n,o,null);let l=e.createFramebuffer();if(!l)return!1;e.bindFramebuffer(e.FRAMEBUFFER,l),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,u,0);let c=e.checkFramebufferStatus(e.FRAMEBUFFER);return e.bindFramebuffer(e.FRAMEBUFFER,null),e.deleteFramebuffer(l),e.deleteTexture(u),c===e.FRAMEBUFFER_COMPLETE}class X{constructor(r,n){this.vertexShader=r,this.fragmentShaderSource=n,this.programs={},this.activeProgram=null,this.uniforms={}}setKeywords(r){let n=0;for(let u=0;u<r.length;u++)n+=st(r[u]);let o=this.programs[n];if(!o){let u=S(t,t.FRAGMENT_SHADER,de(this.fragmentShaderSource,r));o=ce(t,this.vertexShader,u),this.programs[n]=o}o!==this.activeProgram&&(this.uniforms=le(t,o),this.activeProgram=o)}bind(){this.activeProgram&&t.useProgram(this.activeProgram)}}class _{constructor(r,n){this.program=ce(t,r,n),this.uniforms=le(t,this.program)}bind(){this.program&&t.useProgram(this.program)}}function ce(e,r,n){let o=e.createProgram();return e.attachShader(o,r),e.attachShader(o,n),e.bindAttribLocation(o,0,"aPosition"),e.linkProgram(o),e.getProgramParameter(o,e.LINK_STATUS)||console.trace(e.getProgramInfoLog(o)),o}function le(e,r){let n={},o=e.getProgramParameter(r,e.ACTIVE_UNIFORMS);for(let u=0;u<o;u++){let l=e.getActiveUniform(r,u);if(!l)continue;let c=l.name,h=e.getUniformLocation(r,c);h&&(n[c]=h)}return n}function S(e,r,n){let o=e.createShader(r);return e.shaderSource(o,n),e.compileShader(o),e.getShaderParameter(o,e.COMPILE_STATUS)||console.trace(e.getShaderInfoLog(o)),o}function de(e,r){if(!r||r.length===0)return e;let n="";return r.forEach(o=>{n+="#define "+o+`
4
- `}),n+e}let L=S(t,t.VERTEX_SHADER,`precision highp float;
5
- attribute vec2 aPosition;
6
- varying vec2 vUv;
7
- varying vec2 vL;
8
- varying vec2 vR;
9
- varying vec2 vT;
10
- varying vec2 vB;
11
- uniform vec2 texelSize;
12
- void main () {
13
- vUv = aPosition * 0.5 + 0.5;
14
- vL = vUv - vec2(texelSize.x, 0.0);
15
- vR = vUv + vec2(texelSize.x, 0.0);
16
- vT = vUv + vec2(0.0, texelSize.y);
17
- vB = vUv - vec2(0.0, texelSize.y);
18
- gl_Position = vec4(aPosition, 0.0, 1.0);
19
- }`),Me=S(t,t.FRAGMENT_SHADER,`precision mediump float;
20
- precision mediump sampler2D;
21
- varying highp vec2 vUv;
22
- uniform sampler2D uTexture;
23
- void main () {
24
- gl_FragColor = texture2D(uTexture, vUv);
25
- }`),ze=S(t,t.FRAGMENT_SHADER,`precision mediump float;
26
- precision mediump sampler2D;
27
- varying highp vec2 vUv;
28
- uniform sampler2D uTexture;
29
- uniform float value;
30
- void main () {
31
- gl_FragColor = value * texture2D(uTexture, vUv);
32
- }`),Ie=`precision highp float;
33
- precision highp sampler2D;
34
- varying vec2 vUv;
35
- varying vec2 vL;
36
- varying vec2 vR;
37
- varying vec2 vT;
38
- varying vec2 vB;
39
- uniform sampler2D uTexture;
40
- uniform vec2 texelSize;
41
- void main () {
42
- vec3 c = texture2D(uTexture, vUv).rgb;
43
- #ifdef shading
44
- vec3 lc = texture2D(uTexture, vL).rgb;
45
- vec3 rc = texture2D(uTexture, vR).rgb;
46
- vec3 tc = texture2D(uTexture, vT).rgb;
47
- vec3 bc = texture2D(uTexture, vB).rgb;
48
- float dx = length(rc) - length(lc);
49
- float dy = length(tc) - length(bc);
50
- vec3 n = normalize(vec3(dx, dy, length(texelSize)));
51
- vec3 l = vec3(0.0, 0.0, 1.0);
52
- float diffuse = clamp(dot(n, l) + 0.7, 0.7, 1.0);
53
- c *= diffuse;
54
- #endif
55
- float a = max(c.r, max(c.g, c.b));
56
- gl_FragColor = vec4(c, a);
57
- }`,Xe=S(t,t.FRAGMENT_SHADER,`precision highp float;
58
- precision highp sampler2D;
59
- varying vec2 vUv;
60
- uniform sampler2D uTarget;
61
- uniform float aspectRatio;
62
- uniform vec3 color;
63
- uniform vec2 point;
64
- uniform float radius;
65
- void main () {
66
- vec2 p = vUv - point.xy;
67
- p.x *= aspectRatio;
68
- vec3 splat = exp(-dot(p, p) / radius) * color;
69
- vec3 base = texture2D(uTarget, vUv).xyz;
70
- gl_FragColor = vec4(base + splat, 1.0);
71
- }`),Oe=S(t,t.FRAGMENT_SHADER,de(`precision highp float;
72
- precision highp sampler2D;
73
- varying vec2 vUv;
74
- uniform sampler2D uVelocity;
75
- uniform sampler2D uSource;
76
- uniform vec2 texelSize;
77
- uniform vec2 dyeTexelSize;
78
- uniform float dt;
79
- uniform float dissipation;
80
- vec4 bilerp (sampler2D sam, vec2 uv, vec2 tsize) {
81
- vec2 st = uv / tsize - 0.5;
82
- vec2 iuv = floor(st);
83
- vec2 fuv = fract(st);
84
- vec4 a = texture2D(sam, (iuv + vec2(0.5, 0.5)) * tsize);
85
- vec4 b = texture2D(sam, (iuv + vec2(1.5, 0.5)) * tsize);
86
- vec4 c = texture2D(sam, (iuv + vec2(0.5, 1.5)) * tsize);
87
- vec4 d = texture2D(sam, (iuv + vec2(1.5, 1.5)) * tsize);
88
- return mix(mix(a, b, fuv.x), mix(c, d, fuv.x), fuv.y);
89
- }
90
- void main () {
91
- #ifdef MANUAL_FILTERING
92
- vec2 coord = vUv - dt * bilerp(uVelocity, vUv, texelSize).xy * texelSize;
93
- vec4 result = bilerp(uSource, coord, dyeTexelSize);
94
- #else
95
- vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;
96
- vec4 result = texture2D(uSource, coord);
97
- #endif
98
- float decay = 1.0 + dissipation * dt;
99
- gl_FragColor = result / decay;
100
- }`,p.supportLinearFiltering?null:["MANUAL_FILTERING"])),Ne=S(t,t.FRAGMENT_SHADER,`precision mediump float;
101
- precision mediump sampler2D;
102
- varying highp vec2 vUv;
103
- varying highp vec2 vL;
104
- varying highp vec2 vR;
105
- varying highp vec2 vT;
106
- varying highp vec2 vB;
107
- uniform sampler2D uVelocity;
108
- void main () {
109
- float L = texture2D(uVelocity, vL).x;
110
- float R = texture2D(uVelocity, vR).x;
111
- float T = texture2D(uVelocity, vT).y;
112
- float B = texture2D(uVelocity, vB).y;
113
- vec2 C = texture2D(uVelocity, vUv).xy;
114
- if (vL.x < 0.0) { L = -C.x; }
115
- if (vR.x > 1.0) { R = -C.x; }
116
- if (vT.y > 1.0) { T = -C.y; }
117
- if (vB.y < 0.0) { B = -C.y; }
118
- float div = 0.5 * (R - L + T - B);
119
- gl_FragColor = vec4(div, 0.0, 0.0, 1.0);
120
- }`),He=S(t,t.FRAGMENT_SHADER,`precision mediump float;
121
- precision mediump sampler2D;
122
- varying highp vec2 vUv;
123
- varying highp vec2 vL;
124
- varying highp vec2 vR;
125
- varying highp vec2 vT;
126
- varying highp vec2 vB;
127
- uniform sampler2D uVelocity;
128
- void main () {
129
- float L = texture2D(uVelocity, vL).y;
130
- float R = texture2D(uVelocity, vR).y;
131
- float T = texture2D(uVelocity, vT).x;
132
- float B = texture2D(uVelocity, vB).x;
133
- float vorticity = R - L - T + B;
134
- gl_FragColor = vec4(0.5 * vorticity, 0.0, 0.0, 1.0);
135
- }`),Ye=S(t,t.FRAGMENT_SHADER,`precision highp float;
136
- precision highp sampler2D;
137
- varying vec2 vUv;
138
- varying vec2 vL;
139
- varying vec2 vR;
140
- varying vec2 vT;
141
- varying vec2 vB;
142
- uniform sampler2D uVelocity;
143
- uniform sampler2D uCurl;
144
- uniform float curl;
145
- uniform float dt;
146
- void main () {
147
- float L = texture2D(uCurl, vL).x;
148
- float R = texture2D(uCurl, vR).x;
149
- float T = texture2D(uCurl, vT).x;
150
- float B = texture2D(uCurl, vB).x;
151
- float C = texture2D(uCurl, vUv).x;
152
- vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));
153
- force /= length(force) + 0.0001;
154
- force *= curl * C;
155
- force.y *= -1.0;
156
- vec2 velocity = texture2D(uVelocity, vUv).xy;
157
- velocity += force * dt;
158
- velocity = min(max(velocity, -1000.0), 1000.0);
159
- gl_FragColor = vec4(velocity, 0.0, 1.0);
160
- }`),We=S(t,t.FRAGMENT_SHADER,`precision mediump float;
161
- precision mediump sampler2D;
162
- varying highp vec2 vUv;
163
- varying highp vec2 vL;
164
- varying highp vec2 vR;
165
- varying highp vec2 vT;
166
- varying highp vec2 vB;
167
- uniform sampler2D uPressure;
168
- uniform sampler2D uDivergence;
169
- void main () {
170
- float L = texture2D(uPressure, vL).x;
171
- float R = texture2D(uPressure, vR).x;
172
- float T = texture2D(uPressure, vT).x;
173
- float B = texture2D(uPressure, vB).x;
174
- float C = texture2D(uPressure, vUv).x;
175
- float divergence = texture2D(uDivergence, vUv).x;
176
- float pressure = (L + R + B + T - divergence) * 0.25;
177
- gl_FragColor = vec4(pressure, 0.0, 0.0, 1.0);
178
- }`),ke=S(t,t.FRAGMENT_SHADER,`precision mediump float;
179
- precision mediump sampler2D;
180
- varying highp vec2 vUv;
181
- varying highp vec2 vL;
182
- varying highp vec2 vR;
183
- varying highp vec2 vT;
184
- varying highp vec2 vB;
185
- uniform sampler2D uPressure;
186
- uniform sampler2D uVelocity;
187
- void main () {
188
- float L = texture2D(uPressure, vL).x;
189
- float R = texture2D(uPressure, vR).x;
190
- float T = texture2D(uPressure, vT).x;
191
- float B = texture2D(uPressure, vB).x;
192
- vec2 velocity = texture2D(uVelocity, vUv).xy;
193
- velocity.xy -= vec2(R - L, T - B);
194
- gl_FragColor = vec4(velocity, 0.0, 1.0);
195
- }`),T=(()=>{let e=t.createBuffer();t.bindBuffer(t.ARRAY_BUFFER,e),t.bufferData(t.ARRAY_BUFFER,new Float32Array([-1,-1,-1,1,1,1,1,-1]),t.STATIC_DRAW);let r=t.createBuffer();return t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,r),t.bufferData(t.ELEMENT_ARRAY_BUFFER,new Uint16Array([0,1,2,0,2,3]),t.STATIC_DRAW),t.vertexAttribPointer(0,2,t.FLOAT,!1,0,0),t.enableVertexAttribArray(0),(n,o=!1)=>{n==null?(t.viewport(0,0,t.drawingBufferWidth,t.drawingBufferHeight),t.bindFramebuffer(t.FRAMEBUFFER,null)):(t.viewport(0,0,n.width,n.height),t.bindFramebuffer(t.FRAMEBUFFER,n.fbo)),o&&(t.clearColor(0,0,0,1),t.clear(t.COLOR_BUFFER_BIT)),t.drawElements(t.TRIANGLES,6,t.UNSIGNED_SHORT,0)}})(),R,d,J,$,C,fe=new _(L,Me),Z=new _(L,ze),A=new _(L,Xe),D=new _(L,Oe),Q=new _(L,Ne),ee=new _(L,He),U=new _(L,Ye),O=new _(L,We),N=new _(L,ke),H=new X(L,Ie);function te(){let e=Se(i.simResolution),r=Se(i.dyeResolution),n=p.halfFloatTexType,o=p.formatRGBA,u=p.formatRG,l=p.formatR,c=p.supportLinearFiltering?t.LINEAR:t.NEAREST;t.disable(t.BLEND),R==null?R=re(r.width,r.height,o.internalFormat,o.format,n,c):R=me(R,r.width,r.height,o.internalFormat,o.format,n,c),d==null?d=re(e.width,e.height,u.internalFormat,u.format,n,c):d=me(d,e.width,e.height,u.internalFormat,u.format,n,c),J=G(e.width,e.height,l.internalFormat,l.format,n,t.NEAREST),$=G(e.width,e.height,l.internalFormat,l.format,n,t.NEAREST),C=re(e.width,e.height,l.internalFormat,l.format,n,t.NEAREST)}function G(e,r,n,o,u,l){t.activeTexture(t.TEXTURE0);let c=t.createTexture();t.bindTexture(t.TEXTURE_2D,c),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,l),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,l),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texImage2D(t.TEXTURE_2D,0,n,e,r,0,o,u,null);let h=t.createFramebuffer();t.bindFramebuffer(t.FRAMEBUFFER,h),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,c,0),t.viewport(0,0,e,r),t.clear(t.COLOR_BUFFER_BIT);let g=1/e,B=1/r;return{texture:c,fbo:h,width:e,height:r,texelSizeX:g,texelSizeY:B,attach(f){return t.activeTexture(t.TEXTURE0+f),t.bindTexture(t.TEXTURE_2D,c),f}}}function re(e,r,n,o,u,l){let c=G(e,r,n,o,u,l),h=G(e,r,n,o,u,l);return{width:e,height:r,texelSizeX:c.texelSizeX,texelSizeY:c.texelSizeY,get read(){return c},set read(g){c=g},get write(){return h},set write(g){h=g},swap(){let g=c;c=h,h=g}}}function Ve(e,r,n,o,u,l,c){let h=G(r,n,o,u,l,c);return fe.bind(),t.uniform1i(fe.uniforms.uTexture,e.attach(0)),T(h),h}function me(e,r,n,o,u,l,c){return e.width===r&&e.height===n||(e.read=Ve(e.read,r,n,o,u,l,c),e.write=G(r,n,o,u,l,c),e.width=r,e.height=n,e.texelSizeX=1/r,e.texelSizeY=1/n),e}function qe(){let e=[];i.shading&&e.push("shading"),H.setKeywords(e)}qe(),te();let ne=Date.now(),Y=0,oe=0;function ve(){let e=Ke();I()&&te(),je(e),Je(),i.paused||$e(e),he(null),oe=requestAnimationFrame(ve)}function Ke(){let e=Date.now(),r=(e-ne)/1e3;return r=Math.min(r,.016666),ne=e,r}function I(){let e=y(a.clientWidth),r=y(a.clientHeight);return a.width!==e||a.height!==r?(a.width=e,a.height=r,!0):!1}function je(e){Y+=e*i.colorUpdateSpeed,Y>=1&&(Y=ut(Y,0,1),b.forEach(r=>{r.color=Fe(W())}))}function Je(){b.forEach(e=>{e.moved&&(e.moved=!1,Qe(e))})}function $e(e){t.disable(t.BLEND),ee.bind(),t.uniform2f(ee.uniforms.texelSize,d.texelSizeX,d.texelSizeY),t.uniform1i(ee.uniforms.uVelocity,d.read.attach(0)),T($),U.bind(),t.uniform2f(U.uniforms.texelSize,d.texelSizeX,d.texelSizeY),t.uniform1i(U.uniforms.uVelocity,d.read.attach(0)),t.uniform1i(U.uniforms.uCurl,$.attach(1)),t.uniform1f(U.uniforms.curl,i.curl),t.uniform1f(U.uniforms.dt,e),T(d.write),d.swap(),Q.bind(),t.uniform2f(Q.uniforms.texelSize,d.texelSizeX,d.texelSizeY),t.uniform1i(Q.uniforms.uVelocity,d.read.attach(0)),T(J),Z.bind(),t.uniform1i(Z.uniforms.uTexture,C.read.attach(0)),t.uniform1f(Z.uniforms.value,i.pressure),T(C.write),C.swap(),O.bind(),t.uniform2f(O.uniforms.texelSize,d.texelSizeX,d.texelSizeY),t.uniform1i(O.uniforms.uDivergence,J.attach(0));for(let n=0;n<i.pressureIteration;n++)t.uniform1i(O.uniforms.uPressure,C.read.attach(1)),T(C.write),C.swap();N.bind(),t.uniform2f(N.uniforms.texelSize,d.texelSizeX,d.texelSizeY),t.uniform1i(N.uniforms.uPressure,C.read.attach(0)),t.uniform1i(N.uniforms.uVelocity,d.read.attach(1)),T(d.write),d.swap(),D.bind(),t.uniform2f(D.uniforms.texelSize,d.texelSizeX,d.texelSizeY),p.supportLinearFiltering||t.uniform2f(D.uniforms.dyeTexelSize,d.texelSizeX,d.texelSizeY);let r=d.read.attach(0);t.uniform1i(D.uniforms.uVelocity,r),t.uniform1i(D.uniforms.uSource,r),t.uniform1f(D.uniforms.dt,e),t.uniform1f(D.uniforms.dissipation,i.velocityDissipation),T(d.write),d.swap(),p.supportLinearFiltering||t.uniform2f(D.uniforms.dyeTexelSize,R.texelSizeX,R.texelSizeY),t.uniform1i(D.uniforms.uVelocity,d.read.attach(0)),t.uniform1i(D.uniforms.uSource,R.read.attach(1)),t.uniform1f(D.uniforms.dissipation,i.densityDissipation),T(R.write),R.swap()}function he(e){t.blendFunc(t.ONE,t.ONE_MINUS_SRC_ALPHA),t.enable(t.BLEND),Ze(e)}function Ze(e){let r=e==null?t.drawingBufferWidth:e.width,n=e==null?t.drawingBufferHeight:e.height;H.bind(),i.shading&&t.uniform2f(H.uniforms.texelSize,1/r,1/n),t.uniform1i(H.uniforms.uTexture,R.read.attach(0)),T(e)}function Qe(e){let r=e.deltaX*i.splatForce,n=e.deltaY*i.splatForce,o=ot(e.color);ie(e.texcoordX,e.texcoordY,r,n,o)}function pe(e){let r=W();r.r*=10,r.g*=10,r.b*=10;let n=10*(Math.random()-.5),o=30*(Math.random()-.5);ie(e.texcoordX,e.texcoordY,n,o,r)}function ie(e,r,n,o,u){A.bind(),t.uniform1i(A.uniforms.uTarget,d.read.attach(0)),t.uniform1f(A.uniforms.aspectRatio,a.width/a.height),t.uniform2f(A.uniforms.point,e,r),t.uniform3f(A.uniforms.color,n,o,0),t.uniform1f(A.uniforms.radius,et(i.splatRadius/100)),T(d.write),d.swap(),t.uniform1i(A.uniforms.uTarget,R.read.attach(0)),t.uniform3f(A.uniforms.color,u.r,u.g,u.b),T(R.write),R.swap()}function et(e){let r=a.width/a.height;return r>1&&(e*=r),e}let xe=e=>{let r=b[0],n=a.getBoundingClientRect(),o=y(e.clientX-n.left),u=y(e.clientY-n.top);Te(r,-1,o,u),pe(r)},ge=e=>{let r=b[0],n=a.getBoundingClientRect(),o=y(e.clientX-n.left),u=y(e.clientY-n.top),l=r.color;ye(r,o,u,l)},be=e=>{let r=e.targetTouches,n=a.getBoundingClientRect(),o=b[0];for(let u=0;u<r.length;u++){let l=y(r[u].clientX-n.left),c=y(r[u].clientY-n.top);Te(o,r[u].identifier,l,c),pe(o)}},Re=e=>{e.preventDefault();let r=e.targetTouches,n=a.getBoundingClientRect(),o=b[0];for(let u=0;u<r.length;u++){let l=y(r[u].clientX-n.left),c=y(r[u].clientY-n.top);ye(o,l,c,o.color)}},Ee=e=>{let r=e.changedTouches,n=b[0];for(let o=0;o<r.length;o++)tt(n)};window.addEventListener("mousedown",xe),window.addEventListener("mousemove",ge),window.addEventListener("touchstart",be),window.addEventListener("touchmove",Re,{passive:!1}),window.addEventListener("touchend",Ee);function Te(e,r,n,o){e.id=r,e.down=!0,e.moved=!1,e.texcoordX=n/a.width,e.texcoordY=1-o/a.height,e.prevTexcoordX=e.texcoordX,e.prevTexcoordY=e.texcoordY,e.deltaX=0,e.deltaY=0,e.color=Fe(W())}function ye(e,r,n,o){e.prevTexcoordX=e.texcoordX,e.prevTexcoordY=e.texcoordY,e.texcoordX=r/a.width,e.texcoordY=1-n/a.height,e.deltaX=rt(e.texcoordX-e.prevTexcoordX),e.deltaY=nt(e.texcoordY-e.prevTexcoordY),e.moved=Math.abs(e.deltaX)>0||Math.abs(e.deltaY)>0,e.color=o}function tt(e){e.down=!1}function rt(e){let r=a.width/a.height;return r<1&&(e*=r),e}function nt(e){let r=a.width/a.height;return r>1&&(e/=r),e}function W(){let e=i.colorIntensity,r=i.palette;if(r&&r.length>0){let o=r[Math.floor(Math.random()*r.length)],u=gt(o);if(u)return{r:u.r*e,g:u.g*e,b:u.b*e}}let n=it(Math.random(),1,1);return n.r*=e,n.g*=e,n.b*=e,n}function Fe(e){return[e.r,e.g,e.b]}function ot(e){return{r:e[0],g:e[1],b:e[2]}}function it(e,r,n){let o=0,u=0,l=0,c=Math.floor(e*6),h=e*6-c,g=n*(1-r),B=n*(1-h*r),f=n*(1-(1-h)*r);switch(c%6){case 0:o=n,u=f,l=g;break;case 1:o=B,u=n,l=g;break;case 2:o=g,u=n,l=f;break;case 3:o=g,u=B,l=n;break;case 4:o=f,u=g,l=n;break;case 5:o=n,u=g,l=B;break}return{r:o,g:u,b:l}}function ut(e,r,n){let o=n-r;return o===0?r:(e-r)%o+r}function Se(e){let r=t.drawingBufferWidth/t.drawingBufferHeight;r<1&&(r=1/r);let n=Math.round(e),o=Math.round(e*r);return t.drawingBufferWidth>t.drawingBufferHeight?{width:o,height:n}:{width:n,height:o}}function y(e){let r=Math.min(window.devicePixelRatio||1,Math.max(1,i.maxDpr));return Math.floor(e*r)}function st(e){if(e.length===0)return 0;let r=0;for(let n=0;n<e.length;n++)r=(r<<5)-r+e.charCodeAt(n),r|=0;return r}function at(){var e,r;ue||(ue=!0,q(),window.removeEventListener("mousedown",xe),window.removeEventListener("mousemove",ge),window.removeEventListener("touchstart",be),window.removeEventListener("touchmove",Re),window.removeEventListener("touchend",Ee),window.removeEventListener("resize",Le),document.removeEventListener("visibilitychange",De),(e=E==null?void 0:E.removeEventListener)==null||e.call(E,"change",we),M==null||M.disconnect(),m&&(a==null||a.remove()),(r=t.getExtension("WEBGL_lose_context"))==null||r.loseContext())}let ue=!1,k=!1;function V(){k||ue||(k=!0,ne=Date.now(),oe=requestAnimationFrame(ve))}function q(){k=!1,cancelAnimationFrame(oe)}let De=()=>{i.pauseOnHidden&&(document.hidden?q():z||V())},Le=()=>I(),M=typeof ResizeObserver!="undefined"?new ResizeObserver(()=>I()):null;M==null||M.observe(a);let E=typeof window.matchMedia=="function"?window.matchMedia("(prefers-reduced-motion: reduce)"):null,we=()=>{i.respectReducedMotion&&(E!=null&&E.matches?q():z||V())},z=!1;return window.addEventListener("resize",Le),document.addEventListener("visibilitychange",De),(Ce=E==null?void 0:E.addEventListener)==null||Ce.call(E,"change",we),i.respectReducedMotion&&Rt()?(z=!0,he(null)):V(),{dispose:at,pause(){z=!0,q()},resume(){z=!1,V()},isPaused:()=>z||!k,setConfig(e){let r=e.simResolution!==void 0&&e.simResolution!==i.simResolution||e.dyeResolution!==void 0&&e.dyeResolution!==i.dyeResolution;Object.assign(i,e),e.maxDpr!==void 0&&I(),r&&te(),e.zIndex!==void 0&&(a.style.zIndex=String(e.zIndex)),e.pointerEvents!==void 0&&(a.style.pointerEvents=e.pointerEvents?"auto":"none")},splat(e,r,n){let o=a.getBoundingClientRect(),u=y(e),l=y(r),c=n!=null?n:W();ie(u,a.height-l,0,0,c)},get canvas(){return a}}};var Ge=require("react/jsx-runtime"),Et=["densityDissipation","velocityDissipation","pressure","pressureIteration","curl","splatRadius","splatForce","shading","colorUpdateSpeed","paused","transparent","backColor","palette","colorIntensity","zIndex","pointerEvents","maxDpr","pauseOnHidden","respectReducedMotion"],Tt=s=>JSON.stringify([s==null?void 0:s.id,s==null?void 0:s.position,s==null?void 0:s.className,s==null?void 0:s.simResolution,s==null?void 0:s.dyeResolution,s==null?void 0:s.captureResolution]);function Ue(s,i){let m=P.default.useRef(null),a=P.default.useRef(s);a.current=s;let F=Tt(s);return P.default.useEffect(()=>{let w=ae({...a.current,...i!=null&&i.current?{container:i.current}:{}});return m.current=w,()=>{w.dispose(),m.current=null}},[F,i]),P.default.useEffect(()=>{let w=m.current;if(!w||!s)return;let b={};for(let t of Et)s[t]!==void 0&&(b[t]=s[t]);w.setConfig(b)}),m}var yt=P.default.forwardRef(function({config:i,scoped:m=!1,className:a,style:F,children:w},b){let t=P.default.useRef(null),p=Ue(i,m?t:void 0);return P.default.useImperativeHandle(b,()=>({dispose:()=>{var v;return(v=p.current)==null?void 0:v.dispose()},pause:()=>{var v;return(v=p.current)==null?void 0:v.pause()},resume:()=>{var v;return(v=p.current)==null?void 0:v.resume()},isPaused:()=>{var v,x;return(x=(v=p.current)==null?void 0:v.isPaused())!=null?x:!0},setConfig:v=>{var x;return(x=p.current)==null?void 0:x.setConfig(v)},splat:(v,x,j)=>{var X;return(X=p.current)==null?void 0:X.splat(v,x,j)},get canvas(){var v,x;return(x=(v=p.current)==null?void 0:v.canvas)!=null?x:null}}),[p]),m?(0,Ge.jsx)("div",{ref:t,className:a,style:{position:"relative",overflow:"hidden",...F},children:w}):null});0&&(module.exports={SmokeyFluidCursor,initFluid,useSmokeyFluidCursor});
2
+ "use strict";var I=Object.create;var y=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,h=Object.prototype.hasOwnProperty;var v=(e,r)=>{for(var s in r)y(e,s,{get:r[s],enumerable:!0})},F=(e,r,s,d)=>{if(r&&typeof r=="object"||typeof r=="function")for(let a of N(r))!h.call(e,a)&&a!==s&&y(e,a,{get:()=>r[a],enumerable:!(d=P(r,a))||d.enumerable});return e};var H=(e,r,s)=>(s=e!=null?I(f(e)):{},F(r||!e||!e.__esModule?y(s,"default",{value:e,enumerable:!0}):s,e)),E=e=>F(y({},"__esModule",{value:!0}),e);var b={};v(b,{SmokeyFluidCursor:()=>O,characterNames:()=>u.characterNames,getPreset:()=>u.getPreset,initFluid:()=>u.initFluid,paletteNames:()=>u.paletteNames,presetNames:()=>u.presetNames,presets:()=>u.presets,useSmokeyFluidCursor:()=>C});module.exports=E(b);var n=H(require("react")),k=require("smokey-fluid-cursor"),u=require("smokey-fluid-cursor"),R=require("react/jsx-runtime"),x=["densityDissipation","velocityDissipation","pressure","pressureIteration","curl","splatRadius","splatForce","shading","colorUpdateSpeed","paused","transparent","backColor","palette","colorIntensity","zIndex","pointerEvents","maxDpr","pauseOnHidden","respectReducedMotion"],L=e=>JSON.stringify([e==null?void 0:e.id,e==null?void 0:e.position,e==null?void 0:e.className,e==null?void 0:e.simResolution,e==null?void 0:e.dyeResolution,e==null?void 0:e.captureResolution]);function C(e,r){let s=n.default.useRef(null),d=n.default.useRef(e);d.current=e;let a=L(e);return n.default.useEffect(()=>{let i=(0,k.initFluid)({...d.current,...r!=null&&r.current?{container:r.current}:{}});return s.current=i,()=>{i.dispose(),s.current=null}},[a,r]),n.default.useEffect(()=>{let i=s.current;if(!i||!e)return;let m={};for(let p of x)e[p]!==void 0&&(m[p]=e[p]);i.setConfig(m)}),s}var O=n.default.forwardRef(function({config:r,scoped:s=!1,className:d,style:a,children:i},m){let p=n.default.useRef(null),o=C(r,s?p:void 0);return n.default.useImperativeHandle(m,()=>({dispose:()=>{var t;return(t=o.current)==null?void 0:t.dispose()},pause:()=>{var t;return(t=o.current)==null?void 0:t.pause()},resume:()=>{var t;return(t=o.current)==null?void 0:t.resume()},isPaused:()=>{var t,l;return(l=(t=o.current)==null?void 0:t.isPaused())!=null?l:!0},setConfig:t=>{var l;return(l=o.current)==null?void 0:l.setConfig(t)},splat:(t,l,S)=>{var c;return(c=o.current)==null?void 0:c.splat(t,l,S)},get canvas(){var t,l;return(l=(t=o.current)==null?void 0:t.canvas)!=null?l:null}}),[o]),s?(0,R.jsx)("div",{ref:p,className:d,style:{position:"relative",overflow:"hidden",...a},children:i}):null});0&&(module.exports={SmokeyFluidCursor,characterNames,getPreset,initFluid,paletteNames,presetNames,presets,useSmokeyFluidCursor});
package/dist/index.mjs CHANGED
@@ -1,195 +1,2 @@
1
1
  "use client";
2
- import A from"react";var it={simResolution:128,dyeResolution:1440,captureResolution:512,densityDissipation:3.5,velocityDissipation:2,pressure:.1,pressureIteration:20,curl:10,splatRadius:.5,splatForce:6e3,shading:!0,colorUpdateSpeed:10,paused:!1,backColor:{r:0,g:0,b:0},transparent:!0,id:"smokey-fluid-canvas",position:"fixed",zIndex:-9999,pointerEvents:!1,maxDpr:2,pauseOnHidden:!0,respectReducedMotion:!0,palette:null,colorIntensity:.15},Be=l=>{var u;return l?typeof l!="string"?l:(u=document.querySelector(l))!=null?u:document.getElementById(l):null},ut=l=>{let u=l.trim().replace(/^#/,"");return u.length===3&&(u=u[0]+u[0]+u[1]+u[1]+u[2]+u[2]),/^[0-9a-f]{6}$/i.test(u)?{r:parseInt(u.slice(0,2),16)/255,g:parseInt(u.slice(2,4),16)/255,b:parseInt(u.slice(4,6),16)/255}:null},st=l=>{var s;if(l>=0||typeof document=="undefined"||typeof process!="undefined"&&((s=process.env)==null?void 0:s.NODE_ENV)==="production")return;let u=window.getComputedStyle(document.body).backgroundColor;u&&u!=="transparent"&&!/rgba\(\s*0\s*,\s*0\s*,\s*0\s*,\s*0\s*\)/.test(u)&&console.warn("[smokey-fluid-cursor] <body> has an opaque background ("+u+") and the canvas sits at z-index "+l+`, so the effect will be painted over and stay invisible.
3
- Move the background to <html>, or give the canvas a zIndex above your background.`)},at=()=>typeof window!="undefined"&&typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches,ue={dispose:()=>{},pause:()=>{},resume:()=>{},isPaused:()=>!0,setConfig:()=>{},splat:()=>{},canvas:null},Ce=(l={})=>{var Le,we,_e;let u={...it,...l};if(typeof document=="undefined")return ue;let E=!1,s=(Le=Be(u.canvas))!=null?Le:document.getElementById(u.id);if(!s){let e=(we=Be(u.container))!=null?we:document.body;if(!e)return ue;s=document.createElement("canvas"),s.id=u.id,e.appendChild(s),E=!0}u.className&&s.classList.add(...u.className.split(/\s+/));let z=u.position==="fixed"||u.position==="absolute";Object.assign(s.style,{position:u.position,...z?{top:"0",left:"0",width:"100%",height:"100%"}:{},display:"block",pointerEvents:u.pointerEvents?"auto":"none",zIndex:String(u.zIndex)}),st(u.zIndex),I();class L{constructor(){this.id=-1;this.texcoordX=0;this.texcoordY=0;this.prevTexcoordX=0;this.prevTexcoordY=0;this.deltaX=0;this.deltaY=0;this.down=!1;this.moved=!1;this.color=[30,0,300]}}let g=[];g.push(new L);let t,h;try{({gl:t,ext:h}=m(s))}catch(e){typeof console!="undefined"&&console.warn("[smokey-fluid-cursor] WebGL is unavailable; the cursor effect is disabled.",e);let r=s,n=E;return{...ue,dispose:()=>{n&&r.remove()},setConfig:o=>{o.zIndex!==void 0&&(r.style.zIndex=String(o.zIndex)),o.pointerEvents!==void 0&&(r.style.pointerEvents=o.pointerEvents?"auto":"none")},get canvas(){return r}}}h.supportLinearFiltering||(u.dyeResolution=512,u.shading=!1);function m(e){let r={alpha:!0,depth:!1,stencil:!1,antialias:!1,preserveDrawingBuffer:!1},n=e.getContext("webgl2",r),o=!!n;if(o||(n=e.getContext("webgl",r)||e.getContext("experimental-webgl",r)),!n)throw new Error("WebGL not supported");let i=null,c,a;if(o){let f=n;f.getExtension("EXT_color_buffer_float"),c=!!f.getExtension("OES_texture_float_linear"),a=f.HALF_FLOAT}else{let f=n;if(i=f.getExtension("OES_texture_half_float"),c=!!f.getExtension("OES_texture_half_float_linear"),!i)throw new Error("OES_texture_half_float not supported on WebGL1");a=i.HALF_FLOAT_OES}n.clearColor(0,0,0,1);let v=null,x=null,_=null;if(o){let f=n;v=p(f,f.RGBA16F,f.RGBA,a),x=p(f,f.RG16F,f.RG,a),_=p(f,f.R16F,f.RED,a)}else{let f=n;v=p(f,f.RGBA,f.RGBA,a),x=p(f,f.RGBA,f.RGBA,a),_=p(f,f.RGBA,f.RGBA,a)}return{gl:n,ext:{formatRGBA:v,formatRG:x,formatR:_,halfFloatTexType:a,supportLinearFiltering:c,isWebGL2:o}}}function p(e,r,n,o){if(!K(e,r,n,o)){if(e.RGBA16F!==void 0){let i=e;switch(r){case i.R16F:return p(i,i.RG16F,i.RG,o);case i.RG16F:return p(i,i.RGBA16F,i.RGBA,o);default:return null}}return null}return{internalFormat:r,format:n}}function K(e,r,n,o){let i=e.createTexture();if(!i)return!1;e.bindTexture(e.TEXTURE_2D,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),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,r,4,4,0,n,o,null);let c=e.createFramebuffer();if(!c)return!1;e.bindFramebuffer(e.FRAMEBUFFER,c),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,i,0);let a=e.checkFramebufferStatus(e.FRAMEBUFFER);return e.bindFramebuffer(e.FRAMEBUFFER,null),e.deleteFramebuffer(c),e.deleteTexture(i),a===e.FRAMEBUFFER_COMPLETE}class X{constructor(r,n){this.vertexShader=r,this.fragmentShaderSource=n,this.programs={},this.activeProgram=null,this.uniforms={}}setKeywords(r){let n=0;for(let i=0;i<r.length;i++)n+=nt(r[i]);let o=this.programs[n];if(!o){let i=F(t,t.FRAGMENT_SHADER,ce(this.fragmentShaderSource,r));o=se(t,this.vertexShader,i),this.programs[n]=o}o!==this.activeProgram&&(this.uniforms=ae(t,o),this.activeProgram=o)}bind(){this.activeProgram&&t.useProgram(this.activeProgram)}}class w{constructor(r,n){this.program=se(t,r,n),this.uniforms=ae(t,this.program)}bind(){this.program&&t.useProgram(this.program)}}function se(e,r,n){let o=e.createProgram();return e.attachShader(o,r),e.attachShader(o,n),e.bindAttribLocation(o,0,"aPosition"),e.linkProgram(o),e.getProgramParameter(o,e.LINK_STATUS)||console.trace(e.getProgramInfoLog(o)),o}function ae(e,r){let n={},o=e.getProgramParameter(r,e.ACTIVE_UNIFORMS);for(let i=0;i<o;i++){let c=e.getActiveUniform(r,i);if(!c)continue;let a=c.name,v=e.getUniformLocation(r,a);v&&(n[a]=v)}return n}function F(e,r,n){let o=e.createShader(r);return e.shaderSource(o,n),e.compileShader(o),e.getShaderParameter(o,e.COMPILE_STATUS)||console.trace(e.getShaderInfoLog(o)),o}function ce(e,r){if(!r||r.length===0)return e;let n="";return r.forEach(o=>{n+="#define "+o+`
4
- `}),n+e}let D=F(t,t.VERTEX_SHADER,`precision highp float;
5
- attribute vec2 aPosition;
6
- varying vec2 vUv;
7
- varying vec2 vL;
8
- varying vec2 vR;
9
- varying vec2 vT;
10
- varying vec2 vB;
11
- uniform vec2 texelSize;
12
- void main () {
13
- vUv = aPosition * 0.5 + 0.5;
14
- vL = vUv - vec2(texelSize.x, 0.0);
15
- vR = vUv + vec2(texelSize.x, 0.0);
16
- vT = vUv + vec2(0.0, texelSize.y);
17
- vB = vUv - vec2(0.0, texelSize.y);
18
- gl_Position = vec4(aPosition, 0.0, 1.0);
19
- }`),Ae=F(t,t.FRAGMENT_SHADER,`precision mediump float;
20
- precision mediump sampler2D;
21
- varying highp vec2 vUv;
22
- uniform sampler2D uTexture;
23
- void main () {
24
- gl_FragColor = texture2D(uTexture, vUv);
25
- }`),Pe=F(t,t.FRAGMENT_SHADER,`precision mediump float;
26
- precision mediump sampler2D;
27
- varying highp vec2 vUv;
28
- uniform sampler2D uTexture;
29
- uniform float value;
30
- void main () {
31
- gl_FragColor = value * texture2D(uTexture, vUv);
32
- }`),Ue=`precision highp float;
33
- precision highp sampler2D;
34
- varying vec2 vUv;
35
- varying vec2 vL;
36
- varying vec2 vR;
37
- varying vec2 vT;
38
- varying vec2 vB;
39
- uniform sampler2D uTexture;
40
- uniform vec2 texelSize;
41
- void main () {
42
- vec3 c = texture2D(uTexture, vUv).rgb;
43
- #ifdef shading
44
- vec3 lc = texture2D(uTexture, vL).rgb;
45
- vec3 rc = texture2D(uTexture, vR).rgb;
46
- vec3 tc = texture2D(uTexture, vT).rgb;
47
- vec3 bc = texture2D(uTexture, vB).rgb;
48
- float dx = length(rc) - length(lc);
49
- float dy = length(tc) - length(bc);
50
- vec3 n = normalize(vec3(dx, dy, length(texelSize)));
51
- vec3 l = vec3(0.0, 0.0, 1.0);
52
- float diffuse = clamp(dot(n, l) + 0.7, 0.7, 1.0);
53
- c *= diffuse;
54
- #endif
55
- float a = max(c.r, max(c.g, c.b));
56
- gl_FragColor = vec4(c, a);
57
- }`,Ge=F(t,t.FRAGMENT_SHADER,`precision highp float;
58
- precision highp sampler2D;
59
- varying vec2 vUv;
60
- uniform sampler2D uTarget;
61
- uniform float aspectRatio;
62
- uniform vec3 color;
63
- uniform vec2 point;
64
- uniform float radius;
65
- void main () {
66
- vec2 p = vUv - point.xy;
67
- p.x *= aspectRatio;
68
- vec3 splat = exp(-dot(p, p) / radius) * color;
69
- vec3 base = texture2D(uTarget, vUv).xyz;
70
- gl_FragColor = vec4(base + splat, 1.0);
71
- }`),Me=F(t,t.FRAGMENT_SHADER,ce(`precision highp float;
72
- precision highp sampler2D;
73
- varying vec2 vUv;
74
- uniform sampler2D uVelocity;
75
- uniform sampler2D uSource;
76
- uniform vec2 texelSize;
77
- uniform vec2 dyeTexelSize;
78
- uniform float dt;
79
- uniform float dissipation;
80
- vec4 bilerp (sampler2D sam, vec2 uv, vec2 tsize) {
81
- vec2 st = uv / tsize - 0.5;
82
- vec2 iuv = floor(st);
83
- vec2 fuv = fract(st);
84
- vec4 a = texture2D(sam, (iuv + vec2(0.5, 0.5)) * tsize);
85
- vec4 b = texture2D(sam, (iuv + vec2(1.5, 0.5)) * tsize);
86
- vec4 c = texture2D(sam, (iuv + vec2(0.5, 1.5)) * tsize);
87
- vec4 d = texture2D(sam, (iuv + vec2(1.5, 1.5)) * tsize);
88
- return mix(mix(a, b, fuv.x), mix(c, d, fuv.x), fuv.y);
89
- }
90
- void main () {
91
- #ifdef MANUAL_FILTERING
92
- vec2 coord = vUv - dt * bilerp(uVelocity, vUv, texelSize).xy * texelSize;
93
- vec4 result = bilerp(uSource, coord, dyeTexelSize);
94
- #else
95
- vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;
96
- vec4 result = texture2D(uSource, coord);
97
- #endif
98
- float decay = 1.0 + dissipation * dt;
99
- gl_FragColor = result / decay;
100
- }`,h.supportLinearFiltering?null:["MANUAL_FILTERING"])),ze=F(t,t.FRAGMENT_SHADER,`precision mediump float;
101
- precision mediump sampler2D;
102
- varying highp vec2 vUv;
103
- varying highp vec2 vL;
104
- varying highp vec2 vR;
105
- varying highp vec2 vT;
106
- varying highp vec2 vB;
107
- uniform sampler2D uVelocity;
108
- void main () {
109
- float L = texture2D(uVelocity, vL).x;
110
- float R = texture2D(uVelocity, vR).x;
111
- float T = texture2D(uVelocity, vT).y;
112
- float B = texture2D(uVelocity, vB).y;
113
- vec2 C = texture2D(uVelocity, vUv).xy;
114
- if (vL.x < 0.0) { L = -C.x; }
115
- if (vR.x > 1.0) { R = -C.x; }
116
- if (vT.y > 1.0) { T = -C.y; }
117
- if (vB.y < 0.0) { B = -C.y; }
118
- float div = 0.5 * (R - L + T - B);
119
- gl_FragColor = vec4(div, 0.0, 0.0, 1.0);
120
- }`),Ie=F(t,t.FRAGMENT_SHADER,`precision mediump float;
121
- precision mediump sampler2D;
122
- varying highp vec2 vUv;
123
- varying highp vec2 vL;
124
- varying highp vec2 vR;
125
- varying highp vec2 vT;
126
- varying highp vec2 vB;
127
- uniform sampler2D uVelocity;
128
- void main () {
129
- float L = texture2D(uVelocity, vL).y;
130
- float R = texture2D(uVelocity, vR).y;
131
- float T = texture2D(uVelocity, vT).x;
132
- float B = texture2D(uVelocity, vB).x;
133
- float vorticity = R - L - T + B;
134
- gl_FragColor = vec4(0.5 * vorticity, 0.0, 0.0, 1.0);
135
- }`),Xe=F(t,t.FRAGMENT_SHADER,`precision highp float;
136
- precision highp sampler2D;
137
- varying vec2 vUv;
138
- varying vec2 vL;
139
- varying vec2 vR;
140
- varying vec2 vT;
141
- varying vec2 vB;
142
- uniform sampler2D uVelocity;
143
- uniform sampler2D uCurl;
144
- uniform float curl;
145
- uniform float dt;
146
- void main () {
147
- float L = texture2D(uCurl, vL).x;
148
- float R = texture2D(uCurl, vR).x;
149
- float T = texture2D(uCurl, vT).x;
150
- float B = texture2D(uCurl, vB).x;
151
- float C = texture2D(uCurl, vUv).x;
152
- vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));
153
- force /= length(force) + 0.0001;
154
- force *= curl * C;
155
- force.y *= -1.0;
156
- vec2 velocity = texture2D(uVelocity, vUv).xy;
157
- velocity += force * dt;
158
- velocity = min(max(velocity, -1000.0), 1000.0);
159
- gl_FragColor = vec4(velocity, 0.0, 1.0);
160
- }`),Oe=F(t,t.FRAGMENT_SHADER,`precision mediump float;
161
- precision mediump sampler2D;
162
- varying highp vec2 vUv;
163
- varying highp vec2 vL;
164
- varying highp vec2 vR;
165
- varying highp vec2 vT;
166
- varying highp vec2 vB;
167
- uniform sampler2D uPressure;
168
- uniform sampler2D uDivergence;
169
- void main () {
170
- float L = texture2D(uPressure, vL).x;
171
- float R = texture2D(uPressure, vR).x;
172
- float T = texture2D(uPressure, vT).x;
173
- float B = texture2D(uPressure, vB).x;
174
- float C = texture2D(uPressure, vUv).x;
175
- float divergence = texture2D(uDivergence, vUv).x;
176
- float pressure = (L + R + B + T - divergence) * 0.25;
177
- gl_FragColor = vec4(pressure, 0.0, 0.0, 1.0);
178
- }`),Ne=F(t,t.FRAGMENT_SHADER,`precision mediump float;
179
- precision mediump sampler2D;
180
- varying highp vec2 vUv;
181
- varying highp vec2 vL;
182
- varying highp vec2 vR;
183
- varying highp vec2 vT;
184
- varying highp vec2 vB;
185
- uniform sampler2D uPressure;
186
- uniform sampler2D uVelocity;
187
- void main () {
188
- float L = texture2D(uPressure, vL).x;
189
- float R = texture2D(uPressure, vR).x;
190
- float T = texture2D(uPressure, vT).x;
191
- float B = texture2D(uPressure, vB).x;
192
- vec2 velocity = texture2D(uVelocity, vUv).xy;
193
- velocity.xy -= vec2(R - L, T - B);
194
- gl_FragColor = vec4(velocity, 0.0, 1.0);
195
- }`),T=(()=>{let e=t.createBuffer();t.bindBuffer(t.ARRAY_BUFFER,e),t.bufferData(t.ARRAY_BUFFER,new Float32Array([-1,-1,-1,1,1,1,1,-1]),t.STATIC_DRAW);let r=t.createBuffer();return t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,r),t.bufferData(t.ELEMENT_ARRAY_BUFFER,new Uint16Array([0,1,2,0,2,3]),t.STATIC_DRAW),t.vertexAttribPointer(0,2,t.FLOAT,!1,0,0),t.enableVertexAttribArray(0),(n,o=!1)=>{n==null?(t.viewport(0,0,t.drawingBufferWidth,t.drawingBufferHeight),t.bindFramebuffer(t.FRAMEBUFFER,null)):(t.viewport(0,0,n.width,n.height),t.bindFramebuffer(t.FRAMEBUFFER,n.fbo)),o&&(t.clearColor(0,0,0,1),t.clear(t.COLOR_BUFFER_BIT)),t.drawElements(t.TRIANGLES,6,t.UNSIGNED_SHORT,0)}})(),b,d,j,J,B,le=new w(D,Ae),$=new w(D,Pe),C=new w(D,Ge),S=new w(D,Me),Z=new w(D,ze),Q=new w(D,Ie),P=new w(D,Xe),O=new w(D,Oe),N=new w(D,Ne),H=new X(D,Ue);function ee(){let e=ye(u.simResolution),r=ye(u.dyeResolution),n=h.halfFloatTexType,o=h.formatRGBA,i=h.formatRG,c=h.formatR,a=h.supportLinearFiltering?t.LINEAR:t.NEAREST;t.disable(t.BLEND),b==null?b=te(r.width,r.height,o.internalFormat,o.format,n,a):b=de(b,r.width,r.height,o.internalFormat,o.format,n,a),d==null?d=te(e.width,e.height,i.internalFormat,i.format,n,a):d=de(d,e.width,e.height,i.internalFormat,i.format,n,a),j=U(e.width,e.height,c.internalFormat,c.format,n,t.NEAREST),J=U(e.width,e.height,c.internalFormat,c.format,n,t.NEAREST),B=te(e.width,e.height,c.internalFormat,c.format,n,t.NEAREST)}function U(e,r,n,o,i,c){t.activeTexture(t.TEXTURE0);let a=t.createTexture();t.bindTexture(t.TEXTURE_2D,a),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,c),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,c),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texImage2D(t.TEXTURE_2D,0,n,e,r,0,o,i,null);let v=t.createFramebuffer();t.bindFramebuffer(t.FRAMEBUFFER,v),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,a,0),t.viewport(0,0,e,r),t.clear(t.COLOR_BUFFER_BIT);let x=1/e,_=1/r;return{texture:a,fbo:v,width:e,height:r,texelSizeX:x,texelSizeY:_,attach(f){return t.activeTexture(t.TEXTURE0+f),t.bindTexture(t.TEXTURE_2D,a),f}}}function te(e,r,n,o,i,c){let a=U(e,r,n,o,i,c),v=U(e,r,n,o,i,c);return{width:e,height:r,texelSizeX:a.texelSizeX,texelSizeY:a.texelSizeY,get read(){return a},set read(x){a=x},get write(){return v},set write(x){v=x},swap(){let x=a;a=v,v=x}}}function He(e,r,n,o,i,c,a){let v=U(r,n,o,i,c,a);return le.bind(),t.uniform1i(le.uniforms.uTexture,e.attach(0)),T(v),v}function de(e,r,n,o,i,c,a){return e.width===r&&e.height===n||(e.read=He(e.read,r,n,o,i,c,a),e.write=U(r,n,o,i,c,a),e.width=r,e.height=n,e.texelSizeX=1/r,e.texelSizeY=1/n),e}function Ye(){let e=[];u.shading&&e.push("shading"),H.setKeywords(e)}Ye(),ee();let re=Date.now(),Y=0,ne=0;function fe(){let e=We();I()&&ee(),ke(e),Ve(),u.paused||qe(e),me(null),ne=requestAnimationFrame(fe)}function We(){let e=Date.now(),r=(e-re)/1e3;return r=Math.min(r,.016666),re=e,r}function I(){let e=y(s.clientWidth),r=y(s.clientHeight);return s.width!==e||s.height!==r?(s.width=e,s.height=r,!0):!1}function ke(e){Y+=e*u.colorUpdateSpeed,Y>=1&&(Y=rt(Y,0,1),g.forEach(r=>{r.color=Te(W())}))}function Ve(){g.forEach(e=>{e.moved&&(e.moved=!1,je(e))})}function qe(e){t.disable(t.BLEND),Q.bind(),t.uniform2f(Q.uniforms.texelSize,d.texelSizeX,d.texelSizeY),t.uniform1i(Q.uniforms.uVelocity,d.read.attach(0)),T(J),P.bind(),t.uniform2f(P.uniforms.texelSize,d.texelSizeX,d.texelSizeY),t.uniform1i(P.uniforms.uVelocity,d.read.attach(0)),t.uniform1i(P.uniforms.uCurl,J.attach(1)),t.uniform1f(P.uniforms.curl,u.curl),t.uniform1f(P.uniforms.dt,e),T(d.write),d.swap(),Z.bind(),t.uniform2f(Z.uniforms.texelSize,d.texelSizeX,d.texelSizeY),t.uniform1i(Z.uniforms.uVelocity,d.read.attach(0)),T(j),$.bind(),t.uniform1i($.uniforms.uTexture,B.read.attach(0)),t.uniform1f($.uniforms.value,u.pressure),T(B.write),B.swap(),O.bind(),t.uniform2f(O.uniforms.texelSize,d.texelSizeX,d.texelSizeY),t.uniform1i(O.uniforms.uDivergence,j.attach(0));for(let n=0;n<u.pressureIteration;n++)t.uniform1i(O.uniforms.uPressure,B.read.attach(1)),T(B.write),B.swap();N.bind(),t.uniform2f(N.uniforms.texelSize,d.texelSizeX,d.texelSizeY),t.uniform1i(N.uniforms.uPressure,B.read.attach(0)),t.uniform1i(N.uniforms.uVelocity,d.read.attach(1)),T(d.write),d.swap(),S.bind(),t.uniform2f(S.uniforms.texelSize,d.texelSizeX,d.texelSizeY),h.supportLinearFiltering||t.uniform2f(S.uniforms.dyeTexelSize,d.texelSizeX,d.texelSizeY);let r=d.read.attach(0);t.uniform1i(S.uniforms.uVelocity,r),t.uniform1i(S.uniforms.uSource,r),t.uniform1f(S.uniforms.dt,e),t.uniform1f(S.uniforms.dissipation,u.velocityDissipation),T(d.write),d.swap(),h.supportLinearFiltering||t.uniform2f(S.uniforms.dyeTexelSize,b.texelSizeX,b.texelSizeY),t.uniform1i(S.uniforms.uVelocity,d.read.attach(0)),t.uniform1i(S.uniforms.uSource,b.read.attach(1)),t.uniform1f(S.uniforms.dissipation,u.densityDissipation),T(b.write),b.swap()}function me(e){t.blendFunc(t.ONE,t.ONE_MINUS_SRC_ALPHA),t.enable(t.BLEND),Ke(e)}function Ke(e){let r=e==null?t.drawingBufferWidth:e.width,n=e==null?t.drawingBufferHeight:e.height;H.bind(),u.shading&&t.uniform2f(H.uniforms.texelSize,1/r,1/n),t.uniform1i(H.uniforms.uTexture,b.read.attach(0)),T(e)}function je(e){let r=e.deltaX*u.splatForce,n=e.deltaY*u.splatForce,o=et(e.color);oe(e.texcoordX,e.texcoordY,r,n,o)}function ve(e){let r=W();r.r*=10,r.g*=10,r.b*=10;let n=10*(Math.random()-.5),o=30*(Math.random()-.5);oe(e.texcoordX,e.texcoordY,n,o,r)}function oe(e,r,n,o,i){C.bind(),t.uniform1i(C.uniforms.uTarget,d.read.attach(0)),t.uniform1f(C.uniforms.aspectRatio,s.width/s.height),t.uniform2f(C.uniforms.point,e,r),t.uniform3f(C.uniforms.color,n,o,0),t.uniform1f(C.uniforms.radius,Je(u.splatRadius/100)),T(d.write),d.swap(),t.uniform1i(C.uniforms.uTarget,b.read.attach(0)),t.uniform3f(C.uniforms.color,i.r,i.g,i.b),T(b.write),b.swap()}function Je(e){let r=s.width/s.height;return r>1&&(e*=r),e}let he=e=>{let r=g[0],n=s.getBoundingClientRect(),o=y(e.clientX-n.left),i=y(e.clientY-n.top);Re(r,-1,o,i),ve(r)},pe=e=>{let r=g[0],n=s.getBoundingClientRect(),o=y(e.clientX-n.left),i=y(e.clientY-n.top),c=r.color;Ee(r,o,i,c)},xe=e=>{let r=e.targetTouches,n=s.getBoundingClientRect(),o=g[0];for(let i=0;i<r.length;i++){let c=y(r[i].clientX-n.left),a=y(r[i].clientY-n.top);Re(o,r[i].identifier,c,a),ve(o)}},ge=e=>{e.preventDefault();let r=e.targetTouches,n=s.getBoundingClientRect(),o=g[0];for(let i=0;i<r.length;i++){let c=y(r[i].clientX-n.left),a=y(r[i].clientY-n.top);Ee(o,c,a,o.color)}},be=e=>{let r=e.changedTouches,n=g[0];for(let o=0;o<r.length;o++)$e(n)};window.addEventListener("mousedown",he),window.addEventListener("mousemove",pe),window.addEventListener("touchstart",xe),window.addEventListener("touchmove",ge,{passive:!1}),window.addEventListener("touchend",be);function Re(e,r,n,o){e.id=r,e.down=!0,e.moved=!1,e.texcoordX=n/s.width,e.texcoordY=1-o/s.height,e.prevTexcoordX=e.texcoordX,e.prevTexcoordY=e.texcoordY,e.deltaX=0,e.deltaY=0,e.color=Te(W())}function Ee(e,r,n,o){e.prevTexcoordX=e.texcoordX,e.prevTexcoordY=e.texcoordY,e.texcoordX=r/s.width,e.texcoordY=1-n/s.height,e.deltaX=Ze(e.texcoordX-e.prevTexcoordX),e.deltaY=Qe(e.texcoordY-e.prevTexcoordY),e.moved=Math.abs(e.deltaX)>0||Math.abs(e.deltaY)>0,e.color=o}function $e(e){e.down=!1}function Ze(e){let r=s.width/s.height;return r<1&&(e*=r),e}function Qe(e){let r=s.width/s.height;return r>1&&(e/=r),e}function W(){let e=u.colorIntensity,r=u.palette;if(r&&r.length>0){let o=r[Math.floor(Math.random()*r.length)],i=ut(o);if(i)return{r:i.r*e,g:i.g*e,b:i.b*e}}let n=tt(Math.random(),1,1);return n.r*=e,n.g*=e,n.b*=e,n}function Te(e){return[e.r,e.g,e.b]}function et(e){return{r:e[0],g:e[1],b:e[2]}}function tt(e,r,n){let o=0,i=0,c=0,a=Math.floor(e*6),v=e*6-a,x=n*(1-r),_=n*(1-v*r),f=n*(1-(1-v)*r);switch(a%6){case 0:o=n,i=f,c=x;break;case 1:o=_,i=n,c=x;break;case 2:o=x,i=n,c=f;break;case 3:o=x,i=_,c=n;break;case 4:o=f,i=x,c=n;break;case 5:o=n,i=x,c=_;break}return{r:o,g:i,b:c}}function rt(e,r,n){let o=n-r;return o===0?r:(e-r)%o+r}function ye(e){let r=t.drawingBufferWidth/t.drawingBufferHeight;r<1&&(r=1/r);let n=Math.round(e),o=Math.round(e*r);return t.drawingBufferWidth>t.drawingBufferHeight?{width:o,height:n}:{width:n,height:o}}function y(e){let r=Math.min(window.devicePixelRatio||1,Math.max(1,u.maxDpr));return Math.floor(e*r)}function nt(e){if(e.length===0)return 0;let r=0;for(let n=0;n<e.length;n++)r=(r<<5)-r+e.charCodeAt(n),r|=0;return r}function ot(){var e,r;ie||(ie=!0,q(),window.removeEventListener("mousedown",he),window.removeEventListener("mousemove",pe),window.removeEventListener("touchstart",xe),window.removeEventListener("touchmove",ge),window.removeEventListener("touchend",be),window.removeEventListener("resize",Se),document.removeEventListener("visibilitychange",Fe),(e=R==null?void 0:R.removeEventListener)==null||e.call(R,"change",De),G==null||G.disconnect(),E&&(s==null||s.remove()),(r=t.getExtension("WEBGL_lose_context"))==null||r.loseContext())}let ie=!1,k=!1;function V(){k||ie||(k=!0,re=Date.now(),ne=requestAnimationFrame(fe))}function q(){k=!1,cancelAnimationFrame(ne)}let Fe=()=>{u.pauseOnHidden&&(document.hidden?q():M||V())},Se=()=>I(),G=typeof ResizeObserver!="undefined"?new ResizeObserver(()=>I()):null;G==null||G.observe(s);let R=typeof window.matchMedia=="function"?window.matchMedia("(prefers-reduced-motion: reduce)"):null,De=()=>{u.respectReducedMotion&&(R!=null&&R.matches?q():M||V())},M=!1;return window.addEventListener("resize",Se),document.addEventListener("visibilitychange",Fe),(_e=R==null?void 0:R.addEventListener)==null||_e.call(R,"change",De),u.respectReducedMotion&&at()?(M=!0,me(null)):V(),{dispose:ot,pause(){M=!0,q()},resume(){M=!1,V()},isPaused:()=>M||!k,setConfig(e){let r=e.simResolution!==void 0&&e.simResolution!==u.simResolution||e.dyeResolution!==void 0&&e.dyeResolution!==u.dyeResolution;Object.assign(u,e),e.maxDpr!==void 0&&I(),r&&ee(),e.zIndex!==void 0&&(s.style.zIndex=String(e.zIndex)),e.pointerEvents!==void 0&&(s.style.pointerEvents=e.pointerEvents?"auto":"none")},splat(e,r,n){let o=s.getBoundingClientRect(),i=y(e),c=y(r),a=n!=null?n:W();oe(i,s.height-c,0,0,a)},get canvas(){return s}}};import{jsx as ft}from"react/jsx-runtime";var ct=["densityDissipation","velocityDissipation","pressure","pressureIteration","curl","splatRadius","splatForce","shading","colorUpdateSpeed","paused","transparent","backColor","palette","colorIntensity","zIndex","pointerEvents","maxDpr","pauseOnHidden","respectReducedMotion"],lt=l=>JSON.stringify([l==null?void 0:l.id,l==null?void 0:l.position,l==null?void 0:l.className,l==null?void 0:l.simResolution,l==null?void 0:l.dyeResolution,l==null?void 0:l.captureResolution]);function dt(l,u){let E=A.useRef(null),s=A.useRef(l);s.current=l;let z=lt(l);return A.useEffect(()=>{let L=Ce({...s.current,...u!=null&&u.current?{container:u.current}:{}});return E.current=L,()=>{L.dispose(),E.current=null}},[z,u]),A.useEffect(()=>{let L=E.current;if(!L||!l)return;let g={};for(let t of ct)l[t]!==void 0&&(g[t]=l[t]);L.setConfig(g)}),E}var xt=A.forwardRef(function({config:u,scoped:E=!1,className:s,style:z,children:L},g){let t=A.useRef(null),h=dt(u,E?t:void 0);return A.useImperativeHandle(g,()=>({dispose:()=>{var m;return(m=h.current)==null?void 0:m.dispose()},pause:()=>{var m;return(m=h.current)==null?void 0:m.pause()},resume:()=>{var m;return(m=h.current)==null?void 0:m.resume()},isPaused:()=>{var m,p;return(p=(m=h.current)==null?void 0:m.isPaused())!=null?p:!0},setConfig:m=>{var p;return(p=h.current)==null?void 0:p.setConfig(m)},splat:(m,p,K)=>{var X;return(X=h.current)==null?void 0:X.splat(m,p,K)},get canvas(){var m,p;return(p=(m=h.current)==null?void 0:m.canvas)!=null?p:null}}),[h]),E?ft("div",{ref:t,className:s,style:{position:"relative",overflow:"hidden",...z},children:L}):null});export{xt as SmokeyFluidCursor,Ce as initFluid,dt as useSmokeyFluidCursor};
2
+ import o from"react";import{initFluid as c}from"smokey-fluid-cursor";import{initFluid as h,presets as v,presetNames as H,paletteNames as E,characterNames as x,getPreset as L}from"smokey-fluid-cursor";import{jsx as R}from"react/jsx-runtime";var F=["densityDissipation","velocityDissipation","pressure","pressureIteration","curl","splatRadius","splatForce","shading","colorUpdateSpeed","paused","transparent","backColor","palette","colorIntensity","zIndex","pointerEvents","maxDpr","pauseOnHidden","respectReducedMotion"],k=e=>JSON.stringify([e==null?void 0:e.id,e==null?void 0:e.position,e==null?void 0:e.className,e==null?void 0:e.simResolution,e==null?void 0:e.dyeResolution,e==null?void 0:e.captureResolution]);function C(e,u){let l=o.useRef(null),d=o.useRef(e);d.current=e;let p=k(e);return o.useEffect(()=>{let a=c({...d.current,...u!=null&&u.current?{container:u.current}:{}});return l.current=a,()=>{a.dispose(),l.current=null}},[p,u]),o.useEffect(()=>{let a=l.current;if(!a||!e)return;let i={};for(let n of F)e[n]!==void 0&&(i[n]=e[n]);a.setConfig(i)}),l}var P=o.forwardRef(function({config:u,scoped:l=!1,className:d,style:p,children:a},i){let n=o.useRef(null),s=C(u,l?n:void 0);return o.useImperativeHandle(i,()=>({dispose:()=>{var r;return(r=s.current)==null?void 0:r.dispose()},pause:()=>{var r;return(r=s.current)==null?void 0:r.pause()},resume:()=>{var r;return(r=s.current)==null?void 0:r.resume()},isPaused:()=>{var r,t;return(t=(r=s.current)==null?void 0:r.isPaused())!=null?t:!0},setConfig:r=>{var t;return(t=s.current)==null?void 0:t.setConfig(r)},splat:(r,t,y)=>{var m;return(m=s.current)==null?void 0:m.splat(r,t,y)},get canvas(){var r,t;return(t=(r=s.current)==null?void 0:r.canvas)!=null?t:null}}),[s]),l?R("div",{ref:n,className:d,style:{position:"relative",overflow:"hidden",...p},children:a}):null});export{P as SmokeyFluidCursor,x as characterNames,L as getPreset,h as initFluid,E as paletteNames,H as presetNames,v as presets,C as useSmokeyFluidCursor};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-smokey-fluid-cursor",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "A customizable fluid cursor effect for React & Next.js Apps running on the web. Enhance user experience with smooth, interactive cursor animations. Perfect for modern web designs.",
5
5
  "keywords": [
6
6
  "react",
@@ -97,5 +97,8 @@
97
97
  "publishConfig": {
98
98
  "access": "public",
99
99
  "provenance": true
100
+ },
101
+ "dependencies": {
102
+ "smokey-fluid-cursor": "^2.1.0"
100
103
  }
101
104
  }