Chaque lettre reagit au curseur avec un changement de font-weight et un decalage magnetique.
"use client";
import { useRef, useEffect } from "react";
export default function MagneticText({ text = "Magnetic" }) {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
const letters = containerRef.current?.querySelectorAll("span");
letters?.forEach((span) => {
const rect = span.getBoundingClientRect();
const cx = rect.left + rect.width / 2;
const cy = rect.top + rect.height / 2;
const dist = Math.sqrt((e.clientX - cx) ** 2 + (e.clientY - cy) ** 2);
const maxDist = 200;
const t = Math.max(0, 1 - dist / maxDist);
span.style.fontWeight = String(100 + Math.round(t * 800));
const r = Math.round(255 + t * (225 - 255));
const g = Math.round(255 + t * (255 - 255));
const b = Math.round(255 + t * (108 - 255));
span.style.color = `rgb(${r},${g},${b})`;
});
};
window.addEventListener("mousemove", handleMouseMove);
return () => window.removeEventListener("mousemove", handleMouseMove);
}, []);
return (
<div ref={containerRef}>
{text.split("").map((char, i) => <span key={i}>{char}</span>)}
</div>
);
}Necessite une font variable (ex: Inter) pour le font-weight dynamique. La distance max (200px) controle la zone d'influence. La couleur interpole de blanc vers #E1FF6C. Ajoutez transition: font-weight 0.1s sur les spans.