Reanimated v2 – Valores compartidos sincronizados
Pregunta
Estoy tratando de crear esta animación utilizando Reanimated v2:
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 2useDerivedValue
s, 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 elwithRepeat
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
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 usarinterpolate
para mapear el valor de pulso al valor de opacidad correspondiente con un retardo determinista entre ellos. Aquí tienes un ejemplo de implementación:En esta implementación, calculamos la animación del pulso utilizando
withRepeat
para repetirla indefinidamente y actualizamos el valor compartidopulse
en consecuencia. Luego, definimos tres hooksuseDerivedValue
para calcular los valores de opacidad basados en el valor de pulso utilizandointerpolate
. 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.