Components
This hero section has modern and engaging with smooth, sophisticated animations
Loading preview...
"use client"
import { useEffect, useRef } from "react"
import * as THREE from "three"
export default function ThreeBackground() {
const mountRef = useRef<HTMLDivElement>(null)
const sceneRef = useRef<THREE.Scene>()
const rendererRef = useRef<THREE.WebGLRenderer>()
const cameraRef = useRef<THREE.PerspectiveCamera>()
const geometriesRef = useRef<THREE.Mesh[]>([])
useEffect(() => {
if (!mountRef.current) return
// Scene setup
const scene = new THREE.Scene()
sceneRef.current = scene
// Camera setup
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 5
cameraRef.current = camera
// Renderer setup
const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true })
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
rendererRef.current = renderer
mountRef.current.appendChild(renderer.domElement)
// Create floating geometries
const geometries = []
const colors = [0x8b5cf6, 0xa855f7, 0xc084fc, 0xe879f9]
for (let i = 0; i < 20; i++) {
const geometry = new THREE.IcosahedronGeometry(0.1 + Math.random() * 0.3)
const material = new THREE.MeshBasicMaterial({
color: colors[Math.floor(Math.random() * colors.length)],
transparent: true,
opacity: 0.6,
wireframe: Math.random() > 0.5,
})
const mesh = new THREE.Mesh(geometry, material)
mesh.position.set((Math.random() - 0.5) * 10, (Math.random() - 0.5) * 10, (Math.random() - 0.5) * 10)
mesh.rotation.set(Math.random() * Math.PI, Math.random() * Math.PI, Math.random() * Math.PI)
scene.add(mesh)
geometries.push(mesh)
}
geometriesRef.current = geometries
// Animation loop
const animate = () => {
requestAnimationFrame(animate)
// Rotate geometries
geometries.forEach((mesh, index) => {
mesh.rotation.x += 0.005 + index * 0.0001
mesh.rotation.y += 0.005 + index * 0.0001
mesh.position.y += Math.sin(Date.now() * 0.001 + index) * 0.001
})
renderer.render(scene, camera)
}
animate()
// Handle resize
const handleResize = () => {
if (!camera || !renderer) return
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
}
window.addEventListener("resize", handleResize)
// Mouse movement effect
const handleMouseMove = (event: MouseEvent) => {
if (!camera) return
const x = (event.clientX / window.innerWidth) * 2 - 1
const y = -(event.clientY / window.innerHeight) * 2 + 1
camera.position.x += (x * 0.5 - camera.position.x) * 0.05
camera.position.y += (y * 0.5 - camera.position.y) * 0.05
}
window.addEventListener("mousemove", handleMouseMove)
return () => {
window.removeEventListener("resize", handleResize)
window.removeEventListener("mousemove", handleMouseMove)
if (mountRef.current && renderer.domElement) {
mountRef.current.removeChild(renderer.domElement)
}
renderer.dispose()
}
}, [])
return <div ref={mountRef} className="absolute inset-0 z-0" />
}
Loading preview...