172 lines
5.6 KiB
TypeScript
172 lines
5.6 KiB
TypeScript
'use client';
|
||
|
||
import React, { useRef, useMemo } from 'react';
|
||
import { Canvas, useFrame } from '@react-three/fiber';
|
||
import { Float, Stars } from '@react-three/drei';
|
||
import * as THREE from 'three';
|
||
|
||
// ------------------- Three.js Components -------------------
|
||
|
||
const GeometryArt = () => {
|
||
const meshRef = useRef<THREE.Mesh>(null);
|
||
|
||
useFrame((state) => {
|
||
if (meshRef.current) {
|
||
meshRef.current.rotation.x = state.clock.getElapsedTime() * 0.1;
|
||
meshRef.current.rotation.y = state.clock.getElapsedTime() * 0.15;
|
||
}
|
||
});
|
||
|
||
return (
|
||
<Float speed={1.5} rotationIntensity={0.5} floatIntensity={0.5}>
|
||
<mesh ref={meshRef} position={[2, 0, 0]} scale={1.8}>
|
||
<icosahedronGeometry args={[1, 1]} />
|
||
<meshStandardMaterial
|
||
color="#C5A059"
|
||
wireframe
|
||
transparent
|
||
opacity={0.3}
|
||
roughness={0}
|
||
metalness={1}
|
||
/>
|
||
</mesh>
|
||
<mesh position={[2, 0, 0]} scale={0.5}>
|
||
<sphereGeometry args={[1, 32, 32]} />
|
||
<meshStandardMaterial
|
||
color="#C5A059"
|
||
emissive="#C5A059"
|
||
emissiveIntensity={0.5}
|
||
roughness={0.2}
|
||
metalness={1}
|
||
/>
|
||
</mesh>
|
||
</Float>
|
||
);
|
||
};
|
||
|
||
const ConnectingLines = () => {
|
||
// Create random connections mimicking a network
|
||
const count = 40;
|
||
const lines = useMemo(() => {
|
||
const points: [number, number, number][] = [];
|
||
// Use a fixed seed for consistent but pseudo-random positioning
|
||
const seed = 12345;
|
||
const seededRandom = (i: number) => {
|
||
const x = Math.sin(seed + i * 12.9898) * 43758.5453123;
|
||
return x - Math.floor(x);
|
||
};
|
||
for (let i = 0; i < count; i++) {
|
||
points.push([
|
||
(seededRandom(i * 3) - 0.5) * 10,
|
||
(seededRandom(i * 3 + 1) - 0.5) * 6,
|
||
(seededRandom(i * 3 + 2) - 0.5) * 5
|
||
]);
|
||
}
|
||
return points;
|
||
}, []);
|
||
|
||
const ref = useRef<THREE.Group>(null);
|
||
|
||
useFrame((state) => {
|
||
if (ref.current) {
|
||
ref.current.rotation.y = -state.clock.getElapsedTime() * 0.05;
|
||
}
|
||
});
|
||
|
||
return (
|
||
<group ref={ref}>
|
||
{lines.map((pos, i) => (
|
||
<mesh key={i} position={new THREE.Vector3(...pos)}>
|
||
<sphereGeometry args={[0.02, 8, 8]} />
|
||
<meshBasicMaterial color="#ffffff" opacity={0.4} transparent />
|
||
</mesh>
|
||
))}
|
||
</group>
|
||
)
|
||
}
|
||
|
||
const Scene = () => {
|
||
return (
|
||
<>
|
||
<ambientLight intensity={0.2} />
|
||
<pointLight position={[10, 10, 10]} intensity={1.5} color="#C5A059" />
|
||
<pointLight position={[-10, -10, -10]} intensity={0.5} color="#4c4c4c" />
|
||
<spotLight position={[0, 5, 0]} angle={0.3} penumbra={1} intensity={2} color="white" />
|
||
|
||
<GeometryArt />
|
||
<ConnectingLines />
|
||
<Stars radius={100} depth={50} count={5000} factor={4} saturation={0} fade speed={1} />
|
||
</>
|
||
);
|
||
};
|
||
|
||
// ------------------- Main Component -------------------
|
||
|
||
const Hero: React.FC = () => {
|
||
return (
|
||
<section id="hero" className="relative w-full h-screen bg-feie-dark overflow-hidden">
|
||
{/* 3D Canvas Layer */}
|
||
<div className="absolute inset-0 z-0">
|
||
<Canvas camera={{ position: [0, 0, 6], fov: 45 }}>
|
||
<Scene />
|
||
</Canvas>
|
||
</div>
|
||
|
||
{/* Content Overlay */}
|
||
<div className="absolute inset-0 z-10 flex items-center">
|
||
<div className="container mx-auto px-6 grid grid-cols-1 md:grid-cols-2">
|
||
<div className="text-left space-y-6">
|
||
<div className="inline-block px-3 py-1 border border-feie-gold/50 rounded-full">
|
||
<span className="text-feie-gold text-xs font-serif tracking-widest uppercase">
|
||
Est. Nanjing • Technology Leader
|
||
</span>
|
||
</div>
|
||
<h1 className="text-5xl md:text-7xl font-serif text-feie-white leading-tight">
|
||
数字化未来的 <br />
|
||
<span className="text-feie-gold italic">构建者</span>
|
||
</h1>
|
||
<p className="text-feie-white/70 text-lg md:text-xl font-light max-w-md leading-relaxed">
|
||
南京市肥鹅信息技术有限公司致力于为企业提供卓越的数字化解决方案,以创新技术驱动商业价值。
|
||
</p>
|
||
<div className="pt-8 flex gap-4">
|
||
<a
|
||
href="#services"
|
||
className="px-8 py-3 bg-feie-gold text-feie-white font-serif hover:bg-yellow-600 transition-colors duration-300 rounded-sm"
|
||
>
|
||
探索服务
|
||
</a>
|
||
<a
|
||
href="#contact"
|
||
className="px-8 py-3 border border-feie-white text-feie-white font-serif hover:bg-feie-white hover:text-feie-dark transition-colors duration-300 rounded-sm"
|
||
>
|
||
联系我们
|
||
</a>
|
||
</div>
|
||
</div>
|
||
{/* Right side is empty to allow the 3D visual to shine */}
|
||
<div className="hidden md:block"></div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Scroll indicator */}
|
||
<div className="absolute bottom-8 left-1/2 transform -translate-x-1/2 z-10 animate-bounce">
|
||
<svg
|
||
width="24"
|
||
height="24"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#FFFFFF"
|
||
strokeWidth="2"
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
className="opacity-50"
|
||
>
|
||
<path d="M12 5v14M19 12l-7 7-7-7"/>
|
||
</svg>
|
||
</div>
|
||
</section>
|
||
);
|
||
};
|
||
|
||
export default Hero;
|