es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Reanimated v2 – Valores compartidos sincronizados

Pregunta

Estoy tratando de crear esta animación utilizando Reanimated v2:

entrar descripción de la imagen aquí

Esta es la implementación actual:

typescript
const opacity1 = useSharedValue(0);
const opacity2 = useSharedValue(0);
const opacity3 = useSharedValue(0);
useEffect(() => {
const duration = 600;
const timingOptions = { duration: duration };
const pulse = withTiming(1, timingOptions);
const repeated = withRepeat(pulse, -1, true);
opacity1.value = repeated;
// *
opacity2.value = withDelay(duration / 2, repeated);
// *
opacity3.value = withDelay(duration, repeated);
}, []);

El problema es que donde he marcado el código con // * parece haber una demora aleatoria (probablemente debido a la ejecución de JS) que provoca que los tres puntos a veces terminen sincronizados (teniendo la misma opacidad).

Presumo que el problema radica en que la actualización de esos 3 valores no es atómica, por lo que puede ocurrir cualquier cosa entre esas asignaciones.

¿Cuál es la mejor manera de resolver esto y tener esos 3 valores compartidos con una demora determinista entre ellos?


¿Qué he intentado?

  • Intenté usar 1 useSharedValue y 2 useDerivedValues, pero el cálculo para que uno comience en 0, uno comience en 0.5 y uno comience en 1 no es trivial (simplemente agregar 0.5 entre sí y hacerlo módulo (%) 1 no tiene en cuenta el withRepeat volviendo después de alcanzar 1)
  • Intenté usar un useSharedValue([0, 0, 0]) y luego actualizarlo con una operación atómica, pero eso no parece ser soportado
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para resolver este problema, debemos asegurarnos de que las actualizaciones de los valores compartidos sean atómicas y sincronizadas. Una solución es utilizar useDerivedValue para calcular los valores de opacidad basados en un único valor compartido que representa el progreso actual de la animación del pulso. Luego podemos usar interpolate para mapear el valor de pulso al valor de opacidad correspondiente con un retardo determinista entre ellos. Aquí tienes un ejemplo de implementación:

    const pulse = useSharedValue(0);
    
    useEffect(() => {
      const duration = 600;
      const timingOptions = { duration: duration };
      const pulseAnimation = withRepeat(withTiming(1, timingOptions), -1, true);
      pulse.value = pulseAnimation;
    }, []);
    
    const dotOpacity1 = useDerivedValue(() => {
      return interpolate(pulse.value, [0, 0.5], [0, 1]);
    });
    
    const dotOpacity2 = useDerivedValue(() => {
      return interpolate(pulse.value, [0.25, 0.75], [0, 1]);
    });
    
    const dotOpacity3 = useDerivedValue(() => {
      return interpolate(pulse.value, [0.5, 1], [0, 1]);
    });
    

    En esta implementación, calculamos la animación del pulso utilizando withRepeat para repetirla indefinidamente y actualizamos el valor compartido pulse en consecuencia. Luego, definimos tres hooks useDerivedValue para calcular los valores de opacidad basados en el valor de pulso utilizando interpolate. Al establecer los rangos apropiados para cada punto, podemos asegurar un retardo determinista entre ellos.

    Esto debería evitar cualquier retardo aleatorio o problema de sincronización entre los valores compartidos.

Comments are closed.