From aee93c6fdb8bc0be28a70b4703e15c009f61bc64 Mon Sep 17 00:00:00 2001 From: arsam Date: Fri, 18 Sep 2026 23:07:57 +0330 Subject: [PATCH] Import source: src/components/Hero/AudioVisualizer3D Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality. --- src/components/Hero/AudioVisualizer3D.jsx | 92 +++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/components/Hero/AudioVisualizer3D.jsx diff --git a/src/components/Hero/AudioVisualizer3D.jsx b/src/components/Hero/AudioVisualizer3D.jsx new file mode 100644 index 0000000..c21d73d --- /dev/null +++ b/src/components/Hero/AudioVisualizer3D.jsx @@ -0,0 +1,92 @@ +import { useRef, useMemo } from 'react' +import { Canvas, useFrame } from '@react-three/fiber' +import * as THREE from 'three' + +const BAR_COUNT = 80 + +function Bars({ isPlaying }) { + const barsRef = useRef([]) + const phases = useMemo(() => Array.from({ length: BAR_COUNT }, () => Math.random() * Math.PI * 2), []) + const speeds = useMemo(() => Array.from({ length: BAR_COUNT }, () => 0.5 + Math.random() * 1.6), []) + + useFrame(({ clock }, delta) => { + const t = clock.getElapsedTime() + barsRef.current.forEach((mesh, i) => { + if (!mesh) return + const target = isPlaying + ? Math.abs(Math.sin(t * speeds[i] + phases[i])) * 2.4 + 0.06 + : Math.abs(Math.sin(t * 0.22 + phases[i])) * 0.28 + 0.04 + mesh.scale.y = THREE.MathUtils.lerp(mesh.scale.y, target, 0.09) + mesh.position.y = mesh.scale.y * 0.5 + // Subtle colour shift along ring + const hue = 0.12 + (i / BAR_COUNT) * 0.04 + mesh.material.emissiveIntensity = 0.5 + mesh.scale.y * 0.25 + }) + }) + + const positions = useMemo(() => { + const r = 3.4 + return Array.from({ length: BAR_COUNT }, (_, i) => { + const a = (i / BAR_COUNT) * Math.PI * 2 + return { x: Math.cos(a) * r, z: Math.sin(a) * r } + }) + }, []) + + return ( + + {positions.map((p, i) => ( + (barsRef.current[i] = el)} position={[p.x, 0.5, p.z]}> + + + + ))} + + {/* Outer ring */} + + + + + + {/* Inner ring */} + + + + + + {/* Centre glow disc */} + + + + + + ) +} + +function Scene({ isPlaying }) { + const groupRef = useRef() + useFrame((_, delta) => { + if (groupRef.current) groupRef.current.rotation.y += delta * (isPlaying ? 0.38 : 0.07) + }) + return ( + + + + ) +} + +export default function AudioVisualizer3D({ isPlaying }) { + return ( + + + + + + + + + ) +}