import React, { useEffect, useRef } from "react"; import { motion, useAnimation } from "framer-motion"; import clsx from "clsx"; const HoverableSkillList = ({ title, items, color = "red", hoveredItem, setHoveredItem, getKey, isVisible, }) => { const borderClass = `text-${color}-400`; const controls = useAnimation(); const skillLevelRefs = useRef([]); useEffect(() => { if (isVisible) { controls.start((item) => { const circumference = 2 * Math.PI * 40; // Adjusted radius const skillLevel = parseInt( item.skill.split(": ")[1].split("/")[0], 10 ); return { strokeDashoffset: circumference - (skillLevel / 5) * circumference, transition: { duration: 1, ease: "easeInOut" }, }; }); } else { controls.set({ strokeDashoffset: 2 * Math.PI * 40 }); } }, [isVisible, controls]); return ( <div className="relative mx-auto text-center"> <h2 className={clsx("text-2xl font-sans font-semibold mb-8", borderClass)} > {title} </h2> <div className="flex gap-3 flex-wrap justify-center"> {items.map((item, index) => { const circumference = 2 * Math.PI * 40; // Adjusted for better scaling return ( <div key={getKey(item, index)} className="relative flex flex-col items-center mb-2 group" onMouseEnter={() => setHoveredItem(index)} onMouseLeave={() => setHoveredItem(null)} > <div className="relative w-[60px] h-[60px] sm:w-[85px] sm:h-[85px]"> {" "} {/* Adjusted size for mobile */} <svg className="absolute top-0 left-0 w-full h-full transform -rotate-90" viewBox="0 0 100 100" > {/* Background Circle */} <circle cx="50" cy="50" r="40" fill="transparent" stroke="gray" strokeWidth="6" strokeDasharray={circumference} /> {/* Animated Progress Circle */} <motion.circle cx="50" cy="50" r="40" fill="transparent" stroke="currentColor" strokeWidth="6" strokeDasharray={circumference} initial={{ strokeDashoffset: circumference }} animate={controls} custom={item} className={clsx(borderClass, "transition-all duration-300")} /> </svg> {/* Icon */} <motion.img alt={item.name} src={item.logo} className={clsx( "p-2 w-[60px] h-[60px] sm:w-[70px] sm:h-[70px] rounded-full transition-all duration-100 absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2", hoveredItem === index && "shadow-2xl shadow-white" )} /> </div> <p className="mt-2 text-base text-white">{item.name}</p> {hoveredItem === index && ( <div className="absolute bottom-full mb-2 bg-black text-white text-sm font-bold rounded-md px-8 py-3 shadow-lg"> {item.skill} </div> )} </div> ); })} </div> </div> ); }; export default HoverableSkillList;