'use client'; import { useState, useEffect, useRef } from 'react'; import Image from 'next/image'; import { Card, CardBody, Chip } from '@heroui/react'; import { useLanguage } from '@/contexts/LanguageContext'; import { useTheme } from '@/contexts/ThemeContext'; // 数字增长动画Hook function useCountUp(end: number, duration: number = 1500, startRangePercent: number = 0.75) { const [mounted, setMounted] = useState(false); const [count, setCount] = useState(end); const elementRef = useRef(null); const startValueRef = useRef(end); const timerRef = useRef(null); useEffect(() => { setMounted(true); startValueRef.current = Math.floor(end * (startRangePercent + Math.random() * 0.15)); setCount(startValueRef.current); }, [end, startRangePercent]); useEffect(() => { if (!mounted) return; const observer = new IntersectionObserver( (entries) => { if (entries[0].isIntersecting) { // 清除之前可能存在的 timer if (timerRef.current) { clearInterval(timerRef.current); } const start = startValueRef.current; const startTime = Date.now(); const timer = setInterval(() => { const elapsed = Date.now() - startTime; const progress = Math.min(elapsed / duration, 1); const easeOutCubic = 1 - Math.pow(1 - progress, 3); const currentCount = Math.floor(start + (end - start) * easeOutCubic); setCount(currentCount); if (progress === 1) { setCount(end); clearInterval(timer); timerRef.current = null; } }, 16); timerRef.current = timer; } else { if (timerRef.current) { clearInterval(timerRef.current); timerRef.current = null; } setCount(startValueRef.current); } }, { threshold: 0.1 } ); if (elementRef.current) { observer.observe(elementRef.current); } return () => { if (timerRef.current) { clearInterval(timerRef.current); } observer.disconnect(); }; }, [end, duration, mounted]); return { count, elementRef }; } export default function HowItWorksSection() { const { t } = useLanguage(); const { theme } = useTheme(); const [animate, setAnimate] = useState(false); const [activeStep, setActiveStep] = useState(1); const sectionRef = useRef(null); const investAmount = useCountUp(100000, 1500, 0.85); const earnAmount = useCountUp(5150, 1500, 0.85); useEffect(() => { const currentRef = sectionRef.current; if (!currentRef) return; const observer = new IntersectionObserver( (entries) => { if (entries[0].isIntersecting) { setAnimate(true); observer.disconnect(); } }, { threshold: 0.3 } ); observer.observe(currentRef); return () => observer.disconnect(); }, []); const isDark = theme === 'dark'; const steps = [ { number: 1, title: t('how.step1.title'), description: t('how.step1.desc'), hasLine: true }, { number: 2, title: t('how.step2.title'), description: t('how.step2.desc'), hasLine: true }, { number: 3, title: t('how.step3.title'), description: t('how.step3.desc'), hasLine: false } ]; return (

{t('how.title')}

{steps.map((step, index) => { const isActive = activeStep === step.number; return (
setActiveStep(step.number)} className={`flex flex-row gap-6 items-start justify-start flex-shrink-0 relative cursor-pointer transition-all duration-300 ease-out hover:opacity-80 ${ animate ? 'translate-x-0 opacity-100' : '-translate-x-12 opacity-0' }`} style={{ transitionDelay: `${index * 150}ms` }} >
{isActive ? (
{step.number}
) : (
{step.number}
)} {step.hasLine && (
)}

{step.title}

{step.description}

); })}
<> USDC
WUSD
Portfolio
{t('how.simulator.title')}
+5.2% APY
{t('how.simulator.invest')} ${investAmount.count.toLocaleString()}
{t('how.simulator.earn')}
Earn +${earnAmount.count.toLocaleString()}
Fund Market Connect Wallet
O
APY 30.2%
APY 15.2%
Defi +5.2% APY
{/* Cards Grid Container */}
{/* Container 1 */}
O
+10% APY
Boost
{/* Container 2 */}
O
+10% APY
Boost
{/* Container 3 */}
O
+10% APY
Boost
{/* Container 4 - with SWAP button */}
O
Get USDC
SWAP
{/* Container 5 - with LP button */}
O
10% APY
LP
); }