Easy to use declarative transitions and animations for React Native
—
Global registry system for registering, managing, and reusing named animations across your application. Register custom animations once and use them by name throughout your app.
Register a single custom animation in the global registry for reuse by name.
/**
* Registers a custom animation in the global registry
* @param animationName - Unique name for the animation
* @param animation - Animation definition object
*/
function registerAnimation(animationName: string, animation: CustomAnimation): void;Usage Examples:
import * as Animatable from 'react-native-animatable';
// Define custom animation
const myCustomBounce = {
0: {
translateY: 0,
scale: 1,
},
0.4: {
translateY: -40,
scale: 1.1,
},
0.8: {
translateY: 0,
scale: 0.95,
},
1: {
translateY: 0,
scale: 1,
},
};
// Register it globally
Animatable.registerAnimation('customBounce', myCustomBounce);
// Use by name anywhere in your app
<Animatable.View animation="customBounce" duration={800}>
<Text>Custom bounce animation!</Text>
</Animatable.View>
// Also available as imperative method
this.view.customBounce(600);Bulk register multiple animations from a definitions object, ideal for setting up app-wide animation libraries.
/**
* Bulk register animations from a definitions object
* @param animations - Object mapping animation names to definitions
*/
function initializeRegistryWithDefinitions(animations: { [key: string]: CustomAnimation }): void;Usage Examples:
import * as Animatable from 'react-native-animatable';
// Define animation library
const myAnimations = {
slideInSlow: {
from: {
translateX: -100,
opacity: 0,
},
to: {
translateX: 0,
opacity: 1,
},
},
popIn: {
from: {
scale: 0,
rotate: '45deg',
},
to: {
scale: 1,
rotate: '0deg',
},
},
gentlePulse: {
0: {
scale: 1,
},
0.5: {
scale: 1.05,
},
1: {
scale: 1,
},
},
colorShift: {
from: {
backgroundColor: 'rgba(255, 0, 0, 1)',
},
to: {
backgroundColor: 'rgba(0, 255, 0, 1)',
},
},
};
// Register all at once
Animatable.initializeRegistryWithDefinitions(myAnimations);
// Use registered animations by name
<Animatable.View animation="slideInSlow">
<Text>Sliding in slowly</Text>
</Animatable.View>
<Animatable.View animation="popIn" duration={400}>
<Text>Popping in with rotation</Text>
</Animatable.View>
<Animatable.View
animation="gentlePulse"
iterationCount="infinite"
direction="alternate"
>
<Text>Gentle pulsing</Text>
</Animatable.View>Create a dedicated file for your app's animation definitions:
// animations/index.js
export const brandAnimations = {
// Brand-specific entrance
brandSlideIn: {
from: {
translateX: -200,
opacity: 0,
scale: 0.8,
},
to: {
translateX: 0,
opacity: 1,
scale: 1,
},
},
// Brand-specific exit
brandSlideOut: {
from: {
translateX: 0,
opacity: 1,
scale: 1,
},
to: {
translateX: 200,
opacity: 0,
scale: 0.8,
},
},
// Loading animation
brandPulse: {
easing: 'ease-in-out',
0: {
scale: 1,
backgroundColor: 'rgba(0, 123, 255, 1)',
},
0.5: {
scale: 1.1,
backgroundColor: 'rgba(0, 123, 255, 0.7)',
},
1: {
scale: 1,
backgroundColor: 'rgba(0, 123, 255, 1)',
},
},
// Error shake
errorShake: {
easing: 'ease-out',
0: { translateX: 0 },
0.1: { translateX: -8 },
0.2: { translateX: 8 },
0.3: { translateX: -6 },
0.4: { translateX: 6 },
0.5: { translateX: -4 },
0.6: { translateX: 4 },
0.7: { translateX: -2 },
0.8: { translateX: 2 },
1: { translateX: 0 },
},
};
// App initialization
import * as Animatable from 'react-native-animatable';
import { brandAnimations } from './animations';
// Register all brand animations
Animatable.initializeRegistryWithDefinitions(brandAnimations);// components/Card/animations.js
export const cardAnimations = {
cardEnter: {
from: {
scale: 0.9,
opacity: 0,
translateY: 20,
},
to: {
scale: 1,
opacity: 1,
translateY: 0,
},
},
cardExit: {
from: {
scale: 1,
opacity: 1,
translateY: 0,
},
to: {
scale: 0.9,
opacity: 0,
translateY: -20,
},
},
cardFlip: {
style: {
backfaceVisibility: 'hidden',
},
0: {
rotateY: '0deg',
},
1: {
rotateY: '180deg',
},
},
};
// Register component animations
Animatable.initializeRegistryWithDefinitions(cardAnimations);You can override built-in animations by registering custom versions with the same name:
// Custom version of 'bounce' animation
const customBounce = {
easing: 'ease-out-back',
0: {
translateY: 0,
scale: 1,
},
0.3: {
translateY: -30,
scale: 1.05,
},
0.6: {
translateY: 0,
scale: 0.98,
},
1: {
translateY: 0,
scale: 1,
},
};
// Override the built-in bounce animation
Animatable.registerAnimation('bounce', customBounce);
// Now all uses of 'bounce' will use your custom version
<Animatable.View animation="bounce">
<Text>Custom bounce behavior</Text>
</Animatable.View>Register animations dynamically based on app state or user preferences:
class AnimationManager {
static registerThemeAnimations(theme) {
const themeAnimations = {
themeTransition: {
from: {
backgroundColor: theme.oldBackgroundColor,
},
to: {
backgroundColor: theme.newBackgroundColor,
},
},
themePulse: {
0: {
backgroundColor: theme.primaryColor,
scale: 1,
},
0.5: {
backgroundColor: theme.secondaryColor,
scale: 1.05,
},
1: {
backgroundColor: theme.primaryColor,
scale: 1,
},
},
};
Animatable.initializeRegistryWithDefinitions(themeAnimations);
}
static registerUserAnimations(userPrefs) {
const speed = userPrefs.animationSpeed || 1;
const animations = {
userSlideIn: {
easing: userPrefs.easing || 'ease',
from: {
translateX: -100 * speed,
opacity: 0,
},
to: {
translateX: 0,
opacity: 1,
},
},
};
Animatable.initializeRegistryWithDefinitions(animations);
}
}
// Usage
AnimationManager.registerThemeAnimations(currentTheme);
AnimationManager.registerUserAnimations(userPreferences);Organize animations by category for better maintainability:
const uiAnimations = {
// Button animations
buttonPress: { /* definition */ },
buttonRelease: { /* definition */ },
// Modal animations
modalSlideIn: { /* definition */ },
modalFadeOut: { /* definition */ },
// List animations
listItemEnter: { /* definition */ },
listItemExit: { /* definition */ },
};
const transitionAnimations = {
// Page transitions
pageSlideLeft: { /* definition */ },
pageSlideRight: { /* definition */ },
// Tab transitions
tabFadeIn: { /* definition */ },
tabFadeOut: { /* definition */ },
};
const feedbackAnimations = {
// Success feedback
successCheckmark: { /* definition */ },
successGlow: { /* definition */ },
// Error feedback
errorShake: { /* definition */ },
errorPulse: { /* definition */ },
};
// Register all categories
Animatable.initializeRegistryWithDefinitions({
...uiAnimations,
...transitionAnimations,
...feedbackAnimations,
});Install with Tessl CLI
npx tessl i tessl/npm-react-native-animatable