'use client'; import { useState, useEffect, useRef } from 'react'; import Image from 'next/image'; import { Card, CardBody } from '@heroui/react'; import { SearchCheck, Landmark, BarChart2, ArrowRight, LucideIcon } from 'lucide-react'; import { useLanguage, TranslationKey } from '@/contexts/LanguageContext'; const features: { Icon: LucideIcon; titleKey: TranslationKey; descKey: TranslationKey | null; position: string; special?: boolean }[] = [ { Icon: SearchCheck, titleKey: 'security.audited.title', descKey: 'security.audited.desc', position: 'top-left' }, { Icon: Landmark, titleKey: 'security.segregated.title', descKey: 'security.segregated.desc', position: 'top-right' }, { Icon: BarChart2, titleKey: 'security.transparency.title', descKey: 'security.transparency.desc', position: 'bottom-left' }, { Icon: ArrowRight, titleKey: 'security.partners.title', descKey: null, position: 'bottom-right', special: true } ]; export default function SecuritySection() { const { t } = useLanguage(); const [animate, setAnimate] = useState(false); const sectionRef = useRef(null); const [cardHovers, setCardHovers] = useState<{[key: number]: {x: number, y: number} | null}>({}); 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 handleCardMouseMove = (e: React.MouseEvent, index: number) => { const rect = e.currentTarget.getBoundingClientRect(); const x = ((e.clientX - rect.left) / rect.width) * 100; const y = ((e.clientY - rect.top) / rect.height) * 100; setCardHovers(prev => ({...prev, [index]: {x, y}})); }; const handleCardMouseLeave = (index: number) => { setCardHovers(prev => ({...prev, [index]: null})); }; const getBorderGradients = (index: number) => { const hover = cardHovers[index]; if (!hover) return null; const { x, y } = hover; const spreadRange = 20; const horizontalGradient = `linear-gradient(to right, transparent 0%, rgba(136,136,136,0.3) ${Math.max(0, x - spreadRange)}%, rgba(136,136,136,1) ${x}%, rgba(136,136,136,0.3) ${Math.min(100, x + spreadRange)}%, transparent 100%)`; const verticalGradient = `linear-gradient(to bottom, transparent 0%, rgba(136,136,136,0.3) ${Math.max(0, y - spreadRange)}%, rgba(136,136,136,1) ${y}%, rgba(136,136,136,0.3) ${Math.min(100, y + spreadRange)}%, transparent 100%)`; // 根据鼠标位置判断显示哪些边,使用 opacity 平滑过渡 const topOpacity = y < 50 ? 1 : 0; const leftOpacity = x < 50 ? 1 : 0; const rightOpacity = x >= 50 ? 1 : 0; const bottomOpacity = y >= 50 ? 1 : 0; return { horizontalGradient, verticalGradient, topOpacity, leftOpacity, rightOpacity, bottomOpacity }; }; return (
{/* 标题区域 */}

{t('security.title')}

{t('security.subtitle')}

{/* 卡片区域:移动端单列,桌面端2x2 */}
{features.map((feature, index) => { const borders = getBorderGradients(index); return (
{/* 顶部边框光效 */}
{/* 右边边框光效 */}
{/* 底部边框光效 */}
{/* 左边边框光效 */}
) => handleCardMouseMove(e, index)} onMouseLeave={() => handleCardMouseLeave(index)} > {feature.special ? (

{t(feature.titleKey)}

) : (

{t(feature.titleKey)}

{feature.descKey && t(feature.descKey)}

)}
); })}
Logo
); }