/**
* WaveAnimation — flowing wave bars used in "My Wave" header
* Simulates audio wave / signal motion with staggered sine animation
*/
import { useEffect } from 'react';
import { View, StyleSheet } from 'react-native';
import Animated, {
useSharedValue, useAnimatedStyle, withRepeat, withSequence,
withTiming, Easing, cancelAnimation,
} from 'react-native-reanimated';
import { Colors } from '../constants/theme';
interface Props {
active?: boolean;
barCount?: number;
height?: number;
color?: string;
}
const PHASES = [0, 0.4, 0.8, 0.2, 0.6, 0.1, 0.7, 0.3, 0.9, 0.5,
0.15, 0.55, 0.85, 0.25, 0.65];
const BASE_DURATION = 900;
function WaveBar({ active, maxH, phase, color }: {
active: boolean; maxH: number; phase: number; color: string;
}) {
const h = useSharedValue(maxH * 0.15);
useEffect(() => {
if (active) {
const delay = Math.round(phase * BASE_DURATION);
h.value = withSequence(
withTiming(maxH * 0.15, { duration: delay }),
withRepeat(
withSequence(
withTiming(maxH, { duration: BASE_DURATION, easing: Easing.inOut(Easing.sin) }),
withTiming(maxH * 0.1, { duration: BASE_DURATION, easing: Easing.inOut(Easing.sin) }),
),
-1,
false,
)
);
} else {
cancelAnimation(h);
h.value = withTiming(maxH * 0.12, { duration: 400 });
}
}, [active]);
const style = useAnimatedStyle(() => ({
height: h.value,
backgroundColor: color,
borderRadius: 3,
flex: 1,
marginHorizontal: 1.5,
}));
return ;
}
export default function WaveAnimation({ active = true, barCount = 40, height = 56, color }: Props) {
const bars = Array.from({ length: barCount }, (_, i) => i);
const barColor = color ?? Colors.accent;
return (
{bars.map((i) => (
))}
);
}
const s = StyleSheet.create({
wrap: { flexDirection: 'row', alignItems: 'flex-end', overflow: 'hidden' },
});