Video Summary and Transcription
This talk is about animations in React Native, specifically focusing on React Native Reanimated. It covers the use of interpolations and extrapolations in animations, animating items in a carousel or list, sticky elements and interpolation, and fluidity and layout animations. The talk provides valuable tips and tricks for creating performant animations and explores the use of math formulas for natural movements.
1. Introduction to Animations in React Native
Welcome to this talk about animations in React Native. Whether you're a newcomer or an experienced developer, this talk will help you learn how to animate your static UI and provide valuable tips and tricks to level up your skills. Learning by doing can be challenging, but it's a crucial part of the learning process. By expanding your knowledge through hands-on experience, you can reach new heights.
Hey, and welcome to this talk. I'm really nervous to be here in front of you. Not because I will be giving a talk, but because I'll be talking about a subject which is really close to my heart and that's animations in React Native. And animations in general. You see, I have applied with this talk because I see the struggle in this community, especially coming from newcomers that they would like to animate their static UI, but they don't know how to actually get started with. But also from experienced developers that don't know how to level up their skills.
So the goal with this talk, and by the end of this talk, if you're a newcomer, you'll know how to animate your static UI. If you're an experienced developer, you'll look at things with different eyes or from different perspectives, and I'll show you some tricks and tips that will definitely level up your skills.
We're engineers or certain developers, and we don't think that we understand something unless we can build it. In this process, I like to call it learning by doing. It's funny because a while ago I was doing a code application and I came by this amazing code by my friend Aristotle, and it's saying that for the things we have to learn before we can do them, we learn by doing them. I'm a self-taught developer and learning by doing is not a fun process. From time to time you'll struggle quite a lot. You like to give up, and you feel that you know nothing about what you're doing. But it's okay, this itself is a learning process. There's a learning curve but with incremental steps you reach the peak. Well that's because the best solution that you currently know is based on your existing knowledge and for you to expand that knowledge and learn new ways of doing it, you learn by doing it.
2. Introduction to React Native Reanimated
The entire talk is about React Native Reanimated, which empowers developers with tools to create fast, easy, and performant animations. Shared values, derived values, animated styles, and props, interpolation, and animated reactions are the key primitives in Reanimated. Interpolation is particularly important when animating values from an input range to an output range.
The entire talk is going to be around Reanimated or React Native Reanimated. And I believe that this library, React Native Reanimated, is going to empower you with amazing tools and capabilities so you can create delightful experiences really fast, easy and performant. I believe that Reanimated opens the gates for creating amazing animations, it eliminates a lot of roadblocks and is solving 99% of performance issues and is going to let you focus more on things that matters the most, and that's creating pleasant illusions through animations and increasing user experience.
My name is Catalin Miron, I am currently helping others to succeed. You can follow more about my work, you can follow me on twitter using mironcatalin as twitter handler. So, let's start by setting up the ground foundation of this entire talk and start talking about reanimated primitives which I believe are the most critical one to master eventually. The first and by far the most important one is to use shared values. Shared values can carry data and provide a way to react to changes and also drive the animation and it's also important that it's reactive. This data is stored on the UI thread but can be also accessed from the JavaScript side as well hence the name shared. It can be a number, it can be a boolean, a string, an object, an array.
Use derived value is when you'd like to create a new value based on a shared value. In this example I'm just adding 100 to an existing shared value so whenever that value is going to change this derived value is going to change as well. Use animated style is used when a style attribute will need to update based on a shared value or this style attribute depends on a shared value. In other words it's a reactive style sheet. The counterpart of use animated style is use animated props. For non-style attributes in this example I'm animating a stroke with but I can also do it for a path. Interpolate is going to let you remap values based on an input range and output range. You can also have interpolate color is the same as interpolate but for colors as output ranges in this example I'm morphing between red and blue. Of course you can animate those shared values by using timing, spring and decay. You can delay those animations, you can repeat those animations, you can sequence them or go crazy. You can repeat reverse a sequence of animations with an initial delay. If you're using gesture handler you can also listen to some events by using useAnimate gesture handler or if you're using scroll view or flat list or any scrolling components you can use animated scroll handler and listen to those events and if you're just interested in the onScrollEvent you can use the shorthand notation and just get directly the event that's coming from that onScrollEvent. Last but not least is use animated reaction. It's useful if you'd like to set state or call some API's or do something else on the JavaScript side and how it's actually using it's receiving two different methods. One is for the preparation, it's informing the animated reaction what shared value it's interested in and the reaction of that is going to receive the result and the previous value and you can do whatever you'd like to do.
Now that we have set up the ground foundation and what are the most important primitives in my opinion that reanimated exposed, now let's talk what matters the most when coming from outside world or you'd like to animate something. In my perspective the most important one is interpolate. Interpolate is a function that will remap an animation value from an input range to an output range. And yeah it's a method, it's going to accept a shared value, it's going to accept an input range, output range. Extrapolate left and extrapolate right and in case those two extrapolations are equal you can use the shorthand notation.
3. Interpolations and Extrapolations in Animations
By default, the extrapolation in animations extends beyond the defined ranges. Interpolations in animations can estimate values outside of the given ranges. To limit the animation within the defined ranges, you can use the clamp function.
And this is optional and by default the extrapolation is extend and you'll see in a minute what extend actually means. Let me give you an example. I have here a component, I'm initializing a used shared value starting from 0, I'm animating that shared value whenever this component is going to be mounted. Yeah the fancy animation and I'm applying some styles by using use animated style I'm interpolating that value, I'm passing an input range 0 and 1 and the output range 0 and 100 and I'm applying it to a translate x, finally the most important part is to add those styles to an animated view or animated component and this is how it is going to look like, x is going to move from 0 to 1 and the interpolated value or the translate x in our example is going to move from 0 to 100. You see when I'm dealing with interpolations, I would like to represent them visually in my head as a graph. So let me give you a sense of how that graph may look like in my head. So for the input range I have a line with different values, in our example 0 and 1 and for the output range I will have another line from 0 to 100 and yeah in a nutshell whatever we have written in code in my head it's this graph here and interpolate is trying to estimate the numbers between those two ranges and as I mentioned previously the extrapolation by default it extends, that means that interpolation can estimate the numbers outside of or beyond those ranges. So in case when the input range or the value itself is going to be 2, the estimated value is going to be 100. If you not interested in outside world of this range, you can clamp the animations or you can clamp it on the left or clamp it on the right.
4. Animating Items in a Carousel or List
The index-1, index, and index plus 1 problem arises when animating items inside a carousel or a horizontal/vertical list. To animate these items, you need to initialize the scroll X as a shared value, create your own scroll using an animated scroll handler, modify the scroll X based on the listener event, change the flat list to an animated flat list, add the scroll event, and pass the scroll X to the carousel item. By accessing the index and scroll X, you can use interpolation to apply style changes. The formula for interpolation is index minus one multiplied by the width, index multiplied by the width, and index plus one multiplied by the width. Finally, divide by the carousel item width and you'll have an interpolation with an input range of index minus one, index, and index plus one.
The next problem which a lot of us are confused about or don't get it right initially is the index-1, index and index plus 1 problem which it's going to be apply when you'd like to animate something's inside carousel or in an horizontal or vertical list. Let me give you an example. So I have here a flat list that's horizontal and it's going to have paging enabled and I'm rendering a carousel item. Nothing to fancy here. So this is how it's going to look like, right. Because I have paging enabled it's going to snap on each individual carousel item because each item has the screen width as the width size and how we can actually animate those. Well the first thing that you need to do is to initialize the scroll X in our example because it's a horizontal list as a shared value, create the own scroll using use animated scroll handler and modify the scroll X based on the event that's coming on that listener and finally change the flat list to be an animated flat list, add the own scroll event and now pass the scroll X to the carousel item and nothing should be visibly changed but now each carousel item has access the scroll X position and what we can actually do with that, well we can interpolate the value and apply some style changes. In this example I'll apply a different opacity but the most important part to pay attention to is the interpolate because we have access the index and the scroll X we have this formula kind of. So let's take a closer look to the interpolate method here So we have an index minus one multiplied by the width, index multiplied by the width and index plus one multiplied by the width. Well index minus one it's actually the next item or the item that's coming or moving to the right the index plus one is the previous item or the item that's going or coming from the left and of course the index is the current value. So it's exactly the opposite way of thinking, kinda. Now of course since we are in a reanimated world we can apply math and we can divide it by the carousel item width and just clean up the code. So we'll have an interpolation with an input range index minus one, index and index plus one. Nothing should be visible again because just we will have the active carousel item index as a shared value.
5. Sticky Elements and Interpolation
You're not limited to just a single style change. Sticky elements have three types: sticky after, sticky before, and sticky bottom. The position of the item is always relative to the scroll viewport. The interpolate method handles the estimations for sticky elements. The graph shows the specified ranges and calculated values. The second example offsets the item with its minus Y position. The sticky bottom example calculates the initial position of the item. The interpolate method ensures the item is visible on the viewport.
You're not limited to just a single style change, in this case I'm applying a different scale based on the scroll exposition but you can of course use interpolate color and apply a different color for each individual item based on where it's going to go to. So if it's going to the left I will be applying magenta, if it's going to the right I will apply gold. And notice that everything is running at 60FPS or 120FPS depends on your device capabilities but everything is running on UITread, which makes this really performant.
Last is what I would like to call it an interpolation exam and when you know how to do sticky. What I mean by sticky is the following. So there are three types of sticky. It's a sticky after, when the sticky element top edge is equal to the viewport top edge or sticky before, when the top edge of the element is the top edge of the viewport and sticky bottom. It's sticky initially but when the bottom edge of the sticky element, which is the bottom edge of the viewport is going to move along with the scroll. Just before moving further, you need to understand two different things. The first one is the position of the item is always moving in relation to the scroll viewport, that's because the item is relatively positioned, not absolute positioned. And the second one is it's important to find when the sticky element is visible inside the screen or inside the viewport either using a top edge or a bottom edge. We have a scroll view here and I'm just rendering a sticky element randomly positioned inside a scroll view otherwise it's just a dummy element.
And for the first example I'm getting the Y value, basically the Y position inside that scroll for the sticky element and I'm interpolating the scroll Y and it's saying when the top edge of the element is reaching the top edge of the viewport I'm compensating the movement by one. You see by just passing the input range and the output range I'm basically specifying the range that I'm interested in and for shaping this movement and interpolate is going to do the rest of the estimations. Now let's see, let's take a look at the graph which I have also presented in the previous slides. So as you can see I'm just specifying three different parts where I'm interested in and the rest is calculated by the interpolate method. Yeah I'm just leaving everything in the hands of interpolate to do the estimation of the values.
The next one is basically the same but this time I'm moving the item by offsetting it with its minus Y position so it's always going to be visible right at the top but when the top edge of the element is going to reach the top edge of the viewport I'm going to move it with the scroll. I'm also adding a minus 1 and 0 just because on iOS for example you have bounces so you can move below minus 1 with the scroll Y value. So yeah again this is how the graph is going to look like. I will just specify the range that I'm interested in and the rest is going to be calculated by the interpolate method.
Last it's a sticky bottom. The only it's basically the same as sticky before the only trick here is that I'm calculating the initial position of the item. In this case I'm compensating with its minus Y so it's at the top then I'm adding the screen height. Now it's at the bottom and I'm subtracting it's height. So it's always visible at the bottom of the screen. And notice that there is a scroll Y value. And the reason for that again is the item is positioned relative is not absolute. So I need to always compensate the scroll Y position. And it's just a matter of finding the sweet spot where this item is going to be visible or this interpolate method it's basically saying be sticky until the item is fully visible on the viewport.
6. Fluidity and Layout Animations
Next, we'll explore fluidity in animations using math, specifically the ArcTangent formula. We'll apply this formula to create natural movements for a ball and a balloon slider animation. Layout animations in React Native allow for easy creation of mount and unmount animations, with pre-built options and customizable modifiers. These animations can also be used for shared element transitions.
Next, let's talk about fluidity and how we can create natural movements using math. One example is using the ArcTangent formula, which calculates the angle between two coordinates. In this case, we have a ball that moves randomly on the screen, and arrows pointing to it. Each arrow receives the ball's x and y coordinates as shared values and integrates its own x and y using the onLayout event. The rotation angle of each arrow is calculated using the ArcTangent formula. This allows the arrows to always point towards the ball, creating a fluid and natural movement.
Now, let's take a look at applying the same formula to create a natural movement for a balloon slider animation. The balloon indicator receives the x value of the knob as a shared value and uses the ArcTangent formula to calculate its rotation angle. To introduce a delay in the movement, we can use the Springify function to apply a spring animation to the x value. By using math and formulas, we can achieve smooth and natural animations without hard-coding angles.
Layout animations are another powerful feature in React Native. With layout animations, we can create mount and unmount animations for animated components. Reanimated provides 78 pre-built animations, such as fade in, zoom in, and bounce out. These animations can be customized with modifiers like duration, delay, and springiness. Layout animations make it easy to create delightful and dynamic animations, especially for mounting and unmounting components. Additionally, layout animations can be used to create shared element transition animations by specifying the same key for animated views.
Comments