2025-12-03 03:24:29 +01:00
|
|
|
import { useState, useEffect } from 'react';
|
2026-10-24 21:19:22 +02:00
|
|
|
import { profile } from '../data/profile';
|
2025-12-03 03:24:29 +01:00
|
|
|
|
2026-10-24 21:19:22 +02:00
|
|
|
const names = profile.handles;
|
2025-12-03 03:24:29 +01:00
|
|
|
|
|
|
|
|
export default function AnimatedName() {
|
|
|
|
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
|
|
|
const [isAnimating, setIsAnimating] = useState(false);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2026-10-24 21:19:22 +02:00
|
|
|
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
|
|
|
|
|
|
|
|
|
let timeout;
|
2025-12-03 03:24:29 +01:00
|
|
|
const interval = setInterval(() => {
|
|
|
|
|
setIsAnimating(true);
|
2026-10-24 21:19:22 +02:00
|
|
|
timeout = setTimeout(() => {
|
2025-12-03 03:24:29 +01:00
|
|
|
setCurrentIndex((prevIndex) => (prevIndex + 1) % names.length);
|
|
|
|
|
setIsAnimating(false);
|
2026-10-24 21:19:22 +02:00
|
|
|
}, 350);
|
|
|
|
|
}, 3000);
|
2025-12-03 03:24:29 +01:00
|
|
|
|
2026-10-24 21:19:22 +02:00
|
|
|
return () => {
|
|
|
|
|
clearInterval(interval);
|
|
|
|
|
clearTimeout(timeout);
|
|
|
|
|
};
|
2025-12-03 03:24:29 +01:00
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
return (
|
2026-10-24 21:19:22 +02:00
|
|
|
<span className="animated-name" aria-label={names[0]}>
|
|
|
|
|
<span aria-hidden="true" className={isAnimating ? 'is-leaving' : 'is-entering'}>
|
2025-12-03 03:24:29 +01:00
|
|
|
{names[currentIndex]}
|
|
|
|
|
</span>
|
|
|
|
|
</span>
|
|
|
|
|
);
|
|
|
|
|
}
|