Estoy tratando de lograr una animación muy similar en el siguiente ejemplo.
Mi enfoque fue así: obtenga los datos del volumen de voz, agréguelos al borderWidth
de una vista usando un valor compartido de react-native-reanimated
. Sin embargo, dado que borderWidth
se agrega dentro de View
, la visualización se ve como en el siguiente ejemplo:
a continuación puedes encontrar mi código,
inicialización de estados relacionados react-native-reanimated
.
const voiceVolumeMeter = useSharedValue(0); const voiceVolumeMeterStyles = useAnimatedStyle(() => { return { borderWidth: voiceVolumeMeter.value, }; });
agregando datos de volumen al parámetro voiceVolumeMeter
:
voiceVolumeMeter.value = withSpring(55 + e.currentMetering!, { stiffness: 90, velocity: 12, mass: 0.5, });
aplicando estilo animatedStyle
a la View
<Animated.View style={[styles.volumeMeterContainer, voiceVolumeMeterStyles]}> <View style={styles.recorderCircle}> <Text style={styles.audioRecorderTimer}>{recorderState.duration}</Text> </View> </Animated.View>
estilos que usaron el ejemplo de código anterior:
recorderCircle: { width: 280, height: 280, borderRadius: 150, borderColor: Colors.DUSTY_ORANGE, justifyContent: 'center', alignItems: 'center', }, volumeMeterContainer: { width: 290, height: 290, borderRadius: 140.5, borderColor: Colors.WINDOWS_BLUE, justifyContent: 'center', padding: 20, }, audioRecorderTimer: { fontFamily: 'Quicksand', fontStyle: 'normal', fontWeight: '700', fontSize: 45, lineHeight: 56, textAlign: 'center', letterSpacing: -0.746023, color: Colors.DUSTY_ORANGE, },
Este enfoque básicamente produjo una versión exactamente invertida de la visualización de Google. Lo he intentado con los accesorios de esquema de css, pero desafortunadamente, los accesorios de esquema no son compatibles con React Native. así que necesito otro enfoque, pero no se me ocurrió una idea brillante aquí.
Cualquier ayuda será apreciada,
Saludos.
Oye, gracias a tu pregunta, hice esto, para replicar el chat de reunión,
Este es el ejemplo en vivo aquí, siéntase libre de dudas, expo-snack-link
import React, { PureComponent ,useEffect,useCallback , useState } from 'react'; import { StyleSheet, View, TouchableWithoutFeedback, Animated, Easing, Platform ,Text} from 'react-native'; const AppNew = (props={}) => { const currentVolume = props?.currentVolume ?? 0 const maxVolume = 50; const animationRef = React.useRef(new Animated.Value(0)).current const startAnimations = useCallback(() => { Animated.timing(animationRef,{ toValue:(currentVolume/maxVolume), useNativeDriver:true, duration:500 }).start() },[animationRef,currentVolume]) useEffect(() => { startAnimations() },[startAnimations]) const polAnim = animationRef.interpolate({ inputRange:[0,1], outputRange:[1,2], extrapolate:'clamp' }) return( <Animated.View style={[styles.ripler,{ position:'absolute', height:60, width:60, borderRadius:120, transform:[{ scale:polAnim }] }]} > </Animated.View> ) } const data = [1,6,39,40,50,22,7,15,12,1,6,39,40,50,22,7,15,18,1,6,39,40,50,22,7,15,12,1,6,39,40,50,22,7,15,12,1,6,39,40,50,22,7,15,12,1,6,39,40,50,22,7,15,12] const App = () => { const [currentTime, setTime ] = useState(0); const [currIndex,setIndex] = useState(0) useEffect(() => { const interval = setInterval(() => { const newIndex = currIndex +1; setTime(data[currIndex]); setIndex(newIndex); },500) return () => clearInterval(interval) },[currIndex]) return ( <View style={styles.pageContainer}> <View style={{height:100,width:100}} > <AppNew currentVolume={currentTime} /> <View style={{height:60,width:60,borderRadius:60, alignItems:'center', justifyContent:'center', backgroundColor:'rgba(125,244,102,0.9)', zIndex:3 }} > <Text>Messi</Text> </View> </View> </View> ); } const styles = StyleSheet.create({ pageContainer: { flex: 1, alignItems:'center', justifyContent:'center' }, ripler:{ backgroundColor:'rgba(125,244,102,0.3)', zIndex:2 }, contentContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', }, iconContainer: { margin: 16, alignItems: 'center', justifyContent: 'center', }, }); export default App;