'use client'; import { useRef, useEffect, useState } from 'react'; import Image from 'next/image'; import { motion, Variants } from 'framer-motion'; import { useLanguage } from '@/contexts/LanguageContext'; import { useTheme } from '@/contexts/ThemeContext'; import ConsenSysLogo from './ConsenSysLogo'; const itemVariants: Variants = { hidden: { y: '3rem', opacity: 0 }, visible: (i: number) => ({ y: 0, opacity: 1, transition: { duration: 0.7, ease: 'easeOut' as const, delay: i * 0.1 } }) }; export default function TrustedBySection() { const { t } = useLanguage(); const { theme } = useTheme(); const isDark = theme === 'dark'; const scrollRef = useRef(null); const rafRef = useRef(0); const isPaused = useRef(false); const [isMounted, setIsMounted] = useState(false); // 确保组件挂载后才启动滚动 useEffect(() => { setIsMounted(true); }, []); useEffect(() => { if (!isMounted) return; const el = scrollRef.current; if (!el) return; const speed = 1.2; let lastTime = performance.now(); const tick = (currentTime: number) => { const deltaTime = currentTime - lastTime; lastTime = currentTime; if (!isPaused.current && el) { el.scrollLeft += speed * (deltaTime / 16); // 标准化到60fps if (el.scrollLeft >= el.scrollWidth / 2) { el.scrollLeft = 0; } } rafRef.current = requestAnimationFrame(tick); }; // 延迟启动,确保 DOM 完全渲染 const startTimer = setTimeout(() => { rafRef.current = requestAnimationFrame(tick); }, 100); return () => { clearTimeout(startTimer); if (rafRef.current) { cancelAnimationFrame(rafRef.current); } }; }, [isMounted]); const logoClass = isDark ? 'brightness-0 invert opacity-50 group-hover:opacity-100' : 'brightness-0 opacity-50 group-hover:opacity-100'; const partners = [ { name: 'BlackRock', src: '/nav-ireland0.svg', width: 200, height: 40 }, { name: 'Coinbase', src: '/coinbase-10.svg', width: 180, height: 40 }, { name: 'Wintermute', src: '/wintermute0.svg', width: 247, height: 40 }, { name: 'Circle', src: '/group0.svg', width: 156, height: 40 }, { name: 'ConsenSys', src: '', width: 220, height: 50 }, ]; const renderLogo = (partner: typeof partners[number], key: string) => (
{partner.name === 'ConsenSys' ? (
) : ( {partner.name} )}
); return (
{t('trusted.title')}
{/* ── 移动端:自动滚动 + 手动滑动 ── */}
{ isPaused.current = true; }} onTouchEnd={() => { isPaused.current = false; }} onTouchCancel={() => { isPaused.current = false; }} >
{[...partners, ...partners].map((partner, i) => (
{renderLogo(partner, `m-${partner.name}-${i}`)}
))}
{/* ── 桌面端:单行不换行 ── */}
{partners.map((partner, index) => ( {partner.name === 'ConsenSys' ? (
) : ( {partner.name} )}
))}
); }