Transición animada en React Native!

Recientemente he tratado de inspirarme para un próximo desafío de animación. Y aquí vamos, creado por Ivan Parfenov. Tenía curiosidad si puedo hacer este efecto de transición con React Native. ¡Puedes ver un resultado en mi cuenta expo! ¿Por qué necesitamos las animaciones como estas? Lea los consejos de animación de UI de buena a excelente de Pablo Stanley.

Para PLΛTES por Ivan Parfenov

Podemos ver que hay un par de animaciones. Barra de herramientas (mostrar / ocultar), barra inferior (mostrar / ocultar), mover un elemento seleccionado, ocultar todos los demás, mostrar elementos detallados y tal vez incluso más.

Cronología de animaciones

Lo difícil de la transición es sincronizar todas esas animaciones. Realmente no podemos desmontar la página de lista y mostrar la página de detalles porque tenemos que esperar hasta que se realicen todas las animaciones. Además, soy fanático de tener un código limpio. De fácil mantenimiento. Si alguna vez ha intentado implementar una animación en su proyecto, el código generalmente se vuelve desordenado. Lleno de variables auxiliares, cálculos locos, etc. Es por eso que me gustaría presentar react-native-motion.

Una idea de react-native-motion

¿Puedes ver la animación del título de la barra de herramientas? Solo necesita mover el título un poco y animar una opacidad a cero / uno. ¡No es gran cosa! Pero debido a eso, necesitas escribir un código como este. Incluso antes de comenzar a escribir la interfaz de usuario para ese componente.

Ahora echemos un vistazo a cómo podemos usar react-native-motion para esto. Sé que las animaciones suelen ser muy específicas. Y sé que React Native proporciona una API animada muy poderosa. De todos modos, sería genial tener una biblioteca con animaciones básicas.

Elemento compartido

El mayor problema de este desafío fue mover el elemento de lista seleccionado. El elemento que se comparte entre la página de lista y la página de detalles. ¿Cómo mover el elemento de FlatList a la parte superior de la página de detalles cuando el elemento no está en una posición absoluta? Es bastante fácil con react-native-motion.

Especificamos el elemento fuente de SharedElement en la página de lista. Ahora necesitamos hacer casi lo mismo para el elemento de destino en la página de detalles. Para saber la posición donde queremos mover el elemento compartido.

Donde esta la magia

¿Cómo podemos mover un elemento relativamente posicionado de una página a otra? En realidad, no podemos. SharedElement funciona así:

  • obtener una posición del elemento fuente
  • obtener la posición del elemento de destino (obviamente, sin este paso, la animación no se puede iniciar)
  • crear un clon del elemento compartido (¡La magia!)
  • renderizar una nueva capa sobre la pantalla
  • renderizar el elemento clonado que cubrirá el elemento fuente (en su posición)
  • iniciar el movimiento a la posición de destino
  • una vez que se alcanzó la posición de destino, elimine el elemento clonado

Probablemente pueda imaginar que hay 3 elementos del mismo nodo de reacción en el mismo momento. Esto se debe a que la página de lista está cubierta por la página de detalles durante esa animación en movimiento. Por eso podemos ver los 3 elementos. Pero queremos crear una ilusión de que realmente estamos moviendo el elemento fuente original.

Cronología de SharedElement

Puede ver el punto A y el punto B. Ese es un período de tiempo cuando se realiza el movimiento. También puede ver que SharedElement activa algunos eventos útiles. En este caso, usamos eventos WillStart y DidFinish. Depende de usted establecer una opacidad para el elemento de origen y destino en 0 cuando se inició un movimiento al destino, y volver a 1 para el elemento de destino una vez que la animación haya finalizado.

¿Qué piensas?

Todavía hay trabajo en react-native-motion. Definitivamente no es una versión final y estable de esta biblioteca. Pero es un buen comienzo, espero :) ¡Me encantaría saber qué piensas sobre eso!

Estoy constantemente buscando nuevos desafíos y oportunidades. Si necesita ayuda con algo, hágamelo saber, por favor;) Estaré encantado de discutirlo.
LinkedIn || Github || Twitter || Facebook || 500px