The world of animations in mobile development using React Native has been growing steadily, with the efforts of Software Mansion paving a path to the Reanimated library. This library has transformed the old, static feel of mobile apps built with React Native into more interactive and engaging applications that capture the user’s attention. Reanimated provides a structured way of achieving animations. Now, with the release of Reanimated 4, we can bring web CSS animations and transitions into the mobile development process, making it easier to create highly cool and efficient animations to integrate with your business logic.
Enough chitchat let’s get into some code example
Prerequisite set up
Let us first start of with scaffolding a simple expo project. Run the command below
expo init fireproject
After that let us use yarn to add the reanimated 4 library to our project
yarn add react-native-reanimated@next
Run prebuild to update the native code in the ios
and android
directories.
yarn expo prebuild
Fire animation
We begin by importing the necessary components from react-native
and react-native-reanimated
.
Import the common View
from react native and theAnimated
and css
are the main components that will aid in our animation. We also define constants for animation duration, the number of flames, and a color palette for our fire
import { View } from 'react-native';
import Animated, { css } from 'react-native-reanimated';
const ANIMATION_DURATION = 1500;
const FLAMES_COUNT = 4;
const COLORS = {
black: '#111217',
brownDark: '#612E25',
brownLight: '#70392F',
orange: '#FDAC01',
red: '#F73B01',
yellow: '#FFDC01',
};
In Our App
component is where we will render the entire fire animation. We create our container, the fire itself, flames, and logs. To create the flames we are using Array.from
, which creates an array from an iterable object, to generate a list of FLAMES_COUNT
elements. We then map over the array and on each flame we return an Animated.View
, allowing us to animate its properties. In the styles within the Animated.View
, we assign a unique animationDelay
to each flame, creating a staggered effect. We also alternate between flameEven
and flameOdd
animations to introduce some variation see the blow code.
export default function App() {
return (
<View style={styles.container}>
<View style={styles.fire}>
<View style={styles.flames}>
{Array.from({ length: FLAMES_COUNT }).map((_, index) => (
<Animated.View
key={index}
style={[
styles.flame,
{
animationDelay: (ANIMATION_DURATION / 4) * index,
animationName: index % 2 === 0 ? flameEven : flameOdd,
},
]}
/>
))}
</View>
<View style={styles.logs}>
<View style={[styles.log, styles.logDark]} />
<View style={[styles.log, styles.logLight]} />
</View>
</View>
<View>
<Text style={{color: 'red'}}>
Loading ....
</Text>
</View>
</View>
);
}
Now we see the magic of the CSS property from reanimated. With the variables falmeEven
and flameOdd
we are now able to define the animations using css.keyframes
. These keyframes describe how the flames change over time. They control properties like backgroundColor
, bottom
, height
, right
, width
, and zIndex
. The different keyframes create the flickering and rising effect of the flames. The zIndex
property is used to control the layering of the flames, ensuring they appear to overlap realistically.
const flameEven = css.keyframes({
'0%': {
backgroundColor: COLORS.yellow,
bottom: '0%',
height: '0%',
right: '0%',
width: '0%',
zIndex: 1000000,
},
'25%': {
bottom: '1%',
height: '100%',
right: '2%',
width: '100%',
},
'40%': {
backgroundColor: COLORS.orange,
zIndex: 1000000,
},
'100%': {
backgroundColor: COLORS.red,
bottom: '150%',
height: '0%',
right: '170%',
width: '0%',
zIndex: -10,
},
});
const flameOdd = css.keyframes({
'0%': {
backgroundColor: COLORS.yellow,
bottom: '0%',
height: '0%',
right: '0%',
width: '0%',
zIndex: 1000000,
},
'25%': {
bottom: '2%',
height: '100%',
right: '1%',
width: '100%',
},
'40%': {
backgroundColor: COLORS.orange,
zIndex: 1000000,
},
'100%': {
backgroundColor: COLORS.red,
bottom: '170%',
height: '0%',
right: '150%',
width: '0%',
zIndex: -10,
},
});
We finally have the normal styles object we use to style our components as need be only that now we pull them using the css.create
With it, we now define the layout, sizes, colors, and other visual properties. The flames
container is rotated to give the flames a more dynamic appearance. The logs
are positioned and rotated to create the illusion of stacked wood.
const styles = css.create({
fire: {
alignItems: 'center',
maxWidth: 300,
width: '40%',
},
container: {
alignItems: 'center',
backgroundColor: COLORS.black,
flex: 1,
justifyContent: 'center',
},
flame: {
animationDuration: ANIMATION_DURATION,
animationIterationCount: 'infinite',
animationTimingFunction: 'ease-in',
backgroundColor: COLORS.yellow,
borderRadius: 40,
position: 'absolute',
},
flames: {
aspectRatio: 1,
transform: [{ rotate: '45deg' }],
width: '60%',
},
log: {
borderRadius: 50,
height: '100%',
left: '50%',
position: 'absolute',
width: '100%',
},
logDark: {
backgroundColor: COLORS.brownDark,
transform: [{ translateX: '-50%' }, { rotate: '-20deg' }],
},
logLight: {
backgroundColor: COLORS.brownLight,
transform: [{ translateX: '-50%' }, { rotate: '20deg' }],
},
logs: {
aspectRatio: 6,
width: '100%',
},
});
Running the application
It is important to note that the reanimated 4 is still in beta version though it is pretty stable. A kink that needs to be worked out is that it doesn’t work with Expo Go as of now. You need to have a development build or create a release apk. To create an apk with the changes we have just added simply navigate to the android folder in the application and run
/gradlew assembleRelease
After that, the apk will be in the app/build/outputs/apk
folder. Grab that and install it on an emulator or physical device and voila
Conclusion
This example demonstrates how to create a campfire animation using React Native and react-native-reanimated
. By combining CSS keyframes, styling, and the Animated
API, we can achieve complex and performant animations in our React Native applications. This approach offers a declarative way to define animations, making the code easier to understand and maintain. This also means web developers can take their CSS skills and bring them to mobile development.
Till next time happy coding.