File size: 2,100 Bytes
5306da4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
import React, { useEffect, useState } from 'react';
import { motion } from 'framer-motion';
const VoiceVisualizer: React.FC = () => {
const [bars, setBars] = useState<number[]>([]);
useEffect(() => {
// Create random bars for animation - increased bar count for smoother visualization
const barCount = 60;
const initialBars = Array.from({ length: barCount }, () => Math.random() * 50 + 10);
setBars(initialBars);
// Animation interval with smoother transitions
const interval = setInterval(() => {
setBars(prev => prev.map(() => {
// Create more natural voice-like patterns with varying heights
return Math.random() * 65 + 5;
}));
}, 75); // Faster update for smoother animation
return () => clearInterval(interval);
}, []);
return (
<div className="flex items-end justify-center gap-[1px] h-24 w-80 relative overflow-hidden rounded-lg">
{/* Add subtle glow effect in the background */}
<div className="absolute inset-0 bg-black/80 z-0"></div>
{/* Center light glow */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-32 h-32 bg-white/5 rounded-full blur-xl z-0"></div>
{bars.map((height, index) => {
// Calculate dynamic opacity for better visual effect
const opacity = 0.7 + (height / 100) * 0.3;
return (
<motion.div
key={index}
className="w-0.5 rounded-full relative z-10"
animate={{
height: `${height}%`
}}
transition={{
type: "spring",
stiffness: 300,
damping: 20,
duration: 0.2
}}
style={{
background: `linear-gradient(to bottom, rgba(255,255,255,${opacity}) 0%, rgba(255,255,255,${opacity * 0.8}) 50%, rgba(255,255,255,${opacity * 0.5}) 100%)`,
boxShadow: `0 0 4px rgba(255,255,255,${opacity * 0.5})`,
}}
/>
);
})}
</div>
);
};
export default VoiceVisualizer;
|