Example
Move your cursor around
Installation
Copy and paste the source code into your project.
"use client";
import React, { useEffect, useRef } from "react";
type Props = {
speed?: number;
};
/**
* ElasticCursor component.
*
* An elastic ball that follows the cursor with a smooth transition effect.
*
* @param {number} [speed=0.1] - Smoothing factor for cursor movement speed (0.1 = smooth, 1 = instant)
*/
export const ElasticCursor = ({ speed = 0.1 }: Props) => {
const circleRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const circleElement = circleRef.current;
if (!circleElement) {
return;
}
const mouse = { x: 0, y: 0 };
const previousMouse = { x: 0, y: 0 };
const circle = { x: 0, y: 0 };
let currentScale = 0;
let currentAngle = 0;
const handleMouseMove = (e: MouseEvent) => {
mouse.x = e.clientX;
mouse.y = e.clientY;
};
window.addEventListener("mousemove", handleMouseMove);
const tick = () => {
if (!circleElement) return;
const circleRect = circleElement.getBoundingClientRect();
const circleRadius = circleRect.width / 2;
circle.x += (mouse.x - circle.x) * speed;
circle.y += (mouse.y - circle.y) * speed;
const translateTransform = `translate(${circle.x - circleRadius}px, ${circle.y - circleRadius}px)`;
const deltaMouseX = mouse.x - previousMouse.x;
const deltaMouseY = mouse.y - previousMouse.y;
previousMouse.x = mouse.x;
previousMouse.y = mouse.y;
const mouseVelocity = Math.min(
Math.sqrt(deltaMouseX ** 2 + deltaMouseY ** 2) * 4,
150
);
const scaleValue = (mouseVelocity / 150) * 0.5;
currentScale += (scaleValue - currentScale) * speed;
const scaleTransform = `scale(${1 + currentScale}, ${1 - currentScale})`;
const angle = (Math.atan2(deltaMouseY, deltaMouseX) * 180) / Math.PI;
if (mouseVelocity > 20) {
currentAngle = angle;
}
const rotateTransform = `rotate(${currentAngle}deg)`;
circleElement.style.transform = `${translateTransform} ${rotateTransform} ${scaleTransform}`;
window.requestAnimationFrame(tick);
};
window.requestAnimationFrame(tick);
return () => {
window.removeEventListener("mousemove", handleMouseMove);
};
}, [speed]);
return (
<div
ref={circleRef}
className="w-10 h-10 rounded-full fixed top-0 left-0 pointer-events-none border border-slate-500 z-50"
></div>
);
};
Update the import paths to match your project setup.
Props
Prop | Type | Default | Description |
---|---|---|---|
speed | number | 0.1 | Smoothing factor for cursor movement speed (0.1 = smooth, 1 = instant) |