Taste_Rider_Web / src /components /ScrollToTopButton.jsx
Harry9233's picture
Upload 20790 files
5c05829 verified
import React, { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { ArrowUpCircle } from 'lucide-react';
import { Button } from '@/components/ui/button';
const ScrollToTopButton = () => {
const [isVisible, setIsVisible] = useState(false);
const toggleVisibility = () => {
if (window.pageYOffset > 300) {
setIsVisible(true);
} else {
setIsVisible(false);
}
};
const scrollToTop = () => {
// Get the current scroll position
const startPosition = window.pageYOffset;
// Duration of the scroll animation in milliseconds
const duration = 800;
// Improved easing function for smoother animation
const easeOutCubic = t => 1 - Math.pow(1 - t, 3);
let startTime = null;
const animation = currentTime => {
if (startTime === null) startTime = currentTime;
const timeElapsed = currentTime - startTime;
const progress = Math.min(timeElapsed / duration, 1);
const easedProgress = easeOutCubic(progress);
window.scrollTo(0, startPosition * (1 - easedProgress));
if (timeElapsed < duration) {
requestAnimationFrame(animation);
}
};
requestAnimationFrame(animation);
};
useEffect(() => {
window.addEventListener('scroll', toggleVisibility);
return () => {
window.removeEventListener('scroll', toggleVisibility);
};
}, []);
return (
<AnimatePresence>
{isVisible && (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 20 }}
transition={{ duration: 0.5, ease: "easeInOut" }}
className="fixed bottom-20 left-6 z-50"
>
<motion.div
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
transition={{ type: "spring", stiffness: 400, damping: 17 }}
>
<Button
onClick={scrollToTop}
variant="outline"
size="icon"
className="bg-amber-600 hover:bg-amber-700 text-white border-amber-700 rounded-full shadow-lg w-12 h-12"
>
<ArrowUpCircle size={28} />
<span className="sr-only">Scroll to top</span>
</Button>
</motion.div>
</motion.div>
)}
</AnimatePresence>
);
};
export default ScrollToTopButton;