Spaces:
Running
Running
| "use client"; | |
| import { Canvas, useFrame } from "@react-three/fiber"; | |
| import { useRef, useMemo } from "react"; | |
| import * as THREE from "three"; | |
| function ParticleField() { | |
| const points = useRef<THREE.Points>(null); | |
| const particlesCount = 1000; | |
| const positions = useMemo(() => { | |
| const pos = new Float32Array(particlesCount * 3); | |
| for (let i = 0; i < particlesCount; i++) { | |
| pos[i * 3] = (Math.random() - 0.5) * 50; | |
| pos[i * 3 + 1] = (Math.random() - 0.5) * 50; | |
| pos[i * 3 + 2] = (Math.random() - 0.5) * 50; | |
| } | |
| return pos; | |
| }, []); | |
| useFrame((state) => { | |
| if (points.current) { | |
| points.current.rotation.y = state.clock.elapsedTime * 0.05; | |
| points.current.rotation.x = state.clock.elapsedTime * 0.03; | |
| } | |
| }); | |
| return ( | |
| <points ref={points}> | |
| <bufferGeometry> | |
| <bufferAttribute | |
| attach="attributes-position" | |
| count={particlesCount} | |
| array={positions} | |
| itemSize={3} | |
| /> | |
| </bufferGeometry> | |
| <pointsMaterial | |
| size={0.05} | |
| color="#0070f3" | |
| transparent | |
| opacity={0.6} | |
| sizeAttenuation | |
| /> | |
| </points> | |
| ); | |
| } | |
| function WaveGrid() { | |
| const mesh = useRef<THREE.Mesh>(null); | |
| useFrame((state) => { | |
| if (mesh.current) { | |
| const time = state.clock.elapsedTime; | |
| const geometry = mesh.current.geometry as THREE.PlaneGeometry; | |
| const positions = geometry.attributes.position; | |
| for (let i = 0; i < positions.count; i++) { | |
| const x = positions.getX(i); | |
| const y = positions.getY(i); | |
| const wave = Math.sin(x * 0.5 + time) * Math.cos(y * 0.5 + time) * 0.3; | |
| positions.setZ(i, wave); | |
| } | |
| positions.needsUpdate = true; | |
| } | |
| }); | |
| return ( | |
| <mesh ref={mesh} rotation={[-Math.PI / 3, 0, 0]} position={[0, -5, 0]}> | |
| <planeGeometry args={[20, 20, 32, 32]} /> | |
| <meshBasicMaterial | |
| color="#0070f3" | |
| wireframe | |
| transparent | |
| opacity={0.1} | |
| /> | |
| </mesh> | |
| ); | |
| } | |
| export default function ThreeBackground() { | |
| return ( | |
| <div className="fixed inset-0 -z-10"> | |
| <Canvas camera={{ position: [0, 0, 10], fov: 75 }}> | |
| <ambientLight intensity={0.5} /> | |
| <ParticleField /> | |
| <WaveGrid /> | |
| </Canvas> | |
| </div> | |
| ); | |
| } | |