Files
Skyheal/app/components/canvas/DNAHeroBackground.tsx
2026-01-22 11:27:35 +05:30

85 lines
2.8 KiB
TypeScript

"use client";
import { Canvas, useFrame } from "@react-three/fiber";
import { useRef, useMemo } from "react";
import * as THREE from "three";
import { Float, PerspectiveCamera } from "@react-three/drei";
function DNAParticles() {
const points = useMemo(() => {
const p = [];
const count = 100;
const radius = 2;
const height = 15;
for (let i = 0; i < count; i++) {
const angle = (i / count) * Math.PI * 4;
const x = Math.cos(angle) * radius;
const y = (i / count) * height - height / 2;
const z = Math.sin(angle) * radius;
// Strand 1
p.push(new THREE.Vector3(x, y, z));
// Strand 2 (180 deg offset)
p.push(new THREE.Vector3(-x, y, -z));
// Connecting rungs
if (i % 5 === 0) {
const rungPoints = 5;
for (let j = 1; j < rungPoints; j++) {
const t = j / rungPoints;
p.push(new THREE.Vector3(
x * (1 - 2 * t),
y,
z * (1 - 2 * t)
));
}
}
}
return p;
}, []);
const groupRef = useRef<THREE.Group>(null);
useFrame((state) => {
if (groupRef.current) {
groupRef.current.rotation.y += 0.005;
groupRef.current.rotation.z = Math.sin(state.clock.elapsedTime * 0.5) * 0.1;
}
});
return (
<group ref={groupRef}>
{points.map((pos, i) => (
<mesh key={i} position={pos}>
<sphereGeometry args={[0.04, 8, 8]} />
<meshStandardMaterial
color={i % 2 === 0 ? "#3b82f6" : "#8b5cf6"}
emissive={i % 2 === 0 ? "#1e40af" : "#5b21b6"}
emissiveIntensity={2}
/>
</mesh>
))}
</group>
);
}
export default function DNAHeroBackground() {
return (
<div className="fixed inset-0 -z-10 bg-background">
<Canvas shadows dpr={[1, 2]}>
<PerspectiveCamera makeDefault position={[0, 0, 10]} fov={50} />
<ambientLight intensity={0.5} />
<pointLight position={[10, 10, 10]} intensity={1} color="#3b82f6" />
<pointLight position={[-10, -10, -10]} intensity={1} color="#8b5cf6" />
<spotLight position={[0, 5, 0]} angle={0.3} penumbra={1} intensity={2} castShadow />
<Float speed={2} rotationIntensity={0.5} floatIntensity={0.5}>
<DNAParticles />
</Float>
</Canvas>
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-background/50 to-background pointer-events-none" />
</div>
);
}