UNPKG

@cometchat/chat-uikit-react-native

Version:

Ready-to-use Chat UI Components for React Native

97 lines 3.69 kB
import React, { useCallback, useEffect, useRef, useState } from "react"; import { Animated, StyleSheet, View } from "react-native"; export const AnimatedAudioWaves = ({ isAnimating = false, waveStyle = {}, waveContainerStyle = {}, }) => { const animatedValues = useRef([]).current; const delayValues = useRef([]); const [staticBarValues, setStaticBarValues] = useState([]); const animationStartedOnce = useRef(false); useEffect(() => { if (isAnimating === false || animatedValues.length === 0 || staticBarValues.length === 0) { return () => { }; } startAnimation(); return () => { stopAnimation(); }; }, [isAnimating, animatedValues]); const onLayoutHandler = useCallback((event) => { if (animationStartedOnce.current) { return; } const containerWidth = event.nativeEvent.layout.width; const barWidth = 2; const barMargin = 2; const totalBarWidth = barWidth + barMargin; let numBars = Math.floor(containerWidth / totalBarWidth); if (staticBarValues.length > numBars) { numBars = staticBarValues.length; } animatedValues.splice(0, animatedValues.length, ...Array(numBars) .fill(0) .map(() => new Animated.Value(1))); if (staticBarValues.length === 0 || animatedValues.length !== staticBarValues.length) { const newStaticBarValues = Array(numBars) .fill(0) .map(() => ({ height: Math.floor(Math.random() * (20 - 4 + 1)) + 4, marginTop: Math.floor(Math.random() * 5), })); setStaticBarValues(newStaticBarValues); delayValues.current = Array(numBars) .fill(0) .map(() => Math.random()); } }, [staticBarValues]); const startAnimation = () => { for (let i = 0; i < animatedValues.length; i++) { const delay = Math.floor(Math.random() * 500); Animated.loop(Animated.sequence([ Animated.timing(animatedValues[i], { toValue: delayValues.current[i], duration: 800, delay: delay, useNativeDriver: true, }), Animated.timing(animatedValues[i], { toValue: 1, duration: 400, delay: delay, useNativeDriver: true, }), ])).start(); } animationStartedOnce.current = true; }; const stopAnimation = () => { animatedValues.forEach((animatedValue) => { animatedValue.stopAnimation(); }); }; return (<View style={[styles.waveStyleContainer, waveContainerStyle]} onLayout={onLayoutHandler}> {animatedValues.map((animatedValue, index) => { return (<Animated.View key={index} style={[ styles.waveStyle, waveStyle, { transform: [{ scaleY: animatedValue }], height: staticBarValues[index]?.height, // Use optional chaining to avoid undefined errors }, ]}/>); })} </View>); }; const styles = StyleSheet.create({ waveStyleContainer: { alignItems: "center", flexDirection: "row", height: 30, overflow: "hidden", }, waveStyle: { backgroundColor: "#FFFFFF", height: 18, marginHorizontal: 1, width: 2, }, }); //# sourceMappingURL=AnimatedAudioWaves.js.map