149 lines
4.7 KiB
JavaScript
149 lines
4.7 KiB
JavaScript
import React, { useState } from 'react';
|
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
|
|
const Navigation = ({ currentSection, sections, onSectionChange }) => {
|
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
|
|
const menuItems = [
|
|
{ name: '发现', engName: 'Discover', sectionIndex: 0 },
|
|
{ name: '产品', engName: 'Products', sectionIndex: 1 },
|
|
{ name: '团队', engName: 'Team', sectionIndex: 2 },
|
|
{ name: '案例', engName: 'Cases', sectionIndex: 3 },
|
|
{ name: '联系', engName: 'Contact', sectionIndex: 4 }
|
|
];
|
|
|
|
const handleItemClick = (sectionIndex) => {
|
|
onSectionChange(sectionIndex);
|
|
setIsMobileMenuOpen(false);
|
|
};
|
|
|
|
const toggleMobileMenu = () => {
|
|
setIsMobileMenuOpen(!isMobileMenuOpen);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<motion.nav
|
|
className="navigation-glass"
|
|
initial={{ y: -50, opacity: 0 }}
|
|
animate={{ y: 0, opacity: 1 }}
|
|
transition={{ duration: 0.8, delay: 0.2 }}
|
|
>
|
|
{/* Logo */}
|
|
<motion.div
|
|
className="logo-glass"
|
|
whileHover={{
|
|
scale: 1.02,
|
|
y: -1
|
|
}}
|
|
whileTap={{ scale: 0.98 }}
|
|
onClick={() => handleItemClick(0)}
|
|
>
|
|
<motion.div
|
|
className="logo-icon-glass"
|
|
whileHover={{
|
|
rotate: [0, -5, 5, 0],
|
|
scale: 1.1
|
|
}}
|
|
transition={{ duration: 0.5 }}
|
|
>
|
|
Q
|
|
</motion.div>
|
|
<motion.span
|
|
className="logo-text"
|
|
>
|
|
Quant Speed
|
|
</motion.span>
|
|
</motion.div>
|
|
|
|
{/* 桌面端菜单 */}
|
|
<div className="nav-menu-glass">
|
|
{menuItems.map((item, index) => (
|
|
<motion.div
|
|
key={index}
|
|
className={`nav-item-glass ${currentSection === item.sectionIndex ? 'active' : ''}`}
|
|
whileHover={{
|
|
scale: 1.05,
|
|
y: -2
|
|
}}
|
|
whileTap={{ scale: 0.95 }}
|
|
transition={{ duration: 0.2 }}
|
|
onClick={() => handleItemClick(item.sectionIndex)}
|
|
>
|
|
<span className="nav-item-main">{item.name}</span>
|
|
<span className="nav-item-sub">{item.engName}</span>
|
|
{currentSection === item.sectionIndex && (
|
|
<motion.div
|
|
className="nav-item-indicator"
|
|
layoutId="activeIndicator"
|
|
initial={false}
|
|
transition={{ type: "spring", stiffness: 300, damping: 30 }}
|
|
/>
|
|
)}
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
|
|
{/* 移动端汉堡菜单按钮 */}
|
|
<motion.div
|
|
className={`hamburger-glass ${isMobileMenuOpen ? 'active' : ''}`}
|
|
whileHover={{ scale: 1.1 }}
|
|
whileTap={{ scale: 0.9 }}
|
|
onClick={toggleMobileMenu}
|
|
>
|
|
<motion.div
|
|
className="hamburger-line"
|
|
animate={isMobileMenuOpen ? { rotate: 45, y: 6 } : { rotate: 0, y: 0 }}
|
|
/>
|
|
<motion.div
|
|
className="hamburger-line"
|
|
animate={isMobileMenuOpen ? { opacity: 0 } : { opacity: 1 }}
|
|
/>
|
|
<motion.div
|
|
className="hamburger-line"
|
|
animate={isMobileMenuOpen ? { rotate: -45, y: -6 } : { rotate: 0, y: 0 }}
|
|
/>
|
|
</motion.div>
|
|
</motion.nav>
|
|
|
|
{/* 移动端菜单 */}
|
|
<AnimatePresence>
|
|
{isMobileMenuOpen && (
|
|
<motion.div
|
|
className="mobile-menu-glass"
|
|
initial={{ opacity: 0, y: -20 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
exit={{ opacity: 0, y: -20 }}
|
|
transition={{ duration: 0.3 }}
|
|
>
|
|
<motion.div
|
|
className="mobile-menu-content"
|
|
initial={{ scale: 0.95 }}
|
|
animate={{ scale: 1 }}
|
|
exit={{ scale: 0.95 }}
|
|
>
|
|
{menuItems.map((item, index) => (
|
|
<motion.div
|
|
key={index}
|
|
className={`mobile-nav-item ${currentSection === item.sectionIndex ? 'active' : ''}`}
|
|
whileHover={{ x: 10 }}
|
|
whileTap={{ scale: 0.95 }}
|
|
onClick={() => handleItemClick(item.sectionIndex)}
|
|
initial={{ opacity: 0, x: -20 }}
|
|
animate={{ opacity: 1, x: 0 }}
|
|
transition={{ delay: index * 0.1 }}
|
|
>
|
|
<span className="mobile-nav-main">{item.name}</span>
|
|
<span className="mobile-nav-sub">{item.engName}</span>
|
|
</motion.div>
|
|
))}
|
|
</motion.div>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Navigation;
|