Todos os componentes

Mouse Trail

Mouse Trail é um componente para React e Tailwind CSS, da biblioteca Bund UI, com licença MIT. Copia e cola no teu projeto.

Bund UI MIT other

O que é

Mouse Trail é um componente para React e Tailwind CSS, da biblioteca Bund UI, com licença MIT. Copia e cola no teu projeto.

Como usar

Abre o componente no catálogo, carrega em copiar, e cola no teu projeto. O prompt copiado leva o código e as regras para o teu agente o reproduzir sem alterar nada.

Abrir no catálogo

Cinco cópias grátis por mês. Sem cartão.

Precisa de

npm i motion

Licença

Este componente vem de Bund UI e é redistribuído sob a licença MIT, que permite uso comercial. O aviso de copyright viaja com o código.

Mouse Trail

examples/motion/animations/mouse-trail/01/mouse-trail.tsx
"use client";

import { useEffect, useRef, useState } from "react";
import { motion, AnimatePresence } from "motion/react";

interface Dot {
  id: number;
  x: number;
  y: number;
}

interface MouseTrailProps {
  dotColor?: string;
  dotSize?: number;
  spacing?: number;
  trailLength?: number;
  fadeDuration?: number;
}

export const MouseTrail = ({
  dotColor = "#a855f7",
  dotSize = 8,
  spacing = 20,
  trailLength = 20,
  fadeDuration = 1000
}: MouseTrailProps) => {
  const [dots, setDots] = useState<Dot[]>([]);
  const lastPositionRef = useRef({ x: 0, y: 0 });
  const dotIdRef = useRef(0);

  useEffect(() => {
    const handleMouseMove = (e: MouseEvent) => {
      const { clientX: x, clientY: y } = e;
      const lastPos = lastPositionRef.current;

      // Calculate distance from last dot
      const distance = Math.sqrt(Math.pow(x - lastPos.x, 2) + Math.pow(y - lastPos.y, 2));

      // Only add dot if we've moved far enough
      if (distance >= spacing) {
        const newDot: Dot = {
          id: dotIdRef.current++,
          x,
          y
        };

        setDots((prevDots) => {
          const updatedDots = [...prevDots, newDot];
          // Keep only the most recent dots based on trail length
          return updatedDots.slice(-trailLength);
        });

        lastPositionRef.current = { x, y };

        // Remove dot after fade duration
        setTimeout(() => {
          setDots((prevDots) => prevDots.filter((d) => d.id !== newDot.id));
        }, fadeDuration);
      }
    };

    window.addEventListener("mousemove", handleMouseMove);

    return () => {
      window.removeEventListener("mousemove", handleMouseMove);
    };
  }, [spacing, trailLength, fadeDuration]);

  return (
    <div className="pointer-events-none fixed inset-0 z-50">
      <AnimatePresence>
        {dots.map((dot) => (
          <motion.div
            key={dot.id}
            className="absolute rounded-full"
            initial={{
              left: dot.x - dotSize / 2,
              top: dot.y - dotSize / 2,
              opacity: 1,
              scale: 0
            }}
            animate={{
              opacity: 1,
              scale: 1
            }}
            exit={{
              opacity: 0,
              scale: 0.5
            }}
            transition={{
              duration: fadeDuration / 1000,
              ease: "easeOut"
            }}
            style={{
              width: dotSize,
              height: dotSize,
              backgroundColor: dotColor
            }}
          />
        ))}
      </AnimatePresence>
    </div>
  );
};
examples/motion/animations/mouse-trail/01/page.tsx
import { MouseTrail } from "./mouse-trail";

export default function Page() {
  return (
    <MouseTrail
      dotColor="var(--color-primary)"
      dotSize={5}
      spacing={10}
      trailLength={20}
      fadeDuration={500}
    />
  );
}

Componentes parecidos