Animaciones
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
La biblioteca Animated está diseñada para crear animaciones fluidas, potentes y fáciles de construir y mantener. Animated se centra en relaciones declarativas entre entradas y salidas, transformaciones configurables entre ellas, y métodos start y stop para controlar la ejecución de animaciones basadas en tiempo.
El flujo principal para crear una animación consiste en crear un Animated.Value, conectarlo a uno o más atributos de estilo de un componente animado, y luego controlar las actualizaciones mediante animaciones usando Animated.timing().
No modifiques el valor animado directamente. Puedes usar el Hook useRef para obtener un objeto de referencia mutable. La propiedad current de este objeto se inicializa con el argumento dado y persiste durante todo el ciclo de vida del componente.
Ejemplo
El siguiente ejemplo contiene una View que aparecerá y desaparecerá gradualmente basándose en el valor animado fadeAnim:
Consulta la guía de Animaciones para ver ejemplos adicionales de Animated en acción.
Resumen
Hay dos tipos de valores que puedes usar con Animated:
-
Animated.Value()para valores individuales -
Animated.ValueXY()para vectores
Animated.Value puede vincularse a propiedades de estilo u otros props, y también puede interpolarse. Un solo Animated.Value puede controlar cualquier número de propiedades.
Configuración de animaciones
Animated proporciona tres tipos de animaciones. Cada tipo ofrece una curva de animación específica que controla cómo los valores cambian desde su valor inicial al final:
-
Animated.decay()comienza con una velocidad inicial y disminuye gradualmente hasta detenerse. -
Animated.spring()ofrece un modelo básico de física de resortes. -
Animated.timing()anima un valor a lo largo del tiempo usando funciones de easing.
En la mayoría de casos usarás timing(). Por defecto, emplea una curva easeInOut simétrica que transmite la aceleración gradual de un objeto hasta velocidad máxima y concluye desacelerando progresivamente hasta detenerse.
Trabajando con animaciones
Las animaciones se inician llamando a start() en tu animación. start() recibe un callback de finalización que se ejecutará cuando termine la animación. Si la animación finaliza normalmente, el callback se invocará con {finished: true}. Si termina porque se llamó a stop() antes de completarse (ej. por interrupción mediante gestos u otra animación), recibirá {finished: false}.
Animated.timing({}).start(({finished}) => {
/* completion callback */
});
Usar el controlador nativo (native driver)
Al usar el controlador nativo, enviamos toda la información de la animación al entorno nativo antes de iniciarla, permitiendo que el código nativo ejecute la animación en el hilo de UI sin pasar por el puente en cada fotograma. Una vez iniciada, el hilo de JS puede bloquearse sin afectar la animación.
Puedes usar el controlador nativo especificando useNativeDriver: true en tu configuración de animación. Consulta la guía de Animaciones para más detalles.
Componentes animables
Solo los componentes animables pueden animarse. Estos componentes únicos enlazan mágicamente los valores animados a las propiedades y realizan actualizaciones nativas específicas para evitar el costo del proceso de renderizado y reconciliación de React en cada fotograma. También gestionan la limpieza al desmontarse, siendo seguros por defecto.
createAnimatedComponent()puede usarse para hacer un componente animable.
Animated exporta los siguientes componentes animables usando este wrapper:
-
Animated.Image -
Animated.ScrollView -
Animated.Text -
Animated.View -
Animated.FlatList -
Animated.SectionList
Composición de animaciones
Las animaciones también pueden combinarse de formas complejas mediante funciones de composición:
-
Animated.delay()inicia una animación después de un retraso dado. -
Animated.parallel()inicia varias animaciones simultáneamente. -
Animated.sequence()inicia animaciones en secuencia, esperando que cada una finalice antes de comenzar la siguiente. -
Animated.stagger()inicia animaciones en secuencia y paralelo, pero con retrasos sucesivos.
Las animaciones también pueden encadenarse estableciendo el toValue de una animación como otro Animated.Value. Consulta Seguimiento de valores dinámicos en la guía de animaciones.
Por defecto, si una animación se detiene o interrumpe, todas las demás animaciones del grupo también se detendrán.
Combinación de valores animados
Puedes combinar dos valores animados mediante suma, resta, multiplicación, división o módulo para crear nuevos valores animados:
Interpolación
La función interpolate() permite mapear rangos de entrada a diferentes rangos de salida. Por defecto extrapola la curva más allá de los rangos dados, pero también puede limitar el valor de salida. Usa interpolación lineal por defecto pero admite funciones de easing.
Lee más sobre interpolación en la guía de Animaciones.
Manejo de gestos y otros eventos
Gestos (como desplazamientos) y otros eventos pueden mapearse directamente a valores animados usando Animated.event(). Se hace con sintaxis de mapa estructurado para extraer valores de objetos de evento complejos. El primer nivel es un array para mapear múltiples argumentos, conteniendo objetos anidados.
Por ejemplo, para mapear event.nativeEvent.contentOffset.x a scrollX (un Animated.Value) en gestos de desplazamiento horizontal:
onScroll={Animated.event(
// scrollX = e.nativeEvent.contentOffset.x
[{nativeEvent: {
contentOffset: {
x: scrollX
}
}
}]
)}
Referencia
Métodos
Cuando se usa ValueXY en lugar de Value, cada opción de configuración puede ser un vector {x: ..., y: ...} en lugar de un escalar.
decay()
static decay(value, config): CompositeAnimation;
Anima un valor desde una velocidad inicial hasta cero basado en un coeficiente de decaimiento.
La configuración es un objeto con opciones opcionales:
-
velocity: Velocidad inicial. Requerido. -
deceleration: Tasa de decaimiento. Por defecto 0.997. -
isInteraction: Determina si esta animación crea un "manejador de interacción" en elInteractionManager. Por defecto true. -
useNativeDriver: Usa el controlador nativo cuando es true. Obligatorio.
timing()
static timing(value, config): CompositeAnimation;
Anima un valor a lo largo de una curva de easing temporizada. El módulo Easing tiene curvas predefinidas o puedes usar tu propia función.
La configuración es un objeto con opciones opcionales:
-
duration: Duración de la animación (milisegundos). Por defecto 500. -
easing: Función de easing para definir la curva. Por defecto esEasing.inOut(Easing.ease). -
delay: Inicia la animación después de un retraso (milisegundos). Por defecto 0. -
isInteraction: Determina si esta animación crea un "manejador de interacción" en elInteractionManager. Por defecto true. -
useNativeDriver: Usa el controlador nativo cuando es true. Obligatorio.
spring()
static spring(value, config): CompositeAnimation;
Anima un valor según un modelo de resorte analítico basado en oscilación armónica amortiguada. Rastrea el estado de velocidad para crear movimientos fluidos cuando se actualiza toValue, y puede encadenarse.
Config es un objeto que puede tener las siguientes opciones.
Nota: Solo puedes definir una de estas combinaciones: bounciness/speed, tension/friction, o stiffness/damping/mass, pero no más de una:
Las opciones friction/tension o bounciness/speed coinciden con el modelo de resorte en Facebook Pop, Rebound, y Origami.
-
friction: Controla el "rebote"/sobreimpulso. Por defecto 7. -
tension: Controla la velocidad. Por defecto 40. -
speed: Controla la velocidad de la animación. Por defecto 12. -
bounciness: Controla la elasticidad. Por defecto 8.
Especificar stiffness/damping/mass como parámetros hace que Animated.spring use un modelo de resorte analítico basado en ecuaciones de movimiento de un oscilador armónico amortiguado. Este comportamiento es más preciso y fiel a la física subyacente, imitando la implementación de CASpringAnimation en iOS.
-
stiffness: Coeficiente de rigidez del resorte. Por defecto 100. -
damping: Define cómo debe amortiguarse el movimiento del resorte debido a la fricción. Por defecto 10. -
mass: Masa del objeto unido al extremo del resorte. Por defecto 1.
Otras opciones de configuración:
-
velocity: Velocidad inicial del objeto unido al resorte. Por defecto 0 (objeto en reposo). -
overshootClamping: Booleano que indica si el resorte debe sujetarse sin rebotar. Por defecto false. -
restDisplacementThreshold: Umbral de desplazamiento desde el reposo bajo el cual el resorte se considera en reposo. Por defecto 0.001. -
restSpeedThreshold: Velocidad a la que el resorte debe considerarse en reposo (píxeles/segundo). Por defecto 0.001. -
delay: Inicia la animación después de un retraso (milisegundos). Por defecto 0. -
isInteraction: Determina si esta animación crea un "manejador de interacción" en elInteractionManager. Por defecto true. -
useNativeDriver: Usa el controlador nativo cuando es true. Obligatorio.
add()
static add(a: Animated, b: Animated): AnimatedAddition;
Crea un nuevo valor Animated compuesto por la suma de dos valores Animated.
subtract()
static subtract(a: Animated, b: Animated): AnimatedSubtraction;
Crea un nuevo valor Animated compuesto por la resta del segundo valor Animated al primero.
divide()
static divide(a: Animated, b: Animated): AnimatedDivision;
Crea un nuevo valor Animated compuesto por la división del primer valor Animated por el segundo.
multiply()
static multiply(a: Animated, b: Animated): AnimatedMultiplication;
Crea un nuevo valor Animated compuesto por la multiplicación de dos valores Animated.
modulo()
static modulo(a: Animated, modulus: number): AnimatedModulo;
Crea un nuevo valor de Animated que es el módulo (no negativo) del valor Animated proporcionado.
diffClamp()
static diffClamp(a: Animated, min: number, max: number): AnimatedDiffClamp;
Crea un nuevo valor Animated limitado entre dos valores. Utiliza la diferencia con el último valor, permitiendo cambios incluso si está lejos de los límites, comenzando a ajustarse cuando se acerca nuevamente (value = clamp(value + diff, min, max)).
Es útil con eventos de scroll, por ejemplo, para mostrar la barra de navegación al desplazarse hacia arriba y ocultarla al bajar.
delay()
static delay(time: number): CompositeAnimation;
Inicia una animación después del retraso especificado.
sequence()
static sequence(animations: CompositeAnimation[]): CompositeAnimation;
Inicia un array de animaciones en orden, esperando a que cada una termine antes de comenzar la siguiente. Si se detiene la animación actual, no se iniciarán las siguientes.
parallel()
static parallel(
animations: CompositeAnimation[],
config?: ParallelConfig
): CompositeAnimation;
Inicia un array de animaciones simultáneamente. Por defecto, si una animación se detiene, todas se detendrán. Puedes modificar esto con el flag stopTogether.
stagger()
static stagger(
time: number,
animations: CompositeAnimation[]
): CompositeAnimation;
Las animaciones en el array pueden ejecutarse en paralelo (superpuestas), pero se inician secuencialmente con retrasos sucesivos. Ideal para efectos escalonados.
loop()
static loop(
animation: CompositeAnimation[],
config?: LoopAnimationConfig
): CompositeAnimation;
Repite continuamente una animación dada, reiniciándola al finalizar cada ciclo. Funciona sin bloquear el hilo JS si la animación hija usa useNativeDriver: true. Nota: los loops pueden impedir que componentes basados en VirtualizedList rendericen nuevas filas durante la animación. Usa isInteraction: false en la configuración hija para solucionarlo.
La configuración es un objeto con opciones opcionales:
iterations: Número de repeticiones. Por defecto-1(infinito).
event()
static event(
argMapping: Mapping[],
config?: EventConfig
): (...args: any[]) => void;
Toma un array de mapeos, extrae valores de cada argumento y llama a setValue en las salidas mapeadas. Ejemplo:
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {x: this._scrollX}}}],
{listener: (event: ScrollEvent) => console.log(event)}, // Optional async listener
)}
...
onPanResponderMove: Animated.event(
[
null, // raw event arg ignored
{dx: this._panX},
], // gestureState arg
{
listener: (
event: GestureResponderEvent,
gestureState: PanResponderGestureState
) => console.log(event, gestureState),
} // Optional async listener
);
La configuración es un objeto con opciones opcionales:
-
listener: Listener asíncrono opcional. -
useNativeDriver: Usa el controlador nativo cuando es true. Obligatorio.
forkEvent()
static forkEvent(event: AnimatedEvent, listener: Function): AnimatedEvent;
API avanzada para interceptar eventos animados pasados mediante props. Permite añadir un nuevo listener JavaScript a un AnimatedEvent existente. Si animatedEvent es un listener, fusiona ambos; si animatedEvent es nulo/indefinido, asigna directamente el nuevo listener. Usa valores directamente cuando sea posible.
unforkEvent()
static unforkEvent(event: AnimatedEvent, listener: Function);
start()
static start(callback?: (result: {finished: boolean}) => void);
Las animaciones se inician llamando a start() en tu animación. start() acepta un callback de finalización que se llamará cuando la animación termine o cuando termine porque se llamó a stop() antes de que pudiera finalizar.
Parámetros:
| Name | Type | Required | Description |
|---|---|---|---|
| callback | (result: {finished: boolean}) => void | No | Function that will be called after the animation finished running normally or when the animation is done because stop() was called on it before it could finish |
Ejemplo de inicio con callback:
Animated.timing({}).start(({finished}) => {
/* completion callback */
});
stop()
static stop();
Detiene cualquier animación en curso.
reset()
static reset();
Detiene cualquier animación en curso y restablece el valor al original.
Propiedades
Value
Clase estándar para impulsar animaciones. Típicamente se inicializa con useAnimatedValue(0); o new Animated.Value(0); en componentes de clase.
Consulta la API completa de Animated.Value en su página dedicada.
ValueXY
Clase 2D para animaciones bidimensionales, como gestos de arrastre (pan).
Puedes obtener más información sobre la API Animated.ValueXY en la página dedicada.
Interpolation
Exportado para utilizar el tipo Interpolation en Flow.
Node
Exportado para facilitar la verificación de tipos. Todos los valores animados derivan de esta clase.
createAnimatedComponent
Convierte cualquier componente de React en animable. Se utiliza para crear Animated.View, etc.
attachNativeEvent
API imperativa para vincular un valor animado a un evento en una vista. Siempre que sea posible, prefiere usar Animated.event con useNativeDriver: true.