统一字体 响应式 调整

This commit is contained in:
小潘
2026-06-18 14:41:04 +08:00
parent 68e6e98234
commit 9309e3e76a
9 changed files with 688 additions and 377 deletions
@@ -0,0 +1,94 @@
import React, { useState, useEffect, useCallback } from 'react'
import CertificateCard, { certificates } from './CertificateCard'
export default function CertificateCarousel() {
const [active, setActive] = useState(2) // 从中间开始 (ISO 45001)
const [isMobile, setIsMobile] = useState(false)
// 检测是否为移动端
useEffect(() => {
const check = () => setIsMobile(window.innerWidth < 768)
check()
window.addEventListener('resize', check)
return () => window.removeEventListener('resize', check)
}, [])
const next = useCallback(() => {
setActive(prev => (prev + 1) % certificates.length)
}, [])
// 自动轮播
useEffect(() => {
const timer = setInterval(next, 3000)
return () => clearInterval(timer)
}, [next])
const goTo = (index) => setActive(index)
// 响应式参数
const containerHeight = isMobile ? 'h-[360px]' : 'h-[600px]'
const translateXBase = isMobile ? 140 : 260
const scaleCenter = 1.0
const scaleNear = isMobile ? 0.8 : 0.7
const scaleFar = isMobile ? 0.5 : 0.4
return (
<div className="relative max-w-4xl mx-auto">
{/* 证书展示区 */}
<div className={`relative ${containerHeight} flex items-center justify-center`}>
{certificates.map((cert, i) => {
let offset = i - active
// 循环环绕:取最短路径
if (offset > 2) offset = offset - certificates.length
if (offset < -2) offset = offset + certificates.length
const absOffset = Math.abs(offset)
let scale = scaleCenter
if (absOffset === 1) scale = scaleNear
if (absOffset >= 2) scale = scaleFar
let opacity = 1
if (absOffset === 1) opacity = 0.6
if (absOffset >= 2) opacity = 0
let translateX = offset * translateXBase
let zIndex = 10 - absOffset
return (
<div
key={cert.id}
className="absolute transition-all duration-500 ease-in-out cursor-pointer"
style={{
transform: `translateX(${translateX}px) scale(${scale})`,
opacity,
zIndex,
filter: absOffset >= 2 ? 'blur(2px)' : 'none',
}}
onClick={() => goTo(i)}
>
<CertificateCard certificate={cert} index={i} scale={isMobile ? 0.7 : 1} />
</div>
)
})}
</div>
{/* 底部指示点 */}
<div className="flex justify-center gap-2 mt-4">
{certificates.map((cert, i) => (
<button
key={cert.id}
onClick={() => goTo(i)}
className={`w-2 h-2 rounded-full transition-all duration-300 ${
i === active
? 'bg-[#004ec4] w-6'
: 'bg-[#004ec4]/30 hover:bg-[#004ec4]/50'
}`}
/>
))}
</div>
</div>
)
}