Logo

Kaif UI

logoKaif UI
Components

Custom Cursor

Custom Cursor

Enhance user engagement with a stylish, customizable cursor.

Custom Cursor

Customize your cursor

Color
<CustomCursor color="red" />
Glow
<CustomCursor glow="false" />
Size
<CustomCursor size={30} />
Duration
<CustomCursor duration={0.6} />

Installation

Install Dependencies

npm i framer-motion

Copy the source code

components/kaif-ui/CustomCursor.tsx
"use client";
 
// Visit https://kaif-ui.vercel.app/ for more components like this
 
import { useEffect, useState } from "react";
import { motion } from "framer-motion";
 
interface CustomCursorProps {
  color?: string; // Color of the cursor
  glow?: boolean; // Whether to show glow or not
  size?: number; // Size of the cursor
  duration?: number; // Duration of the cursor animation
}
 
const CustomCursor: React.FC<CustomCursorProps> = ({
  color = "#f53b57", // Default color
  glow = true, // Default glow
  size = 20, // Default size
  duration = 0.5, // Default duration
}) => {
  const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
  const [isVisible, setIsVisible] = useState(false);
 
  useEffect(() => {
    const handleMouseMove = (e: MouseEvent) => {
      requestAnimationFrame(() => {
        setMousePosition({
          x: e.clientX,
          y: e.clientY,
        });
        setIsVisible(true); // Show cursor when moving
      });
    };
 
    const handleMouseLeave = () => {
      setIsVisible(false); // Hide cursor when mouse leaves
    };
 
    window.addEventListener("mousemove", handleMouseMove);
    window.addEventListener("mouseleave", handleMouseLeave);
    return () => {
      window.removeEventListener("mousemove", handleMouseMove);
      window.removeEventListener("mouseleave", handleMouseLeave);
    };
  }, []);
 
  const cursorVariants = {
    default: {
      x: mousePosition.x - size / 2, // Adjust for cursor size
      y: mousePosition.y - size / 2,
      transition: {
        duration: duration,
      },
    },
  };
 
  return (
    isVisible && ( // Render only if visible
      <motion.div
        className={`absolute top-0 left-0 rounded-full pointer-events-none z-50 ${
          glow ? "glow" : ""
        }`}
        variants={cursorVariants}
        animate="default"
        style={{
          width: size,
          height: size,
          backgroundColor: color,
          boxShadow: glow ? `0 0 20px ${color}, 0 0 60px ${color}` : "none", // Apply glow if enabled
        }}
      />
    )
  );
};
 
export default CustomCursor;

add in layout file

layout.tsx
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import CustomCursor from "@/components/kaif-ui/CustomCursor";
const inter = Inter({ subsets: ["latin"] });
 
export const metadata: Metadata = {
  title: "Kaif UI",
  description: "Kaif UI",
};
 
export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <CustomCursor color="#0561e2" glow={true} size={20} duration={0.5} />
        {children}
      </body>
    </html>
  );
}

Tech Stack

Props

PropTypeDefault
color
string
"#f53b57"
glow
boolean
true
size
number
20
duration
number
0.5

On this page

Brought to you by Muhammad Kaif Nazeer