You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
4.2 KiB

1 month ago
"use client";
import React, { useEffect, useRef } from "react";
import type { HeroData } from "../types";
interface HeroProps {
data: HeroData;
locale?: string;
}
export function Hero({ data, locale = "zh-CN" }: HeroProps) {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
function resize() {
if (!canvas) return;
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
}
window.addEventListener("resize", resize);
resize();
const particles: Array<{
x: number;
y: number;
r: number;
vx: number;
vy: number;
alpha: number;
}> = [];
if (canvas) {
for (let i = 0; i < 60; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
r: Math.random() * 1.8 + 0.6,
vx: (Math.random() - 0.5) * 0.2,
vy: (Math.random() - 0.5) * 0.2,
alpha: Math.random() * 0.6 + 0.2,
});
}
}
function draw() {
if (!ctx || !canvas) return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (const p of particles) {
p.x += p.vx;
p.y += p.vy;
if (p.x < -10) p.x = canvas.width + 10;
if (p.x > canvas.width + 10) p.x = -10;
if (p.y < -10) p.y = canvas.height + 10;
if (p.y > canvas.height + 10) p.y = -10;
ctx.beginPath();
ctx.fillStyle = `rgba(196,161,75,${p.alpha})`;
ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
ctx.fill();
}
requestAnimationFrame(draw);
}
draw();
return () => {
window.removeEventListener("resize", resize);
};
}, []);
return (
<section className="relative py-12 md:py-20 pb-6 md:pb-10 bg-gradient-to-b from-[rgba(8,8,8,0.6)] to-[rgba(11,11,11,1)] overflow-hidden">
<div className="max-w-[1200px] mx-auto px-4 md:px-6 flex items-center gap-6 md:gap-10 flex-col lg:flex-row">
<div className="flex-1 max-w-[640px] w-full">
<h1 className="text-2xl sm:text-3xl md:text-[40px] mb-3 leading-[1.05] text-white font-bold">
{data.title}
</h1>
<p className="text-sm sm:text-base text-huilong-muted mb-4 md:mb-6 leading-relaxed">{data.subtitle}</p>
<div className="flex flex-wrap gap-2 md:gap-3">
<a
href={`/${locale}/solutions`}
className="inline-block px-4 md:px-[18px] py-2 md:py-3 text-sm md:text-base rounded-lg bg-huilong-gold text-huilong-bg font-semibold no-underline shadow-[0_6px_18px_rgba(196,161,75,0.12)] hover:opacity-90 active:opacity-80 transition-opacity"
>
{data.cta1}
</a>
<a
href={data.cta2Href}
className="inline-block px-4 md:px-[18px] py-2 md:py-3 text-sm md:text-base rounded-lg border border-[rgba(196,161,75,0.18)] text-huilong-gold bg-transparent font-semibold no-underline hover:opacity-80 active:opacity-70 transition-opacity"
>
{data.cta2}
</a>
</div>
</div>
<div className="flex-1 flex justify-center items-center relative h-64 sm:h-72 md:h-80 w-full lg:w-auto">
<div className="relative w-64 h-64 sm:w-72 sm:h-72 md:w-80 md:h-80">
<div className="absolute inset-0 rounded-full bg-[radial-gradient(circle_at_30%_30%,rgba(196,161,75,0.12),rgba(0,0,0,0.6))] flex items-center justify-center shadow-[0_8px_40px_rgba(0,0,0,0.6)]">
<div className="w-[140px] h-[140px] rounded-full bg-gradient-to-b from-[rgba(255,255,255,0.02)] to-[rgba(255,255,255,0.01)] border-2 border-[rgba(196,161,75,0.12)] backdrop-blur-sm" />
</div>
<canvas
ref={canvasRef}
className="absolute inset-0 w-full h-full pointer-events-none"
/>
</div>
</div>
</div>
<svg
className="absolute bottom-0 left-0 w-full h-[100px]"
viewBox="0 0 1440 100"
preserveAspectRatio="none"
>
<path
d="M0,100 C360,0 1080,0 1440,100 L1440 100 L0 100 Z"
fill="#0b0b0b"
/>
</svg>
</section>
);
}