simba-index/components/hero-section.tsx

184 lines
5.5 KiB
TypeScript

"use client"
import { useEffect, useRef } from "react"
import Image from "next/image"
import Link from "next/link"
import { Button } from "@/components/ui/button"
import { ChevronDown, History } from "lucide-react"
export default function HeroSection() {
const canvasRef = useRef<HTMLCanvasElement>(null)
useEffect(() => {
const canvas = canvasRef.current
if (!canvas) return
const ctx = canvas.getContext("2d")
if (!ctx) return
canvas.width = window.innerWidth
canvas.height = window.innerHeight
const particles: {
x: number
y: number
size: number
speedX: number
speedY: number
color: string
}[] = []
const createParticles = () => {
const particleCount = Math.floor(window.innerWidth / 20)
for (let i = 0; i < particleCount; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size: Math.random() * 1.5 + 0.1,
speedX: Math.random() * 0.3 - 0.15,
speedY: Math.random() * 0.3 - 0.15,
color: `rgba(255, 255, 255, ${Math.random() * 0.2})`,
})
}
}
const connectParticles = () => {
for (let i = 0; i < particles.length; i++) {
for (let j = i; j < particles.length; j++) {
const dx = particles[i].x - particles[j].x
const dy = particles[i].y - particles[j].y
const distance = Math.sqrt(dx * dx + dy * dy)
if (distance < 100) {
ctx.beginPath()
ctx.strokeStyle = `rgba(255, 255, 255, ${0.05 - distance / 2000})`
ctx.lineWidth = 0.2
ctx.moveTo(particles[i].x, particles[i].y)
ctx.lineTo(particles[j].x, particles[j].y)
ctx.stroke()
}
}
}
}
const animate = () => {
requestAnimationFrame(animate)
ctx.clearRect(0, 0, canvas.width, canvas.height)
for (let i = 0; i < particles.length; i++) {
const p = particles[i]
ctx.fillStyle = p.color
ctx.beginPath()
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2)
ctx.fill()
p.x += p.speedX
p.y += p.speedY
if (p.x > canvas.width) p.x = 0
else if (p.x < 0) p.x = canvas.width
if (p.y > canvas.height) p.y = 0
else if (p.y < 0) p.y = canvas.height
}
connectParticles()
}
const handleResize = () => {
canvas.width = window.innerWidth
canvas.height = window.innerHeight
particles.length = 0
createParticles()
}
createParticles()
animate()
window.addEventListener("resize", handleResize)
return () => {
window.removeEventListener("resize", handleResize)
}
}, [])
const scrollToAbout = () => {
const aboutSection = document.getElementById("about")
if (aboutSection) {
aboutSection.scrollIntoView({ behavior: "smooth" })
}
}
return (
<section id="home" className="relative min-h-screen flex items-center justify-center overflow-hidden pt-16">
<canvas ref={canvasRef} className="absolute inset-0 z-0" />
<div className="absolute inset-0 grid-pattern opacity-20" />
<div className="absolute top-0 right-0 bottom-0 red-section z-0" />
<div className="container mx-auto px-4 z-20 flex flex-col items-center text-center relative">
<div className="mb-8 relative">
<div className="absolute inset-0 bg-primary/20 blur-3xl rounded-full" />
<Image src="/logo.svg" alt="Simba Robotics Logo" width={200} height={200} className="relative z-10" />
</div>
<div className="relative">
<h1 className="text-4xl md:text-6xl lg:text-7xl font-bold mb-4 uppercase font-mono">
SIMBA
<br />
ROBOTICS
</h1>
<div className="w-20 h-1 bg-primary mx-auto mb-6"></div>
</div>
<p className="text-xl md:text-2xl text-muted-foreground max-w-2xl mb-8 relative">
<span className="text-xs text-primary block mb-2 font-mono">// ROBOMASTER COMPETITION TEAM</span>
RoboMaster
</p>
<div className="flex flex-col sm:flex-row gap-4 mb-16">
<Button
size="lg"
className="px-8 bg-primary text-primary-foreground hover:bg-primary/90 button-hover-effect"
onClick={() => {
const robotsSection = document.getElementById("robots")
if (robotsSection) {
robotsSection.scrollIntoView({ behavior: "smooth" })
}
}}
>
</Button>
<Button
size="lg"
variant="outline"
className="px-8 border-white/20 hover:bg-white/5 button-hover-effect"
onClick={() => {
const contactSection = document.getElementById("contact")
if (contactSection) {
contactSection.scrollIntoView({ behavior: "smooth" })
}
}}
>
</Button>
<Link href="/history">
<Button size="lg" variant="ghost" className="px-8 button-hover-effect">
<History className="mr-2 h-4 w-4" /> 殿
</Button>
</Link>
</div>
</div>
<div
className="absolute bottom-6 left-1/2 transform -translate-x-1/2 z-20 cursor-pointer animate-bounce"
onClick={scrollToAbout}
>
<ChevronDown className="h-10 w-10 text-primary" />
</div>
</section>
)
}