168 lines
6.7 KiB
TypeScript
168 lines
6.7 KiB
TypeScript
"use client"
|
||
|
||
import { useRef, useState, useEffect } from "react"
|
||
import Image from "next/image"
|
||
import Link from "next/link"
|
||
import { Card, CardContent } from "@/components/ui/card"
|
||
import { Button } from "@/components/ui/button"
|
||
import { ChevronLeft, ChevronRight, Info } from "lucide-react"
|
||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
|
||
import { robots } from "@/lib/robot-data"
|
||
|
||
export default function RobotsShowcase() {
|
||
const scrollContainerRef = useRef<HTMLDivElement>(null)
|
||
const [activeIndex, setActiveIndex] = useState(0)
|
||
|
||
// 创建一个循环数组,用于无限滚动
|
||
const displayRobots = [...robots]
|
||
|
||
const scroll = (direction: "left" | "right") => {
|
||
if (scrollContainerRef.current) {
|
||
const { current: container } = scrollContainerRef
|
||
const cardWidth = container.querySelector(".robot-card")?.clientWidth || 350
|
||
|
||
// 更新活跃索引
|
||
if (direction === "left") {
|
||
setActiveIndex((prev) => (prev === 0 ? robots.length - 1 : prev - 1))
|
||
} else {
|
||
setActiveIndex((prev) => (prev === robots.length - 1 ? 0 : prev + 1))
|
||
}
|
||
|
||
// 滚动到新的活跃卡片
|
||
const newScrollPosition = activeIndex * (cardWidth + 24) // 24 是 gap-6
|
||
container.scrollTo({
|
||
left: newScrollPosition,
|
||
behavior: "smooth",
|
||
})
|
||
}
|
||
}
|
||
|
||
// 使用 useEffect 监听活跃索引变化,滚动到对应位置
|
||
useEffect(() => {
|
||
if (scrollContainerRef.current) {
|
||
const cardWidth = scrollContainerRef.current.querySelector(".robot-card")?.clientWidth || 350
|
||
const newScrollPosition = activeIndex * (cardWidth + 24) // 24 是 gap-6
|
||
scrollContainerRef.current.scrollTo({
|
||
left: newScrollPosition,
|
||
behavior: "smooth",
|
||
})
|
||
}
|
||
}, [activeIndex])
|
||
|
||
return (
|
||
<section id="robots" className="py-20 relative overflow-hidden">
|
||
<div className="absolute right-0 top-0 bottom-0 red-section z-0" />
|
||
|
||
<div className="container mx-auto px-4 relative z-10">
|
||
<div className="flex flex-col md:flex-row gap-8 mb-12">
|
||
<div className="md:w-1/3">
|
||
<div className="red-accent pl-4">
|
||
<h2 className="text-3xl font-bold mb-2 uppercase">机器人</h2>
|
||
<p className="text-xs text-muted-foreground uppercase mb-4 font-mono">ROBOTS</p>
|
||
</div>
|
||
<div className="diagonal-line mb-8"></div>
|
||
<div className="content-overlay">
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
探索我们为 RoboMaster 竞赛设计的尖端机器人,每款机器人都针对赛场上的特定战术角色而设计。
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="relative">
|
||
<Button
|
||
variant="outline"
|
||
size="icon"
|
||
className="absolute left-0 top-1/2 -translate-y-1/2 z-10 bg-background/80 backdrop-blur-sm border-white/10 button-hover-effect"
|
||
onClick={() => scroll("left")}
|
||
>
|
||
<ChevronLeft className="h-6 w-6" />
|
||
</Button>
|
||
|
||
<div ref={scrollContainerRef} className="flex gap-6 overflow-x-auto scrollbar-hide py-4 px-2">
|
||
{displayRobots.map((robot, index) => (
|
||
<Card
|
||
key={robot.id}
|
||
className="min-w-[300px] md:min-w-[350px] border-white/10 bg-background/60 backdrop-blur-sm flex-shrink-0 card-hover-effect robot-card"
|
||
>
|
||
<CardContent className="p-0">
|
||
<div className="relative">
|
||
<Image
|
||
src={robot.image || "/placeholder.svg"}
|
||
alt={robot.displayName}
|
||
width={350}
|
||
height={200}
|
||
className="w-full h-48 object-cover"
|
||
/>
|
||
<div className="absolute top-0 right-0 bg-primary text-primary-foreground text-xs px-3 py-1">
|
||
{robot.category}
|
||
</div>
|
||
<div className="absolute bottom-0 left-0 p-2">
|
||
<p className="text-xs text-primary font-mono">{`0${index + 1}/0${robots.length}`}</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="p-4">
|
||
<div className="flex justify-between items-start mb-2">
|
||
<h3 className="text-xl font-bold">{robot.displayName}</h3>
|
||
<TooltipProvider>
|
||
<Tooltip>
|
||
<TooltipTrigger asChild>
|
||
<Button variant="ghost" size="icon" className="h-8 w-8 button-hover-effect">
|
||
<Info className="h-4 w-4" />
|
||
</Button>
|
||
</TooltipTrigger>
|
||
<TooltipContent className="max-w-[250px]">
|
||
<div className="space-y-2">
|
||
<p className="font-bold">技术参数:</p>
|
||
<ul className="text-xs space-y-1">
|
||
{robot.simpleSpecs.map((spec, specIndex) => (
|
||
<li key={specIndex}>{spec}</li>
|
||
))}
|
||
</ul>
|
||
</div>
|
||
</TooltipContent>
|
||
</Tooltip>
|
||
</TooltipProvider>
|
||
</div>
|
||
|
||
<p className="text-sm text-muted-foreground mb-4 leading-relaxed">{robot.shortDescription}</p>
|
||
|
||
<Link href={`/robots#${robot.id}`}>
|
||
<Button variant="outline" size="sm" className="w-full border-white/10 button-hover-effect">
|
||
查看详情
|
||
</Button>
|
||
</Link>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
))}
|
||
</div>
|
||
|
||
<Button
|
||
variant="outline"
|
||
size="icon"
|
||
className="absolute right-0 top-1/2 -translate-y-1/2 z-10 bg-background/80 backdrop-blur-sm border-white/10 button-hover-effect"
|
||
onClick={() => scroll("right")}
|
||
>
|
||
<ChevronRight className="h-6 w-6" />
|
||
</Button>
|
||
|
||
{/* 添加索引指示器 */}
|
||
<div className="flex justify-center mt-6 gap-2">
|
||
{robots.map((_, index) => (
|
||
<button
|
||
key={index}
|
||
className={`w-2 h-2 rounded-full transition-all ${
|
||
activeIndex === index ? "bg-primary w-4" : "bg-gray-500"
|
||
}`}
|
||
onClick={() => setActiveIndex(index)}
|
||
/>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
)
|
||
}
|