Splash Cursor
Cursor movement produces fluid splashes and ripples, approximating a fluid simulation with canvas 2D.
As the cursor sweeps across, colored ink blobs burst along its path, bleeding into each other with additive blending where they overlap and gradually dissipating into a trail, simulating the visual feedback of a fluid splash.
Loading preview…
npx shadcn@latest add https://webberui.com/r/splash-cursor.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
44
1
0.86
<SplashCursor />
Installation
npx shadcn@latest add https://webberui.com/r/splash-cursor.jsonOr, once registries are configured in components.json, install it as @webberui/splash-cursor.
Usage
Use it as a bounded interactive container, putting the foreground content in children; write the layout (centering and so on) directly in className:
import { SplashCursor } from "@/components/ui/splash-cursor";
<SplashCursor className="flex h-[340px] w-full items-center justify-center rounded-xl">
<p className="text-white">Move your cursor</p>
</SplashCursor>Props
| Prop | Type | Default | Description |
|---|---|---|---|
colors | string[] | five neon colors | Splash color cycle, additively blended where they overlap |
backgroundColor | string | "#0a0a0f" | Background color the fluid bleeds across and trails away over |
splatRadius | number | 44 | Base radius of a single fluid particle (px) |
intensity | number | 1 | Splash intensity; higher makes the ink blobs thicker |
trail | number | 0.86 | Trail persistence (0–1); higher makes the spread look more like ink wash |
interactive | boolean | true | Whether interaction is enabled (both mouse and touch) |
children | ReactNode | — | Foreground content stacked on top of the fluid |
Accessibility
- When the user has "reduce motion" enabled at the system level, only the static background color is laid down, with no animation or interaction started
- The canvas is marked
aria-hiddenandpointer-events-none, so this purely visual layer does not interfere with foreground interaction - Leaving (
onPointerLeave) and pressing again (onPointerDown) reset the path origin, so no straight line is dragged across between regions