FluidCursor
Full Navier-Stokes fluid simulation that swirls color in response to cursor and touch movement, running on WebGL2 with a WebGL1 fallback and an optional WebGPU HDR path for wide-gamut, brighter-than-white glow
Preview
<script lang="ts">
import { FluidCursor } from "fancy-ui-svelte";
</script>
<div class="relative h-64 w-full overflow-hidden rounded-lg border">
<FluidCursor />
<div class="pointer-events-none absolute inset-0 flex items-center justify-center">
<p class="text-muted-foreground text-sm select-none">Move your cursor here</p>
</div>
</div>Installation
Usage
<script lang="ts">
import { FluidCursor } from 'fancy-ui-svelte';
</script>
<FluidCursor />Examples
Basic Usage
<script lang="ts">
import { FluidCursor } from "$lib/fancy-ui/fluid-cursor";
</script>
<div class="relative h-64 w-full overflow-hidden rounded-lg border">
<FluidCursor />
<div class="pointer-events-none absolute inset-0 flex items-center justify-center">
<p class="text-muted-foreground text-sm select-none">Move your cursor here</p>
</div>
</div>Custom Colors
Fixed teal fluid color.
<script lang="ts">
import { FluidCursor } from "$lib/fancy-ui/fluid-cursor";
</script>
<div class="relative h-64 w-full overflow-hidden rounded-lg border">
<FluidCursor fluidColor="#00ffcc" colorIntensity={0.4} />
<div class="pointer-events-none absolute inset-0 flex items-center justify-center">
<p class="text-muted-foreground text-sm select-none">Teal fluid color</p>
</div>
</div>HDR Mode
WebGPU engine with extended tone mapping — glows brighter than white on HDR displays. Requires a WebGPU browser (Chrome/Edge 129+, Safari 26+) plus an HDR screen for the full glow; otherwise falls back to wide-gamut WebGL (Chrome 104+, Safari 16.4+, Firefox 132+), then to standard rendering.
<script lang="ts">
import { FluidCursor } from "$lib/fancy-ui/fluid-cursor";
</script>
<div class="relative h-64 w-full overflow-hidden rounded-lg border bg-black">
<FluidCursor
hdr
hdrBoost={2}
fluidColors={["#a142ff", "#42cfff", "#ff2fd6"]}
colorIntensity={0.5}
splatOnMount
allowMultiple
/>
<div class="pointer-events-none absolute inset-0 flex items-center justify-center">
<p class="text-sm text-white/60 select-none">
HDR glow — brightest on an HDR display in a WebGPU browser
</p>
</div>
</div>Bitmap Dithering
Retro ordered-dither rendering — the fluid is snapped to a chunky pixel grid and each color channel is quantized with a 4x4 Bayer threshold, so dot density encodes brightness. Forces the WebGL renderer (hdr is ignored).
<script lang="ts">
import { FluidCursor } from "$lib/fancy-ui/fluid-cursor";
</script>
<div class="relative h-64 w-full overflow-hidden rounded-lg border bg-black">
<FluidCursor
dither
ditherPixelSize={3}
ditherLevels={4}
fluidColors={["#a142ff", "#42cfff", "#2fe6a8", "#ffb02f"]}
colorIntensity={0.5}
autoSplat
splatOnMount
allowMultiple
/>
<div class="pointer-events-none absolute inset-0 flex items-center justify-center">
<p class="text-sm text-white/60 select-none">Bitmap dithering — move your cursor here</p>
</div>
</div>Props
| Prop | Type | Default | Description |
|---|---|---|---|
simResolution | number | 128 | Simulation grid resolution |
dyeResolution | number | 1440 | Dye/color buffer resolution |
captureResolution | number | 512 | Capture buffer resolution |
densityDissipation | number | 3.5 | Rate at which density fades |
velocityDissipation | number | 2 | Rate at which velocity fades |
pressure | number | 0.1 | Pressure solver strength |
pressureIterations | number | 20 | Number of pressure solver iterations |
curl | number | 3 | Amount of curl/vorticity |
splatRadius | number | 0.2 | Radius of fluid splats |
splatForce | number | 6000 | Force of fluid splats |
shading | boolean | true | Enable fluid shading |
colorUpdateSpeed | number | 10 | Speed of color changes |
backColor | ColorRGB | string | { r: 0.5, g: 0, b: 0 } | Background color |
transparent | boolean | true | Transparent background |
fluidColor | string | - | Override all fluid with a single color |
fluidColors | string[] | - | Array of colors to cycle through for fluid splats |
colorIntensity | number | 0.15 | Intensity of color mixing |
autoSplat | boolean | false | Automatically create random splats |
autoSplatInterval | number | 1500 | Interval between auto-splats in ms |
interactive | boolean | true | React to mouse/touch input |
pauseWhenHidden | boolean | true | Pause simulation when tab is hidden |
splatOnMount | boolean | false | Create a splat on mount |
allowMultiple | boolean | false | Allow multiple instances simultaneously |
contained | boolean | true | Confine simulation to parent container |
hdr | boolean | false | Render via the WebGPU HDR engine — wide gamut + brighter-than-white glow on HDR displays. Needs Chrome/Edge 129+ or Safari 26+; falls back to wide-gamut WebGL (Chrome 104+, Safari 16.4+, Firefox 132+), then to standard rendering |
hdrBoost | number | 1.5 | Display exposure multiplier in HDR mode, clamped to [1, 4] |
dither | boolean | false | Experimental retro bitmap dithering — pixelates the fluid to a chunky grid and quantizes color with an ordered 4x4 Bayer threshold. Forces the WebGL renderer; hdr is ignored while set |
ditherPixelSize | number | 3 | Size of one dithered pixel in CSS pixels, minimum 1 |
ditherLevels | number | 4 | Color levels per channel in dither mode, clamped to [2, 16] |
Links
Related components
AnimatedBeam
Animated SVG beams connecting elements with smooth gradients
BorderBeam
Gradient beam that races around a container's border using a CSS offset-path animation, masked so only the border ring is painted, with configurable size, speed, anchor position, and gradient colors
Confetti
Confetti celebration effect powered by canvas-confetti with button trigger support