WebberUI

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.json

Playground

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.json

Or, 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

PropTypeDefaultDescription
colorsstring[]five neon colorsSplash color cycle, additively blended where they overlap
backgroundColorstring"#0a0a0f"Background color the fluid bleeds across and trails away over
splatRadiusnumber44Base radius of a single fluid particle (px)
intensitynumber1Splash intensity; higher makes the ink blobs thicker
trailnumber0.86Trail persistence (01); higher makes the spread look more like ink wash
interactivebooleantrueWhether interaction is enabled (both mouse and touch)
childrenReactNodeForeground 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-hidden and pointer-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

On this page