Files
carrotskin/src/components/ScrollToTop.tsx

66 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
export default function ScrollToTop() {
const [showScrollTop, setShowScrollTop] = useState(false);
useEffect(() => {
let ticking = false;
const handleScroll = () => {
if (!ticking) {
window.requestAnimationFrame(() => {
const currentScrollY = window.scrollY;
// 显示返回顶部按钮滚动超过300px
setShowScrollTop(currentScrollY > 300);
ticking = false;
});
ticking = true;
}
};
window.addEventListener('scroll', handleScroll, { passive: true });
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const scrollToTop = () => {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
};
return (
<AnimatePresence>
{showScrollTop && (
<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 }}
transition={{ duration: 0.2, ease: 'easeOut' }}
onClick={scrollToTop}
className="fixed bottom-6 right-6 w-12 h-12 bg-gradient-to-br from-orange-400/70 to-amber-300/70 hover:from-orange-600/70 hover:to-orange-700/70 text-white rounded-full shadow-lg hover:shadow-xl transition-all duration-200 flex items-center justify-center z-40 group"
whileHover={{ scale: 1.1, y: -2 }}
whileTap={{ scale: 0.9 }}
>
<svg
className="w-5 h-5 transition-transform duration-200 group-hover:-translate-y-0.5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M5 10l7-7m0 0l7 7m-7-7v18"
/>
</svg>
</motion.button>
)}
</AnimatePresence>
);
}