Welcome here at the React Native EU 2021 virtual conference. Thanks for having me again. My name is Alexander and I'm talking about animations today and how to use animations in react native that day. Beautiful that they run smooth at 60 frames per second. Even on a low end devices.
So when we are talking about animations in react native, we have to keep in mind that the general architecture of rig native can be quite challenging for running smooth animations. There are pretty good solutions out there. I want to talk about three of them today and Yeah, basically, it's the three solutions we use regularly in our company when we are working with react native applications.
And I will give a short overview of all these three solutions. And I hope every one of you can take something out of this talk, so let's start right away. When we are talking about animations. The first question we have to answer is why are we using animations? Well, first of all, they make our apps look nice, but that's not the main reason.
At least it shouldn't be, and animation should always serve any purpose. So at least they should increase the user. So for example, we could use an animation to give an advanced feedback for a touch interaction of the users. So when the user, for example, presses a button which he has to press for at least three seconds to trigger any action we could, for example, fill any bar that the user sees, okay, I have to press, press, press, press, press, and now the actions triggered So this is an example which for, for what I mean, when I say any animation should serve any purpose Another thing is progress and loading indications.
So it's always good to give the user anything that you can look at while he's waiting for the content. So progress and loading indication is a good example for an animation or where animations should be used. Also. A lot of apps. Do you scroll animations at the moment? Especially in the header area.
So when we scroll larger header is scrolled out of sight and a smaller header of course. Last, but not least animations are a great tool to grab and direct the user's attention to any part of the screen. So when something moves on the screen, the user looks at it. So animation's a great for grabbing the user's attention.
So basically you could say animations are unimportant part of any high quality app. And since we all want to write high quality apps in react native, we should have a look how to make great animations and to understand how to make great animations. We have to understate understand the challenge with animations in react native first.
So what's the problem with animation in react native? I think the part in the middle of the screen is something you all know, it's the general architecture of rig native. So we have this JS threat where we execute our written day S code. And then we have to native threat which render, which does all the rendering and gets the user interacts.
And these threats communicate via this thing called the bridge and. This is, this architecture is fine. But it can become quite a problem when dealing with animations, because when you look at the example on the left-hand side, this is basically an example. Like I described before we have emerge as a whole.
And when we scroll we slightly moved the image and the title out of the scroll view and a small header occurs, which stays a top of the image. And when we over scroll the image gets scaled. It's just normal behavior in an application or in an, in an, in a mobile app. So a lot of apps do this. So it's basically.
A pretty simple enemy. And what's the problem with the simple animation. When you look on the right hand side here is described what happens under the hood. When we work with the generator, react native architecture we get the on scroll event and the value of the scroll view every 60 milliseconds at least if we don't throttle it and we shouldn't do so, because then the animation would look quite like.
And every 16 milliseconds, we sent a scroll view over the bridge calculate the new values for our animated components sent these animated values or this, these values back to the native thread where the native thread renders the, the view. So. And this can become quite a problem because not every animation is that simple.
So there could be some, some more calculation involved. When we have a lot of calculation on the JF threat in the worst case, our JF thread becomes blocked due to all this calculation. And this would mean on the one hand, we are not able to do, to directly handle any more user input. And on the other hand it would possibly delay our animation and we would drop some frames, which then would make the animation look very messy.
And not that. So. There are some solutions to this general problem. And as I said, I will show three of them today, but before we dive into the solutions, let me just introduce myself very briefly. My name is Alexander critic. I founded my own software company here in Munich in 2002. I work with react native since 2016.
I also made some small contributions on community projects, like ASAM storage by the way it was a great experience. The guys there were very helpful. So if you've never contributed to open source, I can definitely recommend it. So just give it a try, even if it's just a very small contribution it could help us all.
So back to me, I'm also an AWS solution architect professional because I needed some knowledge for writing the backends for my app. And AWS is a great solution for desk for that. And I'm also trying to write from time to time on my medium blog. So if you'd like to, you can, you can follow me.
I'm working at my own company. It's called horizon iPhone. We are based in Munich and we are 32 people at the moment. And we focus on react and react native development. And we build cloud-based backends for our reactant react native applications. We are working with AWS, Google cloud and Azure. So we're working with all three big cloud providers.
Yeah, it's very, very good to work with the cloud providers for backends, for our apps, because it makes it very easy back to the topic. When working with animations, at least when we work with animations in our company for us, there are three ways to deal with any. The first one is the internal react native animated API which does a good job for, for simple animations.
And we'd like to work with it a lot. Second one is the great Lottie framework. There is th th th there are STKs for native integration, but also Ric native Lottie SEK. So you can, it's very simple to use, and I like it a lot. So if you have never heard of it you will be really surprised how easy it is to integrate animations.
Smooth animations running at 60 F FPS in reactive. And third of all it's the awesome reanimated framework, which recently was released in a second word. And I love to work with it. If you haven't ever worked with it you should definitely have a look at it. I think I read in a blog post lately it's the gold standard of animation and I couldn't agree more.
It's really awesome. But let's start with the internal animated API here. We see a very simple example. But it's good to explain how it works. I've taken this from the, from the official react native documentation, and as I say, it's very easy. So. We have this view, which is decorated as animated view.
This basically means dead. We can use animated values by in the styles of the view. So as you can see here, we have a generous diet, and then we have this additional style which gives a positive value. And this opacity is one animated. It's called fate. And it's just a variable, which we define.
We can name it like we want. And yeah, we give this value to the opacity. To complete what you see on the left side, we have these two buttons. It's a, the fade in, and the fade out button, which caused the fade in and the feta OD function. And this is how the declarations look like. So we have this fate and M V a variety.
Which basically we, we work with functional components here, so, and we store it as a reference and basically it's an animated value which got gets initialized with zero. And then we have to fade in, fade out function, which uses the animated dot timing to change this animated. So we give the enemy to dot timing, a defeat, an estimated value, and say, okay, please take this value and change it to one over the duration of five seconds.
And what enemy a timing does, is it calculates how the value should be in any frame in this five, six? And then it renders the value or it, it passes the value for every frame to native. So basically it's the same for a fadeout function. Except that we changed the value to zero and the duration is only three seconds.
So the fade out is faster than the faded. Yeah, it's, it's a very basic example, but I think it shows clearly how it's to LA how animation works and how is it? It is like to work with animated values because basically all animation works with this animated values. So let's come back to our scroll example from the beginning.
Basically it's the same concept. We have this scrolling there. And this growling though, you is changed, but it's not changed via animated timing function. But it's changed you to the animated event function, where, which we use to kind of couple this scrolling value to the onscreen. Event to the native on scroll event of the scroll view.
So what we are doing is we look at a native event which we get on scroll, and then we extract this Y value and coupled to the scrolling animated value. What'd you can see here in the top is basically the image and the view, which is the the small header which are cores. And basically you can see here the capacity it takes an interpret interpolated, small header, pass it to you where able we'll have a look at this later.
And. Here we transform the image, right? So we translate it with the interpolated translate where you, and we also have an interrelated scale where you where we scale the X and Y dimensions of the image. So where does these values come from? Basically, it's simple interpolation. We have to scrolling there, you which has our animated value, like in the example before, but now since we don't only want to use the scrolling value directly because it goes from zero to infinity and we don't want that.
Want to change any opacity to infinity? We do a simple interpolation and this interpolate function works very well because. We just say, okay, take the scrolling there. You, and we define an input range and we define an output range for this input range. So basically when working with this interpolated, small header opacity, or calculating this interpolated small head of opacity, we say, okay, from zero to 200, Please do nothing stay at zero.
And then when changing from 200, 202 to 220, and please change from zero to one. And what this interpolation does, is it calculates the values for, yeah. The difference growth positions and parcels this to native, same for scale. And. So when we come back here you can see this use native driver true.
And this really is a very, very important thing because what does use native driver does, is it says, please take all these logic and pass it down to two native in one call. So when we are working with using native drums, We changed the behavior of the animation from the one we've seen at the beginning to this one, we create the animation rules in our JS threat.
We S we then send this animation rules to Nate. And the native threat, Dan knows the animation rules and all calculation and all rendering is done on the native threat. So we don't have this round trip every time on every frame or on every scroll. We are processing our animation completely into Nate.
And this is really awesome because then we never block our JS threat. We can respond to user interaction. We can use RJs thread as we like. And yeah, that's why you definitely should use he was native driver when working with the animated APS. Well here, we have a little more advanced example. This is taken from an awesome YouTube tutorial on Katelyn Mirren.
I think he spoke here two years ago. And as you can see, basically, Also a flat, a scroll view or a flat list in this example. And basically it works the same, right. We have this animated event where we have the scroll value in this case is it's the X value because it's a horizontal scroll view.
We also use the native driver. And what's the difference to the example before is that we have the interpolation not on one time in general, but we have the interpolation in every item. So for every item we have an animated view, which has, is its own interpolated value. And it's very cool because it shows that This use native driver can create very performant very performance animations.
Even if we have a lot of interpolation in place. And that's only the, the, the, the lower part of the screen here, right. There is some more code for the, the image in the background and the changing of the images in the background, but just have a look I've put export snack of Katelyn neuron here.
Also you has a lot more YouTube videos on his channel, where he talks about using animation with the animated API. So would definitely recommend it. We'd like to see some more complex examples. Please have a look at this YouTube channel. So summary for animated. Basically my tips are used used native driver.
I would recommend not to use animated API without using use native driver. Basically it's just interrelating animated values. It works great with scroll view and flat list. Because then it's easy just to, to couple the scroll value to some animated value and then interpolate it. And it's best for simple and easy animations.
So now we're coming straight to the limitations because complex animations can become quite confusing and they can become a lot of code. And you are able to kind of combine animations. You can run any missions in parallel. You can run animations one after another and so on, but they become quite complex and quite confusing, very fast.
So we in our company use the animated API for simple use cases and in applications where we only have these simple use cases. Another thing, which you have to keep in mind that use native drivers limited to non layout properties. And this is a very, very large limitation. So things like transform and opacity will work, but all Flexbox and position properties will not.
So you cannot just say, okay, please change the height with our with an estimated value why using native dry. So this won't work. So after the internal react native animated solution I want to show you a framework, which I really like. And which is the basis of this animation. You see underwrite and this framework is called.
So when you look at the animation on the right side this animation would be quiet. A lot of code when we would have to script it with animated or even reanimated. So all the, these lines, which or cool one after another it would be a lot of work. So that's where Lottie is the ideal library.
Basically when you look at all these animations all what they have in common is that they are that easy to script. But with Lottie, the code for them basically is all the same. It looks like this. You have a lot of view and you have adjacent fire, which is the resource for your animation. And. This really is cool when you have the Jason fires, I wish all, you know later where these Jason fives come.
But basically it's that easy, right? This is the code for all three of the applications. Just with different Jason fires, we have container, which we center our animation in. Then we have to Lottie view. And we say, we say to the Latif, if you please autoplay and then it just works one thing, which is.
Which makes Lottie a lot cooler is that we do have programmatic control over the animation, which is defined in the Jason fire. So. Basically, as you can see here we are w we, again have a scroll view where we couple the Y where you have the on scroll event to our scrolling, animated, where you, which is defined here.
And then we have an interpolated progress which we couple, which we which we interpolate the scrolling too. And we just say, okay, Please four minus 1000 to zero, go from one to zero and from zero to 1000, go from zero to one. Basically what we're doing is we use this interpolated progress to say the Lottie view.
It should play on a. So when we scroll fast, the animation will play fast. And when we scroll slow, the animation will scroll slow. And as you again, see, we are using native driver here. So all this takes place in the native or UI threat, and we don't block our JS threat. When you look at the animation here on the left side, you can.
It does do nothing when it stays where it is. And when we use the scroll view it starts animating. And this is really cool because we can have very complex animations in this Jason files and we can control when it should play where the progress should be how fast it should play and so on. So we have a lot of control over.
And where does these animation Jason's come from? Well, basically they are after effects, animation files. So Adobe after effects is a program which is used to create animations for videos and for other things. And then there is something called the body movement plugin, which creates these Jason fires out of the after effects.
Anyway. And this is really cool because when we come to the summary there is quite a large market for these Lottie files. So there is this defies Puma com website, and it has a lot of animations, free animations, paid animations, and you can find any animators there which creates. Custom and cool animations in simply no time for your project.
And you as a developer, don't have to script your animations in your code. You can shut, just work with an, with a professional animator who creates the animation, and then you can use this animation via the Lottie react native plugin. I put the link in here and you have. At least some control over the animation programmatically.
And we use it for avatar animation. We use it for animations, which have a lot of components and we use it for animation where we don't have to have to be able to change. All of the animation in our code because that's one of the limitation we don't have full control via code. Right. We can say, okay, please play, please.
Play from, from frame 62 frame 120, but we can say, okay, this part of the animation is two, two two large, please make it smaller. This, that has to be done in, after.
So one of the limitation is you have no full control control via code. The other limitation would be, you need to create the animation fires either by hiring a designer or animator or do it yourself with after effects. After this short introduction to Lottie I want to talk about the awesome reanimated two framework.
It's the third framework we use when we're working with animations. And I think it's the most complete of all. So. To understand what happens with reanimated too. I took some code from the documentation of the software mentioned page it's basically. The idea behind reanimated basically is kind of the same, like use native driver, but it's a lot more complete.
So what they did why creating re reg native animation, they introduced something called booklets and workloads basically are parts of code, which don't run on the J S threat, but it runs on the UI thread that runs directly on the UI. So basically you can simply simply put work that string in your function.
And then when you work with react native reanimated the re reanimated babble plugin sees, okay, this is code, which should be executed on the UI thread and Ababa plugin transforms the code that is executed on the UI threat. So basically this is what I just said. Right. When we have this the scroll view example from before we have to JS thread where we create animation rules, or we create the workloads and then we have to native UI animation threat where we have the worklet context.
It's it's has its own context on the, on the UI threat. And basically. In this context, the calculation of the animation is done. But again, it's on the UI threat
and it gets, it gets even better. So we don't have to write our own workers. So react native reanimated provides us a lot of custom hooks which we can use. To yeah. To, to have it a lot simpler, to work with a re re animated or with, with animated values or with code running on the UI thread. So we don't have to, to define by ourself what is the work that, and what is not so we can.
We can just have a state of arrival or stay constant which we say, okay, use animated style. So make it an animated style. And then we can yeah, it runs on the UI thread.
Another cool thing is that we can have shared where news between our JS context and RJ, a thread and the, the native context or the worklet context, I would say. So what that means is when we're in the worklet context, we can synchronously change these shared lives. And we are also able from the JS context to, to ask them chronically change these values, this is due to the architecture, but it's really cool to be able to communicate from the JS context or JF threat to this native threat, and also be able to synchronously change the shared values inside our workloads.
So let's get this. Let, let, let, let's get the pieces together here. So again, we have the scroll view example, and as you can see here, we have a scroll that you which is defined as use shared value, and which is initialized with zero. And then we have the onscreen. Which basically is a function which M uses animated scroll handler, which is a part word which re native reanimated provides us.
And again, here we look at the on scroll event and we coupled the the Y scroll value to our scroll that you.
When we're looking at? No, I have, have to go back once. Another cool thing you can see here is that we pass this animated scroll there, you down to our item component. So we have a lot of items in this scroll view. You can see it's the, the single items here. And basically with the scroll where you pass down to the item, we can work with this shared value in the item, and that's basically what we're doing here.
So this is how the code of the item looks like. And you can see here, we have a style here and we have a title style here. And basically the title style is the style of this text. And the style is the style of the whole container. And when we go one slide further here, you can see how style and title style are calculated and basically it's look, it looks very similar to how the animated API works.
Like we use this use animated style And then we return an object which includes a style. And basically we are using again, simple interpolation here. So we are using the animated value, which we got passed down to our competitor. And we say, okay, for this input we're using the index year, which we also kept passed down to our component for this index to this index or this, this, this value to this, will you please change the size, the height of from minimal height to maximum height?
I think it's 200 to 400 pixel here. When you remember what I said about animated? Was that any maitre'd in a native context was limited to transforms and capacity, and we could not work with things like height. Well, the cool thing on reanimated is here we can. So we are able to transform our Flexbox values.
When we're coming to the title, stay here. It's also a user animated style. Only thing is that we only change the opacity here. So as you can see, when we scroll up and down the opacity of the text below the title here changes. So yeah, basically it's the same, what we did at any meters. But in the reanimated syntax, So this was a kind of a simple example.
There are a lot more complex animation possible with reanimated. There is this very, very cool YouTube general channel of William can, Dylan. He is a magician when it comes to reanimated and making animations. On his YouTube channel, he has a serious it's called Canada. Be done in react native, where he looks at the best animations from any app and builds them in react native.
Most of the time he's using reanimated and reanimated to now. So the animation you, you see on the left side here basically is swiper where you can change the screen by swiping. But it tracks where you swipe and how fast you scribe and things like that. I, I included it here. Just to give you an idea how complex this calculations of such an animation can be.
This part, I I, I paste it here on the slide is just a calculation for the wave animation here. So it's just a part of this liquid swipe example. I paced up the, the. To the full example here. So if you're interested in really cool reanimated stuff, please check out the YouTube channel, check out the GitHub, which I pass it here.
There are a lot of different examples and you get a very good idea how powerful this reanimated tool is. So to wrap reanimated up we and our company use it for complex animations. We use it. Even, we also use it for easy animations when we use it anywhere in our project, because we don't like to use animated and reanimated in the same project because it can get quite confusing.
So when we have more complex animation and we integrate reanimated into the project we use it for all animations and. My tip definitely is watch the, can it be done in react native series on YouTube? It's it's awesome. Limitations of re-animated. We're basically, there are no real enemy, real enemy.
Limitations except that it can take some time if we want to build really complex animations. So when we compare it to Latinos where you can use after effects to create your animations, this can be much faster than to write your animations in code. Well, the advantage in reanimated is you have full control.
And sometimes it's easier to just create the animation and after effects and you don't need that much control. Then Lottie is the better framework for. And yeah, that's basically what I say at the last point. Animations have to be implemented by the developer. When you have a larger team where you have someone who really has a talent for cool animations but he's not a developer.
Then Lottie is the better framework because he or she can, can, can just build the animation in after effects and then give it handed over to the developer. Yeah, to wrap this up. I made a slide with a useful links. I think I mentioned most of them. Animated has a very good documentation on the rig native page.
I really like the YouTube channel or from of, of Katelyn Miran. The Lottie library is available on GitHub or the Lotteria native plugins available at guitar on guitar and. On Lottie phase.com. There are a lot of fires and animations for free and they are also paid to animations. So just have a look.
Maybe you can find something cool there. Re animated. There are very good documentation fires on the software mansion page, they also have some good webinars available there. So you should definitely check it out if you haven't done it already. And again, I can definitely recommend a YouTube channel of William Candyland.
It's it's awesome. And to serious, can it be done in react native? It's it's really awesome. So I want to close my talk with a little quote. It's basically the same, which I said, I said at the beginning use animations where, where they improve the user experience of your app. Never use animations just because you think they are cool.
So if you're that pumped after this talk now and say, I want to start using animations now and go to lot defies.com. Take the best animations. Please keep in mind. Don't use animations just because they are cool, or if they make your epics look great they always should serve a purpose. So that's from my side.
Thanks for listening. If you have any questions about the talk or any questions about react native stuff in general, you can contact me via email or via my LinkedIn account. Thanks again for having me and have a nice conference.