Skip to content

Liquid Blob Cursor Follow

A soft blurred blob that trails the cursor with spring-smoothed lag.

Freeglassplayful
Category
Backgrounds
Added
2026-08-22
Deps
1
Updated
2026-09-01
Preview
Move your cursor

Props

90
18
Requires framer-motion
"use client";

import { useRef } from "react";
import { motion, useMotionValue, useSpring } from "framer-motion";

export function LiquidBlobCursor({
  size = 90,
  softness = 18,
}: {
  size?: number;
  softness?: number;
}) {
  const areaRef = useRef<HTMLDivElement>(null);
  const x = useMotionValue(0);
  const y = useMotionValue(0);
  const springX = useSpring(x, { stiffness: 120, damping: 16, mass: 0.6 });
  const springY = useSpring(y, { stiffness: 120, damping: 16, mass: 0.6 });

  function handleMove(e: React.MouseEvent<HTMLDivElement>) {
    const rect = areaRef.current?.getBoundingClientRect();
    if (!rect) return;
    x.set(e.clientX - rect.left);
    y.set(e.clientY - rect.top);
  }

  return (
    <div
      ref={areaRef}
      onMouseMove={handleMove}
      className="relative h-64 w-full overflow-hidden rounded-2xl bg-neutral-100"
    >
      <motion.div
        className="pointer-events-none absolute rounded-full bg-red-500"
        style={{
          width: size,
          height: size,
          x: springX,
          y: springY,
          translateX: "-50%",
          translateY: "-50%",
          filter: `blur(${softness}px)`,
          opacity: 0.75,
        }}
      />
    </div>
  );
}
Notes

About this background

This tracks the cursor with a spring rather than locking onto it 1:1, which is the entire trick: raw coordinates go straight into a Framer Motion useMotionValue via .set() inside the mousemove handler, never React state, since that would re-render on every pixel of movement — and each raw value is wrapped in its own useSpring (stiffness ~120, damping ~16, mass ~0.6) before it reaches the blob's x/y style, which is what turns a rigid cursor-lock into a soft, lagging trail. It's a different effect from this library's dot-trail cursor: one blurred shape following with lag, not a chain of discrete points marking the path already travelled — reach for this one for a single ambient glow behind hero content, the dot trail instead when the path itself should stay visible. Tracking is scoped to the container's own bounding rect via a ref, so the blob only follows the mouse while it's over that specific element; there's no window-level listener, so a full-viewport version needs the handler moved to window with viewport-relative coordinates. The heavy blur is core to the look, not a finishing touch — drop softness too low and it stops reading as liquid and starts reading as a plain circle chasing the pointer.

Curator’s note

Raw position lives in a useMotionValue updated directly in the mousemove handler, never React state — routing high-frequency pointer coordinates through setState would re-render the whole tree on every pixel of mouse movement. The spring wrapping is what turns a rigid cursor-lock into a liquid trailing follow.

Related

Pairs well with

Matched on shared tags and category — the entries most likely to be used alongside this one.

Tilt Card

components

A 3D card that tilts toward the cursor with spring physics.

card3dcursor
Featured

Magnetic Button

components

A button whose label leans toward the cursor with a springy pull.

buttoncursorspring
Featured
New

A contextual chip that trails the pointer and names whatever it is over.

cursorlabelspring