Amazing Clock ⏰ Animación con Jetpack Compose (Parte 3) – Optimización + Agregar algunos 🌈Colores | de Mikhail Kulaha | marzo 2023

En esta serie de artículos, solo intentaremos recrear esta increíble animación de reloj, pero en realidad !Animación de reloj con un poco de colorEsta es la tercera parte de nuestra serie de animación. la parte 1 esla parte 2 es

– Se pudo encontrar el código fuente de la versión final de esta animación.– Tenemos para recrear la misma animación, una cony otro usando

Hasta ahora lo hemos logrado en la Parte 1 y la Parte 2:

  • crea uno animación
  • Dibuja una manecilla de reloj que Primero y luego durante los siguientes
  • Jalar que desaparecen y reaparecen cuando es necesario
  • crear puntos
  • Crear 12 en paralelo .

  • la misma animación con un para 12 hilos para difundir animaciones.
  • cambiar de forma a y agrega algunos 🌈 Colores 🔥
  • Si lo desea, detenga una animación sin fin

En la parte 2 anterior se nos ocurrió esto lo que tienes que tener para cada uno de los puntos de propagación. Como ya habrás adivinado, esto no era óptimo. De hecho, podemos reemplazarlo con un y no es necesario crear hilos separados. Conocemos esta animación . Y en base a eso Anima desde la punta de la flecha hasta el borde exterior del círculo usando esta fórmula: positionY = halfStroke + stepHeight * it * (1 – disassembleAnimations[it].value)Donde desensamblarAnimaciones[it].value es un valor de animación de 0 a 1. Se calcula en función de que comienza cada hora con la relajación y la duración adecuadas.

Contenidos

La animación básica

Podemos visualizar el movimiento de los puntos con este diagrama.Los puntos están animados de 0 a 1 . Cada comienza una nueva hora. Este comportamiento se puede describir fácilmente con un // currentDot es un índice del punto. val startAngle = currentDot * 30fval currentDeg = (animationAngle – startAngle).coerceIn(0f, 30f)currentDeg/30fMejoremos nuestro código con esta fórmula. En lugar de usar animaciones y canales paralelos, hagámoslo val dotsPositions = Remember(animationAngle) {List(12) { currentDot ->val startAngle = currentDot * 30fval currentDeg = (animationAngle – startAngle).coerceIn(0f, 30f)currentDeg/30f}} Y usa estas posiciones en lugar de desensamblarAnimaciones valoreshoras. forEach {if (! puntos de visibilidad[it]) return@forEachval grado = it * 30frotate(grado) {val positionY = halfStroke +stepHeight * it * (1 – puntosPosiciones[it])…}}

mejorar la animación

Como vimos en la primera animación, los puntos son este patrón Tú podrías si otro .Entonces debemos buscar algo como estoLa buena noticia es que no se requieren muchos cambios. son los . Ahora simplemente no podemos referirnos al punto final. . En cambio, debemos como queramos, para eso haremos DegreeLimit y reescribir nuestra fórmula…. val DegreeLimit = 45f// currentDot es un índice del punto. val startAngle = currentDot * 30fval currentDeg = (animationAngle – startAngle).coerceIn(0f, gradeLimit)currentDeg/degreeLimit Y veremos eso. ¡Excelente!«¡Pero todavía no es exactamente lo mismo! ¡En la animación original, tiene este toque agradable y suave al final!”, se podría decir. Y tú .Deberíamos tener algo así.Tenemos una pero entonces . En realidad, esto… se parece a un .Felizmente tiene exactamente lo que necesitamos para ello! !Al crear especificaciones de animación, agregamos un parámetro de aceleración. En animación, por lo general está estructurado así: animation = tween(duration, easing = LinearEasing) Si observamos la interfaz de aceleración, podemos encontrar una transformación de método único, que entre 0 y 1 y devuelve lo mismo con la interfaz transform.fun aplicada Easing {fun transform(fraction: Float): Float} ¡Este método es exactamente lo que necesitamos para nuestro caso! Simplemente podemos aplicar cualquier aceleración a nuestra fracción 0..1. Entonces nuestro código se ve así: val easing = LinearOutSlowInEasingval gradeLimit = 45f // currentDot es un índice del punto. val startAngle = currentDot * 30fval currentDeg = (animationAngle – startAngle).coerceIn(0f, degreeLimit)easing.transform(currentDeg/degreeLimit) ¡Así es como se verá nuestra animación! ¡Exactamente como esperábamos!¡Última animación!

Compose Animation Api nos permite especificar cualquier aceleración que queramos con un Clase.

Por ejemplo, esta aceleración CubicBezierEasing(0f,0.3f,0.2f,1f) tiene un comienzo muy rápido y un final muy lento. Puedes jugar más con las flexibilizaciones cubic bezier en este sitio web cubic-bezier.comcubic-bezier.com! En este paso lo hemos hecho eliminando la creación de subprocesos innecesarios y reemplazándolos con una sola función de interpolación.

El código completo para este paso se puede encontrar aquí

Lo prometí en la Parte 2 A esta animación con un control deslizante. Solo necesitamos eliminar la animación infinita y pasar animationAngle como parámetro. Luego agregue un control deslizante que cambie el ángulo de animación de 0 a 720Controla la animación con un control deslizante

El código completo para este paso se puede encontrar aquí

Para ser honesto, la animación inicial aparece ahora a mi 😑. Las formas cuadradas y parecen banales y poco espectaculares. Creo que podemos condimentarlo agregando .¡Versión coloreada! ¡Eso se ve mucho más interesante!

redondear las esquinas

Podemos redondear esquinas fácilmente especificando StrokeCap.Round en lugar del valor predeterminado StrokeCap.ButtdrawLine(…cap = StrokeCap.Round,…). El problema es que StrokeCap.Round necesita algo de espacio extra a la hora de dibujar, por lo que hay que tenerlo en cuenta. Para arreglar eso, eliminamos un mientras dibuja.Diferencia entre tapas a tope y redondas // En lugar de val start = Offset(size.width / 2, positionY — halfStroke) // Eliminar HalfStroke val start = Offset(size.width / 2, positionY) Lo mismo se puede hacer en otros lugares para convertirse en longitud de línea y altura de punto. Fácilmente podemos dibujar un por encima de nuestros puntos con los modos de mezcla DstOut y DstAtop. Necesitamos configurar DstOut para los elementos subyacentes y DstAtop para su superposición. // Establecer el modo de fusión como DstOut para los elementos subyacentes drawLine(…cap = StrokeCap.Round,blendMode = BlendMode. DstOut) Para colorear usamos un pincel con . nosotros también este degradado para hacer las animaciones más interesantesEn esta parte lo hicimos

  • nuestra animación con un para para distribuir animaciones.
  • También cambió de forma y agregué algunos 🌈

Puedes ver el código fuente completo de esta animación en mi G.

Nuevamente, si te gustó este artículo, me alegraría mucho que lo aplaudieras 👏👏👏. Puedes hacerlo varias veces, hasta 15 según recuerdo. ¡Diviértete programando!

Deja una respuesta

Tu dirección de correo electrónico no será publicada.