For my first post of the year I wanted to keep it light and experiment a little bit with the React Native Animated API. We’ll create a few bars that animate in and constantly change their size. Here’s what our end result will be
Please note that any choppiness is a result of recording the GIF (video at end of post as well).
Interested in giving it a shot? Let’s get to it.
All the code is available on Github but if you want to follow along here’s what you need to do to get started.
react-native init RNBarGraphExample
Then create an
app/AnimatedBar.js and copy and paste the following into them to get started.
Both of these files are very simple and will result in a light blue screen in your app (nothing else). Give them a quick once over to understand what’s going on.
Finally, we want to actually use these files in our app — to do so replace
index.android.js with the following.
Final step, which is purely convenience, is to install
randomcolor via npm.
Before we can render anything, we need some data. We’ll keep this very simple and create 10 data elements with a width between 0 and the screen width — this will all take place in
With this when our component mounts it will create 10 elements of varying widths. Now let’s quickly create some static bars so we can start seeing things. In
app/AnimatedBar.js we’ll just set some static styles and apply them to our view.
Note that the background color for each bar is coming from the state, which will be a random color and persist between any re-renders of that components. You should see something like this now
Your colors will vary.
Cool — we see something! But it’s boring…
So now we want to animate the bar width when it’s first rendered. It’s visually pleasing and a quick win. To do this, we need to create a new animated value in
app/AnimatedBar.js and then use that value to dictate the width of our bar.
With that our bar would always have a value of 0 so now we need to animate it from 0 to the value you pass into the
AnimatedBar instance — we’ll do this in the componentDidMount in
AnimatedBar . We’re leveraging the
Animated.timing function to change the value from 0 to the value passed in. You could also use
Animated.spring if you want to.
This function takes our animated value as the first parameter and a configuration object as the second. Initially the width is 0 and we’re telling it to gradually progress from 0 to X (where X is the random width value passed to the component via props). You should now see something like this when reloading the app.
What we did above can be a bit busy — there is a lot going on at once. Let’s set it up to cascade down with a slight delay between rendering each bar, shall we?
If you remember from earlier, we’re also sending a delay to our
AnimatedBar which is simply a static number (100 in this case) * the index of that value in the area. Therefore the delay for the first element is
100 * 0 = 0 , the second is
100 * 1 = 100 , …,
100 * 9 = 900 . So the first element will start immediately and the last won’t start until nearly a second later.
With that in mind let’s use the delay value! Again we’ll be working in our componentDidMount and, in addition to
Animated.timing , we’ll be using
Animated.sequence , and
Animated.sequence allows us to sequence various animation functions and
Animated.delay just lets us delay successive animated events.
Animated.timing actually has a delay option you can pass that does the same thing and is more succinct but I wanted to experiment with different functions to learn about them, and share with you.
So you can see here that we’re passing an array of Animated functions to Animated.sequence which will call them in order. For the delay we’re using the delay that was passed to the component.
And here we see the same animation as before just cascading down with a slight delay between each! Simple change but I think it adds a lot to the animation…. and we learned more APIs!
Right now our app only renders when the data is initially loaded — for many applications this will be adequate but let’s have a little more fun and have it constantly updating. The core animation is in place already — we just need to abstract some of our
AnimatedBar code to also run when the component is updated. We’ll create a new function for that and call it when the component is first mounted as well as when componentWillReceiveProps is called.
Great! Now we’ll set up an interval to generate new data every 1 second.
And there we have our full animation! Below is a video that better shows the movement
Want to see some real world applications of animations in React Native? Sign up for my free React Native course!
Questions/comments? Let me know in a response and be sure to recommend this post!