BlobCursor
blob-cursorTrails a soft animated blob behind pointer movement.
Usage
Basic usage
Wrap any content, and jelly water droplets will appear as you move the mouse over it; children is layered on top of the water droplets.
<div
className="relative h-64 overflow-hidden rounded-xl"
style={{ background: "oklch(0.16 0.02 265)" }}
>
<BlobCursor>
<div className="pointer-events-none flex h-full items-center justify-center text-sm font-medium text-white/70">
Move mouse →
</div>
</BlobCursor>
</div>Square liquid block
square can be combined with the larger gooeyStrength to obtain a liquid block that fuses like mercury.
<BlobCursor square gooeyStrength={20} />Long tail
Increase trailCount, reduce trailStiffness, and the tail will be longer and sticky.
<BlobCursor trailCount={5} trailStiffness={70} />Close gooey
When gooey={false}, each water droplet is independent of each other and no longer merges at the edges.
<BlobCursor gooey={false} />When to Use
Use it when the pointer itself should look like liquid mercury, with springy droplets that merge as they trail through a creative hero or landing page. Use TextCursor for a glyph trail inside a container, Antigravity for a full particle field, or Crosshair for target tracking.
Import
import { BlobCursor } from "@hulianui/ui"Props
| Name | Type | Default | Description |
|---|---|---|---|
| trailCount | number | 3 | Droplet count including the leader; higher values create a denser trail |
| sizes | number[] | [56, 116, 72] | Droplet diameters in pixels, selected by index and cycled when the array is shorter than trailCount |
| innerSizes | number[] | [18, 32, 22] | Inner-highlight diameters in pixels, cycled in the same way |
| fillColor | string | var(--color-primary) | Water drop body fill color, any CSS color can be passed |
| innerColor | string | var(--color-primary-foreground) | inner highlight color |
| square | boolean | false | Use square instead of circular droplets; combine with gooey for a liquid-block effect |
| gooey | boolean | true | Enable the SVG merge filter; when disabled, droplets remain separate |
| gooeyStrength | number | 16 | Gaussian-blur deviation for the merge filter; higher values merge across a wider area with softer edges |
| leadStiffness | number | 500 | Leader spring stiffness; higher values follow the pointer more tightly |
| trailStiffness | number | 120 | Trailing water drop spring stiffness (the smaller the trail, the longer the trail) |
| damping | number | 28 | Spring damping (the bigger it is, the less rebound it will be and the stickier it will be) |
| zIndex | number | 50 | Container stacking level; the droplet layer uses pointer-events:none |
| className | string | — | Class name forwarded to the relative root that fills its parent |
| style | CSSProperties | — | Inline styles forwarded to the root container |
Slots
| Slot | Type | Description |
|---|---|---|
| children | ReactNode | Content layered above the droplets with relative z-10 positioning |
Usage Guidelines
- This client component fills its parent. Give that parent an explicit height and
overflow-hidden. - The recommended array length for
sizes/innerSizesis ≥trailCount. If it is insufficient, it will be recycled according to the index. No error will be reported but the color matching/size will be repeated. - Disabling
gooeyseparates the droplets; square droplets no longer read as a merged liquid block. - The droplet layer uses
pointer-events:none, so it does not intercept underlying interaction. Put overlay content inchildren, which receivesz-10.
Related
BorderBeam · ShineBorder · GlareHover · Lens · AnimatedBeam · OrbitingCircles
Playground
<div className="relative h-64 overflow-hidden rounded-xl"
style={{ background: "oklch(0.16 0.02 265)" }}>
<BlobCursor
trailCount={3}
gooey={true}
gooeyStrength={16}
square={false}
/>
</div>