bayarea/components/BackToTop.tsx

45 lines
1.4 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import gsap from 'gsap';
const BackToTop: React.FC = () => {
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
const toggleVisibility = () => {
if (window.scrollY > 500) {
setIsVisible(true);
} else {
setIsVisible(false);
}
};
window.addEventListener('scroll', toggleVisibility);
return () => window.removeEventListener('scroll', toggleVisibility);
}, []);
const scrollToTop = () => {
gsap.to(window, { duration: 1.2, scrollTo: 0, ease: "power3.inOut" });
};
return (
<AnimatePresence>
{isVisible && (
<motion.button
initial={{ opacity: 0, scale: 0.8, y: 20 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.8, y: 20 }}
whileHover={{ scale: 1.1, backgroundColor: "#3b82f6" }}
whileTap={{ scale: 0.9 }}
onClick={scrollToTop}
className="fixed bottom-8 right-8 z-50 w-12 h-12 flex items-center justify-center rounded-full bg-black dark:bg-white text-white dark:text-black shadow-lg border border-gray-700 dark:border-gray-200 transition-colors"
aria-label="Back to top"
>
<span className="material-symbols-outlined text-2xl">arrow_upward</span>
</motion.button>
)}
</AnimatePresence>
);
};
export default BackToTop;