Estoy animando a lo CALayer
largo de CGPath
(QuadCurve) bastante bien en iOS. Pero me gustaría usar una función de aceleración más interesante que las pocas proporcionadas por Apple (EaseIn / EaseOut, etc.). Por ejemplo, una función de rebote o elástica.
Estas cosas se pueden hacer con MediaTimingFunction (bezier):
Pero me gustaría crear funciones de sincronización que sean más complejas. El problema es que el tiempo de los medios parece requerir un bezier cúbico que no es lo suficientemente poderoso como para crear estos efectos:
(fuente: sparrow-framework.org )
El código para crear lo anterior es bastante simple en otros marcos, lo que hace que esto sea muy frustrante. Tenga en cuenta que las curvas están mapeando el tiempo de entrada al tiempo de salida (curva Tt) y no las curvas de tiempo-posición. Por ejemplo, easyOutBounce (T) = t devuelve una nueva t . Entonces esa t se usa para trazar el movimiento (o cualquier propiedad que debamos animar).
Entonces, me gustaría crear una costumbre compleja CAMediaTimingFunction
pero no tengo ni idea de cómo hacerlo, o si es posible. ¿Existen alternativas?
EDITAR:
Aquí hay un ejemplo concreto en pasos. Muy educativo :)
Quiero animar un objeto a lo largo de una línea desde el punto a al b , pero quiero que "rebote" su movimiento a lo largo de la línea usando la curva easyOutBounce anterior. Esto significa que seguirá la línea exacta de a a b , pero acelerará y desacelerará de una manera más compleja de lo que es posible usando la actual función CAMediaTimingFunction basada en bezier.
Hagamos de esa línea cualquier movimiento de curva arbitrario especificado con CGPath. Aún debería moverse a lo largo de esa curva, pero debería acelerar y desacelerar de la misma manera que en el ejemplo de línea.
En teoría, creo que debería funcionar así:
Vamos a describir la curva de movimiento como un movimiento de animación de fotogramas clave (t) = p , donde t es el tiempo [0..1], p es la posición calculada en el tiempo t . Así que move (0) devuelve la posición al inicio de la curva, mueve (0.5) el centro exacto y mueve (1) al final. Usar una función de temporización time (T) = t para proporcionar los valores de t para move debería darme lo que quiero. Para un efecto de rebote, la función de sincronización debe devolver los mismos valores t para el tiempo (0.8) y el tiempo (0.8)(solo un ejemplo). Simplemente reemplace la función de sincronización para obtener un efecto diferente.
(Sí, es posible hacer un rebote de línea creando y uniendo cuatro segmentos de línea que van y vienen, pero eso no debería ser necesario. Después de todo, es solo una función lineal simple que asigna valores de tiempo a posiciones).
Espero tener sentido aquí.
fuente
Respuestas:
Encontré esto:
Cocoa with Love: curvas de aceleración paramétricas en Core Animation
Pero creo que se puede hacer un poco más simple y más legible usando bloques. Entonces podemos definir una categoría en CAKeyframeAnimation que se parece a esto:
CAKeyframeAnimation + Parametric.h:
CAKeyframeAnimation + Parametric.m:
Ahora el uso se verá así:
Sé que puede que no sea tan simple como lo que querías, pero es un comienzo.
fuente
Desde iOS 10 fue posible crear una función de sincronización personalizada más fácilmente utilizando dos nuevos objetos de sincronización.
1) UICubicTimingParameters permite definir la curva de Bézier cúbica como función de aceleración.
o simplemente usando puntos de control en la inicialización del animador
Este increíble servicio te ayudará a elegir puntos de control para tus curvas.
2) UISpringTimingParameters permite a los desarrolladores manipular la relación de amortiguación , la masa , la rigidez y la velocidad inicial para crear el comportamiento de resorte deseado.
El parámetro de duración todavía se presenta en Animator, pero se ignorará para el tiempo de primavera.
Si estas dos opciones no son suficientes, también puede implementar su propia curva de tiempo confirmando el protocolo UITimingCurveProvider .
Más detalles, cómo crear animaciones con diferentes parámetros de tiempo, puede encontrarlo en la documentación .
Además, consulte la presentación Avances en animaciones y transiciones de UIKit de WWDC 2016.
fuente
CoreAnimation
versión deUISpringTimingParameters
(CASpringAnimation
) es compatible con iOS 9!UITimingCurveProvider
a no solo representar una animación cúbica o de resorte, sino también para representar una animación que combina tanto la vía cúbica como la de resorteUITimingCurveType.composed
.Una manera de crear una función de temporización de encargo es mediante el uso de la functionWithControlPoints :::: método de fábrica en CAMediaTimingFunction (hay un método init correspondientes initWithControlPoints :::: también). Lo que esto hace es crear una curva de Bézier para su función de sincronización. No es una curva arbitraria, pero las curvas de Bézier son muy potentes y flexibles. Se necesita un poco de práctica para dominar los puntos de control. Un consejo: la mayoría de los programas de dibujo pueden crear curvas de Bézier. Jugar con ellos te dará una retroalimentación visual sobre la curva que estás representando con los puntos de control.
Los este enlace por puntos a la documentación de Apple. Hay una sección breve pero útil sobre cómo se construyen las funciones de preconstrucción a partir de curvas.
Editar: el siguiente código muestra una animación de rebote simple. Para hacerlo, creé una función de temporización compuesta ( valores y propiedades de temporización NSArray) y le di a cada segmento de la animación una duración de tiempo diferente ( propiedad de tiempos clave ). De esta forma, puede componer curvas de Bézier para componer tiempos más sofisticados para animaciones. Este es un buen artículo sobre este tipo de animaciones con un buen código de muestra.
fuente
No estoy seguro de si todavía está buscando, pero PRTween se ve bastante impresionante en términos de su capacidad para ir más allá de lo que Core Animation le ofrece, en particular, las funciones de sincronización personalizadas. También viene empaquetado con muchas, si no todas, las populares curvas de flexibilización que ofrecen varios marcos web.
fuente
Una implementación rápida de la versión es TFAnimation . La demostración es una animación de curva de pecado . Úselo
TFBasicAnimation
comoCABasicAnimation
excepto asignartimeFunction
con un bloque que no seatimingFunction
.El punto clave es la subclase
CAKeyframeAnimation
y calcular la posición de los fotogramastimeFunction
en1 / 60fps
el intervalo de s. Después de todo, agregue todo el valor calculado avalues
deCAKeyframeAnimation
y los tiempos por intervalo akeyTimes
también.fuente
Creé un enfoque basado en bloques, que genera un grupo de animación, con múltiples animaciones.
Cada animación, por propiedad, puede usar 1 de 33 curvas paramétricas diferentes, una función de tiempo de decaimiento con velocidad inicial o un resorte personalizado configurado según sus necesidades.
Una vez que se genera el grupo, se almacena en caché en la Vista y se puede activar usando una AnimationKey, con o sin la animación. Una vez activada, la animación se sincroniza en consecuencia con los valores de la capa de presentación y se aplica en consecuencia.
El marco se puede encontrar aquí FlightAnimator
A continuación se muestra un ejemplo:
Para activar la animación
fuente