Merge version_2 into main #3
104
src/components/ui/horizon-hero-section.tsx
Normal file
104
src/components/ui/horizon-hero-section.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
"use client";
|
||||
|
||||
import React, { useRef, useEffect } from "react";
|
||||
import { gsap } from "gsap";
|
||||
import * as THREE from "three";
|
||||
|
||||
interface HorizonHeroSectionProps {
|
||||
title: string;
|
||||
description: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const HorizonHeroSection: React.FC<HorizonHeroSectionProps> = ({
|
||||
title,
|
||||
description,
|
||||
className,
|
||||
}) => {
|
||||
const mountRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!mountRef.current) return;
|
||||
|
||||
const currentMount = mountRef.current;
|
||||
const scene = new THREE.Scene();
|
||||
const camera = new THREE.PerspectiveCamera(
|
||||
75,
|
||||
currentMount.clientWidth / currentMount.clientHeight,
|
||||
0.1,
|
||||
1000
|
||||
);
|
||||
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
||||
|
||||
renderer.setSize(currentMount.clientWidth, currentMount.clientHeight);
|
||||
currentMount.appendChild(renderer.domElement);
|
||||
|
||||
// Example: Add a simple cube
|
||||
const geometry = new THREE.BoxGeometry();
|
||||
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
|
||||
const cube = new THREE.Mesh(geometry, material);
|
||||
scene.add(cube);
|
||||
|
||||
camera.position.z = 5;
|
||||
|
||||
const animate = () => {
|
||||
requestAnimationFrame(animate);
|
||||
|
||||
cube.rotation.x += 0.01;
|
||||
cube.rotation.y += 0.01;
|
||||
|
||||
renderer.render(scene, camera);
|
||||
};
|
||||
|
||||
animate();
|
||||
|
||||
// GSAP animation example
|
||||
gsap.fromTo(
|
||||
".hero-content", { opacity: 0, y: 50 },
|
||||
{ opacity: 1, y: 0, duration: 1.5, ease: "power3.out" }
|
||||
);
|
||||
|
||||
const handleResize = () => {
|
||||
camera.aspect = currentMount.clientWidth / currentMount.clientHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(currentMount.clientWidth, currentMount.clientHeight);
|
||||
};
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
if (currentMount.contains(renderer.domElement)) {
|
||||
currentMount.removeChild(renderer.domElement);
|
||||
}
|
||||
renderer.dispose();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<section
|
||||
className={`relative w-full h-screen overflow-hidden flex items-center justify-center bg-transparent ${className}`}
|
||||
>
|
||||
<div ref={mountRef} className="absolute inset-0 z-0"></div>
|
||||
<div className="hero-content relative z-10 text-center text-white p-4 max-w-4xl">
|
||||
<h1 className="text-5xl md:text-7xl font-bold mb-4 leading-tight">
|
||||
{title}
|
||||
</h1>
|
||||
<p className="text-lg md:text-xl opacity-80">
|
||||
{description}
|
||||
</p>
|
||||
<div className="mt-8 flex justify-center space-x-4">
|
||||
{/* Placeholder for buttons if needed */}
|
||||
<button className="px-6 py-3 bg-blue-600 hover:bg-blue-700 rounded-lg text-white font-semibold transition-colors">
|
||||
Get Started
|
||||
</button>
|
||||
<button className="px-6 py-3 border border-white text-white rounded-lg hover:bg-white hover:text-blue-600 transition-colors">
|
||||
Learn More
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default HorizonHeroSection;
|
||||
Reference in New Issue
Block a user