
Hola a todos!
La Navidad ya pasó, pero después tenemos una historia interesante sobre cómo usar la función Core Animation que se usa con poca frecuencia para crear un ambiente festivo para los usuarios. Comparto la traducción de un artículo de mi colega londinense Alexis.
La Navidad siempre ha sido uno de mis días favoritos del año para mí. Trae mucho amor, risas, felicidad y magia a nuestras vidas.
Nací y crecí en España, en Tenerife, una isla soleada en medio del Océano Atlántico frente a la costa de África. Y, créanme, la Navidad en Tenerife es muy diferente de la Navidad en Londres, donde lo conocí los últimos dos años (desde que empecé a trabajar en Badoo).
Para mí, uno de los beneficios de vivir en Londres era contemplar los copos de nieve. Aquí los vi por primera vez en mi vida, ¡fue simplemente increíble!
Al recordar esto, decidí compartir con ustedes una historia interesante que me sucedió en la oficina poco antes de Navidad, antes de ir a Tenerife para celebrar las vacaciones con mi familia.
Dio la casualidad de que me asignaron una tarea inusual con la siguiente descripción:

Hmm, muy gracioso. Queríamos agregar animación navideña con copos de nieve a nuestra aplicación iOS, y me convertí en la afortunada de crearla. Pero no sabía por dónde empezar.
Como de costumbre, se adjuntó un archivo Sketch a la tarea con el diseño necesario, que se parecía a esto:

Al menos vi lo que necesitábamos, pero no estaba completamente seguro de cómo deberían comportarse estos copos de nieve. Para aclarar todos los detalles, fui a hablar con los diseñadores.
Como sospechaba, ya tenían una gran animación dibujada en
After Effects .
Los diseñadores me explicaron que querían agregar los copos de nieve que caían desde arriba en la animación ya existente de iniciar la aplicación (así como el gorro de Papá Noel en nuestro logotipo, pero fue una simple sustitución de la imagen, indigna de mencionar en este artículo).
Sabía que la animación del lanzamiento de una aplicación en iOS se realizó con
Lottie , ya que se agregó después de
unirme a la empresa (
Radek Cieciwa puede encontrar detalles en el artículo). Sin embargo, les dije a los diseñadores que trataría de encontrar soluciones más simples para mostrar los copos de nieve (sin la necesidad de usar Lottie) y comencé a explorar varios enfoques.
Aquí hay una animación que mi colega Radek hizo para Badoo. Impecable!

Y entonces agregué copos de nieve cayendo. ¿Quieres saber cómo lo hice? Encontrará la respuesta a continuación.

Sistemas de partículas
Mientras leía varios documentos sobre animaciones, recordé que en los juegos y películas, los sistemas de partículas a menudo se usan para resolver tales problemas.
Wikipedia describe este concepto con bastante precisión:
“El sistema de partículas es un método utilizado en gráficos por computadora para representar objetos que no tienen límites geométricos claros (varias nubes, nebulosas, explosiones, chorros de vapor, trenes de misiles, humo, nieve, lluvia, etc.). Los sistemas de partículas se pueden implementar en gráficos bidimensionales y tridimensionales ".
Esta técnica se utilizó por primera vez en 1982 en Star Trek 2: The Wrath of Khan, para crear un "efecto de génesis".
Un sistema de partículas consta de una o más primitivas gráficas, como puntos, líneas o imágenes, llamadas partículas. Estas partículas son creadas y emitidas por un emisor que forma parte de un sistema de partículas.
Cada partícula tiene un conjunto de parámetros que afectan directa o indirectamente su comportamiento y determinan cómo se dibujará. Las partículas pueden moverse simultáneamente en grandes cantidades y en diferentes direcciones, por ejemplo, para crear el efecto de un líquido.
La animación surte efecto cuando el sistema emite partículas. El sistema emite partículas en lugares aleatorios dentro del área especificada del sistema de partículas. Puede tomar varias formas: círculo, rectángulo, esfera, caja, línea, punto, etc.
El sistema también determina las propiedades de las partículas que afectan su geometría, velocidad y otros parámetros. Las diferentes API de emisor tienen diferentes nombres para propiedades similares.
Cuando el sistema emite partículas al mismo tiempo, crean animaciones impresionantes que pueden verse como lluvia, fuego o nieve.



De la teoría a la práctica.
Pensé que Apple probablemente tiene soporte de sistema de partículas incorporado en uno de sus marcos. Y los resultados de mis búsquedas han demostrado que tengo razón.
El sistema de partículas forma parte del marco Core Animation y está bien descrito en las
clases CAEmitterLayer y
CAEmitterCell .
Después de estudiar toda la información necesaria sobre el sistema de partículas y las API compatibles en iOS, pasé a mi parte favorita: implementar nuestra idea.
Desafortunadamente, la Navidad no dura para siempre, por lo que necesitábamos la capacidad de apagar los copos de nieve de forma remota después del 25 de diciembre.
Como mencioné anteriormente, la animación de inicio de la aplicación se implementó usando Lottie. Es decir, necesitaba encontrar una manera de agregar copos de nieve de tal manera que no afectara la animación existente y su código, porque mi solución tuvo que ser eliminada inmediatamente después del lanzamiento.
Encontré una manera muy simple de hacer esto: agregué una nueva UIView transparente para mostrar los copos de nieve frente a la animación y el fondo existentes y luego controlé su apariencia de forma remota usando una bandera.

La imagen de arriba muestra las UIView que se usaron en la solución final:
- UIView con un sistema de partículas que emitió copos de nieve.
- UIViews utilizados en animaciones de lanzamiento de aplicaciones basadas en Lottie.
Después de resolver este problema, tuve que crear un componente que contenga la lógica de emisión de partículas para generar copos de nieve animados.
Para empezar, necesitaba imágenes de copos de nieve que pudiera usar como contenido para el emisor. Deberían ser bastante simples, ¿verdad?
Cada copo de nieve era un círculo blanco ordinario o borroso. Los creé yo mismo en Sketch.

Algunos detalles de implementación
CAEmitterLayer es un CALayer especial que crea, anima y renderiza un sistema de partículas. Le permite controlar su geometría, posición, modo de dibujo y mucho más.
Comencé a desarrollar animación creando una capa:
snowEmitterLayer.emitterShape = CAEmitterLayerEmitterShape.line snowEmitterLayer.beginTime = CACurrentMediaTime() snowEmitterLayer.timeOffset = 10.0
Solo necesitaba cambiar tres propiedades:
- emitterShape : define la forma de la capa. Usé una línea que permitía que aparecieran copos de nieve a lo largo de toda la pantalla;
- beginTime : forma parte del protocolo CAMediaTiming y representa el tiempo de inicio de la animación de capa en relación con las animaciones de capa principal;
- timeOffset : también forma parte del protocolo CAMediaTiming y, en esencia, es una animación de avance rápido para un tiempo determinado en relación con su inicio. Especifiqué un valor de 10 segundos, lo que condujo al hecho de que en el momento en que comenzó la animación, los copos de nieve ya cubrían toda la pantalla, y eso es exactamente lo que queríamos (si hubiera establecido el valor en 0 segundos, los copos de nieve comenzarían a aparecer en la parte superior y cubrirían la pantalla enteramente solo después de algún tiempo).
Al tener una capa terminada, creé dos emisores diferentes: más pesados para los copos de nieve y más fáciles para los copos de nieve.
Para los copos de nieve pesados, configuré el emisor de la siguiente manera:
let flakeEmitterCell = CAEmitterCell() flakeEmitterCell.contents = UIImage(named: "snowflake_dot")!.cgImage flakeEmitterCell.emissionRange = .pi flakeEmitterCell.lifetime = 20.0 flakeEmitterCell.birthRate = 30 flakeEmitterCell.scale = 0.15 flakeEmitterCell.scaleRange = 0.6 flakeEmitterCell.velocity = 30.0 flakeEmitterCell.velocityRange = 20 flakeEmitterCell.spin = -0.5 flakeEmitterCell.spinRange = 1.0 flakeEmitterCell.yAcceleration = 30.0 flakeEmitterCell.xAcceleration = 5.0
Como puede ver, tuve que cambiar un número significativo de propiedades, cada una de las cuales es muy importante para lograr el efecto deseado:
- contenido : CGImage solía mostrar un copo de nieve (como recordarán, esta es una de esas imágenes que yo mismo creé);
- rango de emisión : ángulo en radianes que define el cono dentro del cual aparecerán las partículas (elegí el ángulo PI para que las partículas sean visibles en toda la pantalla);
- vida útil : determina la vida útil de una partícula;
- birthRate : determina el número de partículas emitidas por segundo;
- scale and scaleRange : afecta el tamaño de partícula, donde un valor de 1.0 es el tamaño máximo; el intervalo determina las desviaciones de tamaño entre las partículas creadas, lo que permite que se emitan partículas de tamaños aleatorios;
- velocidad y rango de velocidad : afecta la velocidad de aparición de partículas; se desvía aleatoriamente dentro del valor especificado en velocityRange;
- spin y spinRange : afectan la velocidad de rotación, medida en radianes por segundo, y la desviación aleatoria dentro del valor especificado en spinRange;
- Aceleración y aceleración : son dos componentes del vector de aceleración aplicado al emisor.
También necesitaba un segundo emisor para crear copos de nieve ligeros. Todas las propiedades permanecieron sin cambios, con la excepción de dos:
- contenido : aquí utilicé imágenes con un círculo borroso;
- velocidad : y aquí tuve que reducir la velocidad de caída para hacer que los copos de nieve fueran ligeros.
let blurryFlakeEmitterCell = CAEmitterCell() blurryFlakeEmitterCell.contents = UIImage(named: "snowflake_blurry_dot")?.cgImage blurryFlakeEmitterCell.velocity = 40
Solo pude conectar la capa y los emisores, lo que resultó ser muy fácil:
snowEmitterLayer.emitterCells = [flakeEmitterCell, blurryFlakeEmitterCell] self.layer.addSublayer(snowEmitterLayer)
Conclusión
Rápidamente creé una versión funcional con copos de nieve cayendo, que se veía muy bien. Fue bastante simple de implementar y no cambió el código existente. Se lo mostré a los diseñadores, y realmente les gustó.
Las animaciones del sistema de partículas pueden ser bastante impresionantes y relativamente fáciles de implementar si tiene las herramientas adecuadas.
Se puede encontrar más información sobre los sistemas de partículas en las siguientes fuentes: