React Native Reanimated 2 - a webinar by Krzysztof Magiera

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Documentation improvements is a must here. Half it it isn’t even completed

👍︎︎ 9 👤︎︎ u/krolyat 📅︎︎ Jul 09 2020 🗫︎ replies
Captions
this is self-invention Academy our second webinar it's going to be about Riya reanimated person - I'm Christopher mogera I work at soft mention I've been involved in various the react native products here at supplement should be meeting mobile related efforts here and previously I've been I part of react native core team at Facebook left a couple of years ago been doing reg native since then so we have as a company a lot of expertise in reg native specifically been working on many open-source projects you might have heard of gesture handler or react native screams and also reanimated in particular so three weeks ago we released a second version of reanimated and this webinar is to discuss what are the changes do a showcase of the API and also discuss some internals so so yeah so I'm Christoph there's my twitter handle over there it's with k triple Z and F and yeah let's let's start maybe so there are rules during this webinar and yeah the first rule is that there is this question button next to the chat window so whenever you want to ask question um then use that button it will actually like create a actual question that we can then browse through because I cannot be keeping up with the chat throughout the presentation so just use that button when you when you ask a question and I'll try to go over some of them at the end and an answer so it should be somewhere over there and then the second rule is that animation presented here are smooth humor actually and not see that because of the very very betrayed of the video stream but they you need to trust me that let's move and the last rule is that you should stay hydrated because if you are on the non-owner side of the globe there is summer approaching so yeah drink water you know I wanted to use this opportunity also to before we begin to bring to your attention the black lives matter movement if you have heard of it if you haven't heard of it you should definitely google it or just search on Twitter for this hashtag so black lives matter movement aims to put an end to racial injustice in any particular to frequent incidents of u.s. police violence that costed many people's lives so there are there ways in which you can help even if you don't live in the US and you can check my pimp pass on Twitter for a good place to start so that was just this one slide at all that ok let's move on to animations so I want to start by giving some context some animations I hope I mean I'm sure that's like lots of people here who've joined are familiar with the concept of animations in drag native but I just wanted to start by adding some context here so when it comes to animations we often refer to several different types of them and in particular in react native we can distinguish between animations of individual properties like for example rotation on the left or animation layout animations so the difference here is that with live animations we're not actually changing we are also changing an individual property in this in this case on the right hand side we are changing the size of the block but as a result this site impacts how other items are positioned on the screen positions on the screen and when we press the button they are actually animate into the place where they should be at the end of the animation so I'm sure you're familiar with the react native architecture and know that and our two distinguished threats in back native and dy threat and the JavaScript threat so in case of that type of animations where you are doing fire and forget so you're actually tapping a button and then the animation starts and ends at some point in this in this case the action is initiated on the JavaScript side but the animation can run fully on the UI thread the problem with JavaScript thread is it actually has a lot of a lot of tasks to do it it has it actually runs the whole react code your application logic and maybe parsing data doing network requests and stuff like that so there are times where this vet is busy and when it comes to animations you don't really want any delays so we want them to run smoothly and you don't want them to be interrupted by some slow meanness in your application logic code so so in this type of animations we're doing fire-and-forget we can initiate the animation on the JavaScript side run them on the UI thread and they can run smoothly because on the UI thread and the main responsibilities of that is actually render the UI and not do other things in reg native but what happens when we are actually mixing animations and interactions so in that case you have just the simplest example is where you have a block that you want to pan around the screen so on the left hand side or actually on both phones you can see this small dialogue on top and which shows you I and J SFPs those are like two rectangles to drive so first is UI fps and the second is J's FPS on a second phone on the right we wear purpose we were dropping the J's face frames to 20 or 30 around that and then just to show that there is a problem with handling interactions so the problem comes from the fact that this is not a fire-and-forget type of anime so what happens here is that we actually need to receive an event in this case touch event and then react to that event so we we are updating the UI as a result of that touch event so whenever nagaihas is free and it doesn't do much work and it's running at 60 fps then there is no problem but as soon as we are hitting some issues on the JavaScript side and then this actually slows down our interaction um so there's a solution to that um it's been introduced in 2016 it's cognitive gesture under one of the libraries that we published and first version went out in 2016 I think and the solution is that we want to handle that event on the UI side and in order to do that we need we would have a declarative way of defining how the event properties map to the properties that we used to render render the views so in this case we've had a fine gesture hand in a gesture event which is a event handler for touch events we will map and the translation of the gesture to the translate x value that we then use to to map to the actual property of that blog that we have on-screen but another problem starts where we actually want to do something more fancy so let's say that after the gesture is over we want the the block to snap to some place we're using animation so for for that second part we actually can use the fire-and-forget animation because this will this will no longer be interactive so what we do in that case is that we add another handler which is called to the pan gesture header and we add on handler state change and when the previous state was active which means that you were interacting with the blog and and that and that process ended we won't spin up a new animation using spring to animate to some point in this case this is zero so two value is zero and we start in the spring and want to animate translate eggs so the problem here is that this actually requires and that javascript roundtrip so this event needs to be processed by the JavaScript thread because it actually runs JavaScript code we don't have a declarative way to to describe this one even though we can do that when the gesture is active so what happens when there is a low J's fps is that you can turn around this view and then whenever you you release it it will actually like like a little bit before it actually starts the animation so I hope you can you can see that so yeah I said at the beginning that all the animations are smooth but this one in particular is not smooth so you have this moment of when when this block is actually stuck and in some place and it doesn't yet started animating so the solution to that was basically to make everything declarative so that's essentially what we did were three animated in 2018 and when we release first version so we decided that yeah let's make everything declarative so we could have both the event mapping process being declarative and the decision what happens when the gesture is released it can also be so I was just describing that in whren animated one we decided to make everything declarative so yeah you don't really need to understand this code and animated one and but what what it does in the sense is it it gives you a full description of what happens with that blue box when you're running it around and then releasing so what happens then is that when you release it we would actually like start animation and if you start a new gesture in it which means that the the gesture state is active and then we would follow the finger so here you would be able Ram it and when you were you are able to um and describe exactly that so have conditions like for example what should happen when industries active and what should happen when you release the finger and yeah and when when to start the the animation and with free I made that one you you could go really far with with that approach and a great thing a great example are all Williams chameleons videos it's fantastic channel so I was actually thinking I'm just like playing one of his videos for this for this workshop but ended up actually making out my own slides but I'm sure you enjoy his content I really recommend it so so yeah so so we could really go very far this isn't this was like one of and most complicated examples and I've found in his in his on his channel but even though you could go really far and was still complicated so there are some core issues like initialization cost which means and that in in case where you would actually have a lot of a lot like your your gesture or interaction description was like really long and I've seen cases where you would use like two thousand elements and in to describe a interaction and that was actually not not very frequent but it still would happen the initial cost was big because you would need to run all those methods and then each of those methods will actually generate some piece of description of that interaction and that description needed to be passed over to the UI so so you would actually hit the communication overhead and because we need to communicate between JavaScript and the UI so which time you would render it was often a case that a lot of new elements were being created and then you needed to to pass that information to UI generating like communication overhead on top of on top of previously night so you would pay that cost in initialization and then frequently also during the rear rear Enders and and we we did some attempts to mitigate that problem so for initialization costs we we introduced a procedural notes and I was Last Samurai thing and to address the communication overhead we've been attempting to rewrite the old code that would rely on the react native bridge for the communication 2jsi which means we would use sort of direct c++ method calls and that didn't end up well i mean we haven't seen like a huge improvements in that area and on top of that there was a problem with the learning curve so the problem with the learning curve was that it was actually very difficult to learn and to use be animated we've got over 65 methods in the API most of them are like pretty small but still like every single thing you need to do you need to use a custom made method for that so on top of that that like writing those interactions in this like completely new and different approach so so yeah the code would look like that and it was like it really difficult for many people to adjust to that new way of thinking um even if you knew Lisp or Carter Si and do it then it was still like difficult and you will end up like losing your mind and you're just watching in this code happening and I got first you would be like this but then it would actually turn into this and you would actually end up your head would end up exploding after a while I'm for watching that so many people find it difficult and it was one of the biggest following so we could have found find a finer wise or we could have invest in in ways of resolving other two problems that I mentioned but this one was like really difficult to address and we ended up figuring out that we just had to make reanimated different to make it better so when we are at it let's go back and discuss the learning curve so a learning curve describes like how difficult it is to learn a new technology so when you're learning new things it some that the card stock starts flat so at the beginning it's difficult you're spending a lot of time and not making a lot of progress but then the process accelerates and at some point you're reaching a place where you're very confident and understanding know that technology and this is perhaps for many and what happened with JavaScript so you'll learn JavaScript it's actually pretty easy language to learn the learning curve isn't like really flat or steep however you rotate the idea axises but but you learned that and this is like a tool that you have and you can use that tool to write react native code in in the JavaScript thread but you cannot use it on the UI thread so whenever you wanted to actually execute the code on UI thread you either need to with react native specifically you either need to learn like native objective-c or Swift or Java or coughlin and and somehow bridge to that native code or you would have to learn reanimated DSL to take the kid back so we figured why not use that tool that we have that that JavaScript knowledge that we all have and try to run it on the UI thread so javascript is single friend it and that there ways to to do that so on the web for example there they're working frets there are animation work lights so inspired by that we decided to create our own our own type of work lights and we call them via mated worklets so work let's allow you to execute code JavaScript code on the UI thread and and the perfect basic block for work let's or methods because you can call methods and they have code so they're perfect and I'm module for four more clients essentially so here on the Left we have a JavaScript method and on the right side we have a worklet so the difference is that we have this work light directive at the beginning of it and on the left hand side we have Java method that you can just define any react native app code and it runs from the react native a thread and on the right hand side it's almost the same method you can define it also in your react native app code and it runs on the react native a spread but it also can run on the UI thread um so since we choose methods as a model for worklets there are nice things that comes with that so here is how you can execute a given worklet on the y thread so we use run on UI method you pass a worklet and then you call it and that's it so let's think about method is that you can pass parameters so here you yeah previously there was no parameters in the method but you can add one and then use it inside of worklet so worklets can also call other worklets synchronously on the wire friend so here they call something method calls make by method and it doesn't leave the UI thread it's executive synchronously so the and it also can return something so pi returns a number and then we can use it number and from call something this is pretty simple stuff i hope they can also capture local variables like for example and then make PI method captures this PI variable and actually also in the previous example we we've seen an example of capturing because the call sampling method captures the magpie in order to call it lighter and whenever it's executing yes so worklets can also call regular javascript methods so those methods in that case will be actually executed on the react native java spirit and not on the UI thread so we're click can call not a work LED method it could pass arguments to that metal as well um so yeah you can swing basically do anything you want and in fact console.log is not a work light it's actually a method on the react native javascript phrase so whenever you call console.log from there won't worklet it will actually execute that method on the Java on the react native JavaScript which gives you nice benefits like the yellow boxes and and also all this console statements being printed to to the package or Metro bundler sorry yeah so we can do a quick wrap-up of the knowledge about worklets so we can call the right code from read negative and vice versa it's it's really easy to use because those are just methods so we have that run on the wide lapper in order to call it work left and you can call the react native J's methods without anything special you can access local scope for those methods so they can capture local scope when they're called they can also capture other work let's execute those work lights you can pass parameters either way either to do react native joyous red or to the UI thread so the aim for us was to to make this home work seamlessly and actually it's seamless to the point where you would actually really forget about work you are going to forget about that work the directive and we can even play a game where because you would you will rarely hear a word worklet till the end of this presentation from me so whenever you humor that whenever I say work like I'm gonna drink this water here but it will rarely happen so I hope you will forget about we're close before we hit the end and just take advantage of that being very simplest be integrated into into your app so all that we had endless possibilities we could design the API any way we wanted so we set them some constraints we decided that they reanimated to API needs to be human friendly which basically means that or maybe as opposed to the the animated one API where and the goal wasn't really to provide a user-friendly API the goal was to provide a baton at building blocks for for anyone to build like some higher-level IP eyes for animations and that was our plan from the beginning when we designed we animated one and but it ended up actually being more widely used so people use that directly which wasn't really convenient because it wasn't really designed to be convenient we free animated to we we decided to approach it differently we want this framework to be batteries included we want it to be friendly for you and have all the items that are necessary like for example animations that are going to be that are a first-class citizen now with the animated one there wasn't really concept of animation you you had a barely a notion of time there so you have that if you're familiar with reanimated there was a concept of clocks that you could use clocks to sort of build animations on top of that but on the library per se didn't have a No of animation in it yeah I talked about learning curve and and beside JavaScript many people know react so we should be following similar patterns as in react that people are familiar with like for example unidirectional data flow and yeah we wanted the gesture integration to be very tight it was difficult and two years before I made it one because we were actually doing using this abstract concept of events so we we didn't actually directly interact with the gesture system but we animated would interact with the event system and the event system would and the gesture system would also interact with the event system and that was sort of a proxy which introduced another layer for people to learn and another complexity with that so we want you wanted more tighter integration because most common use cases were actually gesture and based for gesture event-driven interactions or scroll event-driven interaction so they're not that many type of events and there is no really a need to generalize it and we wanted to make the second person backward compatibility compatible so that you can actually use both animated one code and then we made it to code so that you can make them migrate it so the migration process is smooth you can you can do incremental migration you can migrate some of the elements in your app and you you're not obligated to migrate everything and at the end we decided to write the core and C++ um just because just to for it to be like more future-proof and be more portable we've ended up getting 20x reduction in the platform-specific code because of that so most of the the code is actually written in C++ and the code base size of readmitted to is five times smaller when when when speaking about the core so now I'm gonna be describing now I will do a showcase for the API and we will talk about the pike in four sections so first we will talk about how the view are updating and how we can have the views within your API how we manage animated state how we handle animations and again we'll talk about events so starting from updating views yeah so when it comes to that when writing back native components and this is what you may see quite often so you have a component in this case animated view and you have some styles so in this case you have styles written in line and there is wave hi I can color whatever some styles so what you can do instead I'm writing them in line you can decide hey those styles are actually static so let's export them somewhere and write them in a stylesheet and then you can actually move them into a stylesheet and then use a starship difference in this case it Styles dot box to assign a style to the view that you had what people were what some people don't know is that you can mix static styles and styles with an inline this way so you're actually instead of passing a single object to this style property you can pass an array and in array an array can have any number of items and each item can be either a style sheet element or a object dynamic style in this case so this way you can sort of have a distinction between the static styles and styles that you might actually want to animate in reanimated 2.0 we introduced a new API that is called use animated style and it is designed to describe the animated part of the styles so we've use animated style you import that from a limited package and then you you can use it the same way as you would use static styles for the objects so the resulting element is actually behaves as a style object and for use animated style you pass a method to it and that method should return styles that will be assigned to that view to that view so so you sort of button bind the style object to the view and then describe the Styles using the the method provided to use animated style and there is there's no magic here so far at least and we could have used just like a regular style here but yeah this is just marker that those are studying and those could be animated but those are not animated yet but the trick is that and the user amidst a method is a worklet and yeah that's time to drink some water yeah so this means that the code that we pass in that method can actually be executed on the - so it has all the properties as we have seen earlier so so this is not we are not actually taking advantage of that just yet in this example and and in order to do that I will need to learn about managing animated state so by that for the animated style and state in animated Capano we are introducing the concept of shared values current values have three key roles so one is the first one is to carry data second one is to provide reactiveness and third is to drive animations so by that what we mean by that so for carrying the data we mean that those values can contain some data in it they can be it can be modified and can be written and we can do something in order to create a shared value we use another hook that we introduced in reanimated to API it's called use shared value and you call that hook with a initial value and if you are familiar with react native animated shared values are conceptually very similar to animated values so the one of the most important distinction is that they can actually create any type of data not only numbers and strings but they can carry objects RS and like everything almost it doesn't really make too much sense in some cases to to put anything else there but you theoretically can - I mean in particular - to store like some very complex structures day so when when initializing sure the value you pass a initial value to it and then as I mentioned earlier you can read from the value and in order to to read the current value of that strength value I use a value attribute of it so we always do progress dot value in this case and you cannot just use progress because progress is a object and and it's the same way of writing so in order to update the chart value you do publish the value and then assigned to it they're called shared values because you can read and write from both UI and react native is stripe so that's why they're called comes child because they are actually introducing a notion of shared memory so shared value are reactive they're providing reactiveness as I mentioned earlier and for that to work there is nothing actually needed for that to work because and this is all happening automatically as I mentioned the method that is provided to you you say method style is to work left which means that it can run on the UI thread and it can also access the shared value there so here we are creating an animated site that actually reads from the shared value and it multiplies the value by 100 in this way it assigns it to the translate X attribute of a few that is and this that is defined below so now the volume is not really changing but what's happening is that the shared values are reactive and in particular in particular and use animated style worklet it's also reactive which means that whenever it uses some current value it will be updated whenever that value changes so what we can do now is we can try to update the progress so we add the button in unpress we are updating the value and then once the volume is updated that will actually result in the animated style method being executed again and the styles for the view are going to update and this this will all actually happen on the UI thread so so the the whole like rendering process will be skipped in this case so we're just avoiding the the reactive lender in order to provide faster ways of updating the UI so here is how it would actually work so you have a button and whenever you click on it it chooses some random progress then this progress is multiplied by hundred and that actually results in the translate X so the the square can move on a screen so you sign mated style is a reactive cook and there are some other reactive cooks actually one more only thankfully and so the second one is called use derive value and use the right value returns a shared value that is synchronized to some computation based on other values so in this case we can recreate a translate X the rise in value and this derived value will always be synchronized to the progress so the right value can be derived from multiple sources it doesn't necessarily just need to be one in this case we are only using progress but it can actually use many multiple choice values in Kosovo it comes to derive it from other derived values so here we create translate X as a multiplication of progress x value x hundred and then we use translate x shared value in the animated style below instead of using progress directly so derived values are pretty useful for cases where you want to want to hide some implementation details from from child components so in the parent component you can use some internal state yeah I'm gonna be referring to shared values of an estate because they they're just like reminding me of a react State the only difference is that it actually updating those don't actually trigger rerender so so you can have some internal state in a component of internal shared values and then when you want to pass some information to children to take some action you can you can use derived value to hide some implementation details so this is that's the the most common use case for for the derived value alright so so yeah we this is just the same code here so we have a button we whenever we press on it we update the progress value to some random number and the progress goes from 0 to 1 because math.random returns numbers from 0 to 1 then we multiply it in the derived value and then we map that the right value to the translate of the box so this way it actually jumps to new locations each time we click on the move button so yeah so we haven't so far discussed anything about animations but I mentioned that animations we wanted to make animations to be a first-class citizen this is the same code here and we are making immediate updates to the progress value and in order to make animations at first-class citizens we we been thinking a lot of how to structure it so that it's very easy and seamless to use and we decided to introduce the concept of animation signers and one of those is called with timing so when when assigning new value instead of assigning an actual number like for example the randomly chosen number you can wrap that assignment in with timing which is one of the method of we made it to API and this will actually make the process of obtaining being smooth so what would happen here in is that instead of progress being updated immediately to the end value it will actually smoothly animate from the current position of it to the the randomly selected one so when we click on it instead of that box jumping to the end location it will actually animate using some timing curve of course you can customize animations there so for the timing in particular you can provide the duration you can provide using regular things as I also available in other animation libraries another animation another value assignor is called web spring which makes the value to animate using spring physics so here's example of using spring so instead of with timing you just do with spring candid and makes the updates animate using the spring physics and Aniyah the great part of that is that those animations are interrupted and by that what I mean by that is that whenever you update the value while the previous animation is still ongoing it won't wait till that animation is ended but we'll do it we'll start from the exact point that we in which we are at so - in order to to see that we actually need to tap much faster so you can see that like whenever we tap it actually start changes the intended direction immediately so the animations are fully interruptible i that shared values are driving animations so we can easily start animations but you can also control the process of those animations so there is method for cancelling animation and whenever you access the value property it will actually get you the current status of the value so when you're I'm aiding the progress it will be you select some like target value but then before it actually hits that target it will have some intermediate state and when you read the value you will actually get that and current position each time you you access the devalue property so can you have essentially full control over that animation when you when you start in this way with animations we also have the concept of animation modifiers so one is called delay and it makes the animation provided as a second argument to start with some delay so here we use delay and past 300 milliseconds and then just have the same with spring with a random number on it so this makes the spring start with a 300 millisecond delay what's great about modifiers is that they're also interruptible which may not be like very obvious but it's it's pretty interesting actually concept because when you have when you have a delay and you press and then there is some portion of time that the light takes and then animation starts then you press again and there is some delay and then animation starts but what happens when you're pressing faster so when you press faster and there is a chance that you press like very close to the end of the animation in which case the animation shouldn't be interrupted and because there is this delay and only then the new animation kicks in so in this case you will actually see any interruption and that if you are tapping even much faster than this you hit a point at which when you press the delay and the delay is over it will like still the previous animation will be still ongoing so in this case we interrupt the animation and start from them there is another modifier called Luke and when you use look then the animation will just do a loop so go to the target point and then back using the same animation so Luke takes a second argument which just means the number of loops when it's negative it's actually infinite so this way can you can implement like rotating things for example and the best part about modifiers is that they can be mixed together so we can for example have a delay delight loop with timing so this is how it looks like and this is how it works so this is all about animations for now and we'll move on to pending events so I said at the beginning that we wanted a tither integration with the gesture system so when you're using gesture react native just your handler this is how you this is how your code might look like so you would have a pan gesture handler component and and for that component you here pass a undershirt event handler this kind there is a method and that takes an event and can do something with that event so in this case we're just comes from logging that event yeah and we've reanimated too we decided to a hoop that specifically sort of specifically designed to handle case where you're handling events for just your handler objects and this hook is called use animated gesture hender this is how it works so it's actually instead of just getting a method it gets an object of methods and and the possible properties and the one that that is actually going to be most frequently used is called active its property in that object takes a method which is an event handler and that method is actually a worklet so thanks to that we even handler and I can actually run completely in the UI thread and skipping all the JavaScript communication so here we have animated gesture handler handler and we pass it the same way as we would pass a regular method to punish your handler so we use understood event attribute and we pass the result of the resulting the result of the hook and that is the animated yes your handler all right so what happens here is that in that event handler we are making some comp dates to to a share the value that we defined above so we are defining translate X shared values and then we're making updates and the on active event handler so let's see how it would look like if we also define a animated state for it for this component so we define animated state which Maps the translated acts shared value to the translator its attribute of that view and any and then we have animated view in this past that animated style and as one of the style properties so going back to the animated gesture handler hook so what happens here is that we are assigning and the gesture event translation X attribute to the translate x value so this is a little bit problematic here as you can see on the on the video on the right because whenever the gesture starts the translation X of a gesture starts from 0 because gesture doesn't really know that you have already moved that block so when you start the gesturing with actually jump to 0 and then continue from there so runner to avoid that you would actually need to to maintain some context for whenever you're handing this gesture and and yeah and we have an API for that so the handlers passed to it provided the newest animated gesture hender and they take event as a first argument and they also get context as a second argument context is just like an empty object you can use it for anything you want but the thing about context is that it will be shared between each of the gesture States so before we only have a non-active handler defined and but we can also have on start and they're defined so on start kicks in whenever we start the gesture and we use that on start Handler to remember the initial position of the box in in the context so we we do context start x equals translate x value and this way we will remember where where we started the gesture then we can use in the context to offset offset the box when we're planning a run so in one octave handler we're actually reading from the context and we're getting the event translation as well so this way we can you know we can pan around the box we can leave it at some place pick up from the same place pretty simple yeah so let's do something more fancy let's do some animations then so and what we will do now is at the end of the gesture we want this block to come back to the initial position with animation so for that we can use yet another attribute of use animation just your Handler and you can define on end handler for it and so on and we will do something that we learned earlier essentially start an animation for the front sight x value so what happens now is whenever we drop we start stop interacting with the box it will animate with spring to the initial position I hope you can see it on the on the animation and the great part about this is that this interaction is also interruptible so whenever you so so what we can do here is like before the animation the spring animation is complete you can start planning again I hope you can see it on the animation but you can start planning and will actually I start from that exact point where you when you work where you grab the element so we don't need for the animation to finish and just because you're reading the current status of the translate X value whenever the gesture starts so this essentially results in the animation being stopped and yes so so as I mentioned earlier for events we have to tie alert methods in the API so one is called use animated District handler it works with any type of gesture from the react native gesture handler library so with pan rotation pinch tap everything and we also have a second method Tyler for hemming scroll events which is called use I made a scroll handler so you can use it with scroll views flat latest section list I'm not going to be focusing on the second one so please refer to the accommodation on that I just didn't have time for for this part the last thing I wanted to discuss today is using going again back to the use animated style so when we released we animated - I've been getting most of the questions just about use animated style and many people were asking like why is it actually a method because like most of the time we are actually mapping some attributes to that here's why can we do this use it the same way as we would do with and with all animated to assign attributes to properties and my answer to that is that you should actually think of his animated style in the same way as you think about the render method in react so in render method you can also just render children and pass all the properties to that child component and it's in many cases it makes sense and but it's just much more powerful than isn't that so we can you can do plenty of other things and I prepared some examples to show you that so first because you see animated style has a method which is just a JavaScript you can do string formatting in it so this is also just a JavaScript code you can format a color in it if we have a mapping sort of solution then you would would need like a special sort of methods for for doing this kind of stuff and like the API surface would be much bigger and more complex so here is simple JavaScript you return an object you can do formatting and anything with those values in there and the second coolest thing about use animated style is that you can actually use animation cycle animation designers in it so if you remember in the example from the beginning before yeah just the names of the properties were different and that here we have offset shared value and in use animated style we map offset to translate X and then we have a button which just sets the offset value to something random times hundred so we would get that blue box just travel to random destinations on the screen when we tap on the button so before we were actually using the animation assignment we use my with timing or with spring directly whenever we update the value but instead of using it that way you can actually use it directly in the user animated style so what you can do is essentially just wrap the the offset value with whip spring for example so the reason of that is essentially the same and but you sort of move the control of like how the style behaves from the place where you sort of have your business logic to the place where you have a style render method so this just feels like more natural for me to have this description in this one place so the outcome is exactly the same so you essentially whenever the offset changes instead of the translate X being updated immediately to the target destination when I made using some animation so everything here works the same way so we can use animation modifiers like delay or loop and you can use timing with any primers you like you can write your own animations if you want so everyone everything just works the same way here in the animated style so the second example is yeah the same and the same thing again as before we have this box that we want to pan around and then when we release it it would stab to the initial position but say we want to make it a little bit more fancy and whenever you grab this item we want the box to get a little bit bigger I hope this is something that you can notice and because it scales up a little bit when you grab it and then it scales down when you release it and that scaling process is also animated so how we can implement that using use animated style here's how so what you would do here and what I would do here is I introduce another state item so yeah like obviously you can you can have another trend value property that describes the scale of the element and then whenever you start animation of the translated X you can also start the animation of the scale and but let's let's think about some different concept so instead of keeping a scale as a Fed value let's just keep state that this coke is panning so whenever and we start the gesture we will set it to true and whenever we end the gesture we set it to false so the value is true whenever and we are actively interacting with the box this makes it pretty easy to use in this animated style because now we can now we can oh there's some error in the code here doesn't matter just a different ordering like the scale and translate should being should be two separate objects and doesn't matter and but yeah simply you you use the spanning here and whenever the panning value is true then we will use the scale will be like one point two and otherwise this curl is zero we can also wrap everything using word spring so whenever the scale updates it will actually be I made it but that's very simple way of just making this a nice interaction and yeah earlier huh earlier I I said that it's difficult to notice that this this object might gets a little bit larger and so so let's actually use that expanding state to something else as well so we can for example change the opacity of of that box so this is very simple we don't really need to change anything in the gesture handling lodging anymore because we are not we now know whenever the gesture is active thanks to this spanning state if we if we actually instead of doing that define a scale that's a shared value we would need to do that for every individual element and that we want to animate so so here we are taking the approach where like smaller amount of items in our state is better so we try to make the state a small in in terms of length number of elements as possible and then derive everything else from it and so here we can also we just reusing a spanning to two minute manage capacity so whenever we whoops this is a wrong wrong commission actually but the opacity can change us along this cow while the register is active now we can do a little bit a little exercise so what would happen if we also yeah just quick reminder here the translate X wasn't animated but what if we wrap it in web spring yeah I hope someone gets it but I don't really see a chat right now and by what would happen now is that you would have this bubela effect whenever you pan so the the box wouldn't really follow the finger directly and you will always have that sort of spring delay of the items so you can yeah this won't work this way and this is because the translate X animated value will follow the gesture directly so it will actually follow the finger whereas the style of the element will be delighted by that spring that we define and let's move on to another example this is actually one of the samples borrowed from William and we have it in the example folder can be animated repo so this is this nice tap tap bottom tap interaction and whenever you there are a lot of things happening here actually and but let's focus on one thing I'll actually run it in slow motion for you so there are a lot of things happening when you're changing taps so this yeah this this sort of that thing moves from from the previously active tab to the new active tab then there is this circle icon that animates down of the active tab and the new circle icon animates up and also like some of the icons that are on the top they like shifts a little bit down and fades away when when we're moving through them sort of so let's focus on that circle icon for now and what happens here is that when we change the active tab what we want to do is we want to animate out the previously active circle and then animate in and the currently active circle and what's important here is that whenever we start changing the tab the the active circle should start animating immediately but the second circle should animate with slight delay so let's see how this can be done so we would have a tab component and in it we will have icon style users you see animated style and the tab component will take active index and index and so we can use those two indexes to determine whether the current tab is active or not so in animated sound we can calculate is active attribute based on those two elements and then we can calculate Y offset for the circle icon so when the component when the tab is active we want the y offset to be zero so it should be on the top and when the top it's not active it should be offset by 80 pixels down so yeah so here's what would happen if we if we do it this way so we know that we now see in the animation that the the circle doesn't go down or app because it actually just immediately changes from one icon to the other because one of the icon immediately changes to offset to zero and the second icon immediately changes its offset to heidi so just here quick flip and then yeah and it falls so what would happen if we add refining here so when we add with timing we'll actually see them flip so you see the active icon would would animate down and the sorry the previously active iconic animate down and then newly active icon will animate up so that's nice but it's not still it's not ideal because the newly active icon and it animates too soon it starts the animation too soon so we would actually like to delay that nearly as nearly active icon animation a little bit and we can do it with modifier so we would use the delay modifier and then we can pass different delayed based on effective so whenever the new icon is active we want to delay its animation by 150 milliseconds and if it's not active then we wanted the animation to start immediately so this is essentially with what happens here and I also put a wrong condition so I'm sorry but it should be the the final one here the last example I think and it's also one of the examples we had we have in the repo this one's been contributed by Daris a duck and onion and it allows you to swipe away Steve Jobs for example oh and other people as well and so so there are two elements of this interactions here so first is just swiping which we are not going to be focusing now on and the second one is deleting the item so when we delete the item it swipes it slides away but it also that the row also collapses so we have two animations here we're animating translation and we're animating height sorry so the simplest approach would be to have two shared values translate X and height and then when we are removing and the row then with animate the translate X and we I made hype so the problem here as I mentioned earlier is that like in this case this is not like the minimum the minimal set of state that we can keep so we can easily derive height from translation because when we start the translation animation we can we can tell like how much the height should also come how much the rope should actually collapse and by that so this is not particularly useful for this case and but if we have more properties that we animate and then it becomes more more useful that we're not actually keeping the minimal set of state elements and in deriving everything else from it so when we do that what we can do is just have a translate X as a state and then when you remove the item we just start the animation of that translation and then in this animated style what we can do is derive the height so we can do some calculations in order to determine like what should be the height when the translation X passes like minus 200 pixels and this is our threshold and then after that threshold is chuck it should start collapsing and reach some point at some point reaches 0 so this calculation will be a pretty complex we can use interpolate for that that will make it a little bit easier but we can also take another approach we can instead of having a height as a state we can keep removing to be a state and then whenever we remove an element we would assign to that the moving state and just make it true any and you say made this style is just a method so it doesn't necessarily need to have one return statement it can have multiple return statements those witness statements can return different objects and they don't mean to have like the same set of keys every time so in order to describe this animation when we when we would do is that whenever the object is removing we're on the high to animate to zero and we want the transfer to animate to something very small and like minus 500 for example and otherwise if the item is not being removed then we want the height to be 78 and we want the transform the transfer to follow the gesture so here is how you can solve it and in this way you can sort of have all your Styles logic compacted in one place instead of that being scattered throughout the component code so we've spent a lot of time talking about the API and times up and I wanted to talk a little bit about architecture and internals just focus on four thanks here and so the first thing is plugin ii JS executor charge memory and choreographer so under the hood and reanimated who uses a babel plugin this bubble plug-in searches for worklets oops weather whenever it finds the word clip it changes it a little bit to allow us to load the workload code into a secondary JavaScript virtual machine that we run on the UI thread so this bubble plugin turns this into something more or less like that so what we would meet from a worklet fork from a method that this worklet we want to need its content its body thanks it's code so we put a string attribute and then assign this string version of that code to it and we also calculate the closure unless so this actually contains all the elements that are not defined in that method that are used from the outside so we need we need that closure then in order to define reactive worklets and also to provide everything you need from the context so we would copy both the worker code and the elements that that work with uses from the scope yeah as I mentioned the J's executor is something we use a JSI API for so we we used a side to a secondary J SVM on the UI FET and we use that VM to work the rockwork let's code using that string representation and we also load a little bit runtime code and for things like the animation animation appliers to work and all that other stuff for things like shared objects or shared values and for reading writing we use there's this cool API in JSON it's called host object which is essentially works the same way as a proxy object in JavaScript but you you can implement everything in C++ so you you have a way to to to respond so it's respond to getting an element or writing to element the core is written in C++ and JavaScript and we have a little bit of JavaScript runtime and a lot of the animation code is written in JavaScript so this way we can make updates over the year for the code because everything is just keep in the same bundle so so there is no there is no we don't have like a concept of secondary but bundle as you would have with worker threads for example which is pretty nice because you can easily my just swap out and the whole thing you know you can make updates to the reanimated core even as long as those are not C++ updates and but yeah theoretically possible so the notion of shared memory is implemented using three concepts and we have frozen objects we have mutable objects and remote object frozen objects are most common and those are just things that you use from the scope inside of the worklet so whenever whenever we see something that is assigned to closure and we know that this might be needed by the work that executed on the wife and so we need to copy it somehow to the the secondary j/s yeah we use JSI for that so there's no bridge traffic for copying the subjects in those those objects are frozen so we cannot really modify them because if you if we allow for modifications there is yeah so there is like essentially some performance penalty you would hit so we whenever we use frozen objects we we can safely assume that and those are not going to be modified and we don't need to really take care about synchronizing those on the other hand mutable objects allowed to be modified so this is how the shared values are implemented so we have ways to synchronize and I data between between UI and plain JavaScript thread and lastly we have becomes about free objects which are just optimized for being solely modified on the UI thread so remote objects allows you allows the JavaScript the main react native JavaScript thread to keep a reference to an object that lives on the UI VM so you cannot really meet from it or write to it but do you have a reference so you can pass it around to other workers that you're pounding from from the dais from the main JavaScript thread so the remote objects for example are used to keep the gesture gesture from their context that's one of the use cases and finally choreographer so how the way is how we are updating the UI so in each frame we do three steps and we'll run the event runner and event mother runs event worklets which then in turn can update some shared values I'm sorry executing my gesture hinder events or scroll events or any events view that you subscribe to and the second step is to actually run the all the remaining worklets and we need to sort them topologically in order to to make sure that the updates are happening in the correct order I'll talk about it in a second and the last part is just updating the UI once we have all the values calculated so the topological order gives us guarantee that like we can we can set we can create a graph of connections between shared values derived values or style animated styles and there is a particular order in which those updates to be run because some styles or standardized values will well where we use other values so we need to calculate those values first and only then calculate styles so in that graph we create this graph on the in memory and we keep track of like which values are dirty Markus dirty and only calculate them - to optimize the the update process oh yeah we're okay yeah we're very close to the end so just a quick overview of like what's happening next we'll be working on some optimizations black fixes bug fixes yes we are not going to be making any more bugs hopefully and what support is a important priority for us so we want we want to be able to run the community web hopefully like X X Pro support is also like very important to us hopefully we will do our best to make it in the next release that can really promise a much better yeah we are hopeful and we will it's definitely a priority for us to make it available for all the users in Expo will be adding ways to synchronously call methods from the UI thread and in particular two methods that we find very useful in many cases is measuring the view dimensions and controlling this call will be also doing some improvements in documentation and finally we should thank for all of that so the project's been supported and brought to you in cooperation from Shopify and software mentioned and those to Denton ones work on it very hard so two main developers behind the reanimated to come on Carl and this guy over here hey yeah and that's it so how to learn more about being mated to and follow stuff you mention as W mentioned on Twitter and objects come all those two accounts we'll be posting more updates and we'll be posting more information about next webinars so hopefully that we opportunity for you to learn more stuff about reanimated and not only because we will be also hosting other webinars that are not about green misses so so yeah read the documentation we have refreshed the commentation website our announcement post link is here check out the example app in the project they're a couple of interesting examples including the ones that I showed today there is a playground app repo and that we created because because of the fact that we we use turbo modules and every I made it to the setup is pretty complex so you just want to get a fresh react native project that have been animated to installed just use reanimated to playground repo and of course check Williams YouTube channel great content he already has a few videos on we I made it too and that's it I think we can do questions if you still have time and want to you hang around thank you let's start from the first one over there be spring animation for the animated transition yeah so one thing that we I made it to as an address yet are the transitions that we introduced a year ago so we have some plans about that but I can really say too much about that for sure for now because I don't want to make any promises so so yeah so we I made it too doesn't really like touch the aspects of the transitions API that we introduced so you can sort of implement transitions because because you can you can use the animated API for that but but yeah but we're not making any updates to to the transitions to reanimated transitions API okay let's take this one like an example some reanimated to calling worklet functions from touchable with Conklin event does it work in UI thread or it crosses bridge once yeah when you well when you have the touchable it actually crosses the bridge because and the touchable gives us the Jes responder system so to handle events using the native data booth you would actually need to receive those events in JavaScript and only then you can start executing something on the UI but I click interactions don't really suffer from the problems of like small device so this is in most of the cases fine you can always use just your handler buttons and just your have little buttons will give you exactly that what you want I think so with with will just your handler buttons you can handle those events and directly in on the UI thread I will be adding new animations in my app should I continue on do you want or use be - yeah I mean it sort of depends what app is that so reanimated - is still in alpha which is it's more about the library like still rapidly changing and then the stability so we haven't really entered the face where we are focusing on stabilizing the library so I think this will actually take another a couple of weeks if you're planning to releasing your app like in in in a few months from an hour not necessarily today or next week and then and then yeah I'd recommend trying at least reanimated - I think like building the interaction will be much easier for you you get results faster but then yeah if it if it works for you well then yeah it should be fine otherwise yeah it's yeah it's it's it's a risk you're taking so given the fundamental changes in the API and the fact that many libraries use v1 or v2 be backward compatible yeah I think I mentioned that during the presentation so so the backward compatibility actually relies on the fact that we are bringing the whole in the whole reanimated one core into related to libraries so we essentially like just added new API on top of wound existed we haven't removed any code from reanimated one library except from a few changes so we had to rename a couple of methods and it's all documented and in the react to reanimated Docs so just check that otherwise yeah everything should work the same way because it's the same code we will be maintaining that as well so whenever they're critical fixes we'll be publishing updates and since the since it's actually the same code and then then then we'll be publishing that as a part of version 1 in the first part of and a person to alpha yeah oh great would have time to go through all of those questions its debugging possible yeah this is one of the current limitations that we have we haven't yet figure out a way to to provide like proper debugging just haven't had time to focus on that but it's it's on our roadmap we'll be working on it so hopefully soon for now you can use console based debugging control log is available yeah I think I'm just gonna try selecting some random ones and I'm just going through the ones from the top because they're yeah if it's more than I can answer I think uh-huh and I wanted to wrap up in like 15 minutes so yeah let's try let's try this one when is the work clip code sent to the native thread is there a second day is non-degenerate in that battle yeah I think I explained that at the end so hopefully I think this question might have been asked like during the presentation so hopefully this is all clear now how the shirt values work with concurrent mood not really sure if it's yeah if the question is about Viet Cong kind mode if it is I mean they don't really have anything yet they don't know they don't really have anything in common with with con kind mode because shared values are I'm just objects that I can be updated and they've done really like interact with the component lifecycle too much so what we I mean we are using hooks to create share values not only such that we can keep track on when and when the component is being unmounted and if you have started animations on values that belong to an unwanted component then those those animations can be stopped so this is almost like the only sort of interaction a point of interaction between like the react lifecycle or confined mode or any other aspects of reactant side values do I still need to learn reanimated your run in order to use v2 better no I don't think it's it's necessary yeah it's it's completely different set of concepts and yeah I say as I said it's it's difficult to learn v1 if you if you're not familiar with VM v1 then learning it would not help you I think too much but of course you can do it like as I like training and if you want your head to explode and yeah definitely recommend it okay let's try with this one on does this mean our layout properties can now be animated outside of the read react native J's Fred I saw the change in width but would will it also work with more complex flags box layouts yes you can essentially animate any property but it was already possible and we animated one so you could animate any any property including layout properties so there is one aspect to that so when you're making changes to things like opacity or translations of that kind of properties they are they can be animated directly in the UI thread whereas currently in react native the layout is run on a separate thread which is not a Java Script Fred there's just like a separate native thread than France layout code so whenever you update layout properties that layout updating code needs to be executed that doesn't mean that you actually go to j/s and but it is also no not as fast as updating things like translation or or anything that is and that is accelerated how accelerated how can you implement your own modifiers and animation designers ask worklets yes animation ascends and modifiers are both worklets we haven't made that API stable yet so we haven't published any instructions how to do that if you want to learn about it you can check the source code in hopefully I made it because like things like whip spring Luke and stuff like that part or all written in GIS so you can you can check out the code there but we cannot really promise that the the structure of like how that assign there should work wrong change in the next alpha release so unless unless this is yeah something that that you're okay with and yeah go ahead and write your own we even have a pull request for a new sign area that's called with decay yeah but we're just postponing postponing actions there and then because we we're still making some small changes here oops it looks like shared values use proxy based tracking reactivity is there a specific reason to do this over the reactive style with a set state function well he's there yeah I think it's it's more about yeah I wouldn't say like it's not like clear that like if it's of like the one solution is much better than the other keeping it as a single object makes it easier for us to keep track of it because with when you when you use the vehicle you state approach that's how I understand the question and you actually have like two elements that help that are an output so we have like a kind state and then you have a salary for it and from the perspective of a receiver of that you don't really know that those two elements are sort of bound together whereas where we have a shared value we exactly know that this is this is a value here is the the way you read it and here is the way you write it yeah also the Maria use sorry you states method requires you like whenever the state changes you need to re-render I mean we are dusted and and this is okay but we don't necessarily need to rerun some code when the value changes we only do that when we know the value is being used so so this way because we we sort of can keep track where where the where the value is being accessed in which worklets we fork let's use the value we can and we can do that and not sure if that would be as easy with you stupid yep you know she's like three other random questions do you see any other uses to work with other than for animations yes definitely so we're actually design for clips to like potentially also support other use cases so not only run on the UI thread but have also secondary threads or like data processing or processing things like video or audio streams stuff like that so so definitely can be used there we we do have plans to to eventually adapt our record to support something else but yeah for now worklets core is specifically crafted for UI so as I described the the way the choreographer works in this is sort of coupled with that logic currently but buddy I definitely see other use cases and and we also have plans for that is that we're going to try it on this for leaking code from main fit into your eye fat I don't I don't think Apple cares I mean the which thread you used to execute the JavaScript code in fact also of the cross-platform frameworks that run JavaScript code they actually execute JavaScript on the UI thread so react native as far as I know is hey I'm the only framework that doesn't run the JavaScript on that main friend so I think I guess it's okay and they don't have any restrictions on to what Fred you should use to run the JavaScript so the only restriction is that you should use the available - per diem and then we we do that so we essentially spam the secondary context for the JSC home on iOS so this is not like a another PM this is the same VM it's like a secondary genius complex what are the realities of simplifying the installation process what needs to change across the board react here for this to become a simply yarn have that's an interesting question yeah yeah I haven't really spoken to anyone from react native core about that just yet so what what we animated to now that's it it uses the turbo modules sort of api's to to instantiate the reanimated module and this comes with a cost of like changing your setup but like in my opinion many of the steps that are currently being added to the apps that use turbo modules are more like a boilerplate II and can be definitely like moved out and generalized to some extent so so as we I think as we see like more like read the adoption of turbo modules grow we will perhaps also see like the the process of installing turbo models becoming more simpler more more simpler and and seamless I out so so hopefully hopefully some of the next releases will make installing turbo modules as simple as you're not so this is not yeah it's not really specific to reanimated now it's like we just use turbo modules and and the installation looks like that because that's what we would do with any turbo model you try to add our work let's type recognized by type script not sure what types is there question about you know kind of close that one yeah I think I'll take another one and and we wrap up what about callbacks when the animation is ended yeah you can pass callbacks so this is also in documentation I don't I just didn't have any examples in my presentation so things like with timing with spring they take call back in that callback is called and it gets a boolean which indicates whether the animation has finished or whether it's been cancelled all right there a couple of more questions I yeah we'll see if there is a way to save those questions and maybe I can answer them offline or at least at least select some of the most interesting ones and hopefully get we will get some other opportunities to also do like QA section session and but yeah I think the the hard time is ending my time is ending asleep at least so thank you all for coming yeah we have a few people here and so thanks thank you all for coming and any si as I mentioned follow stuff I mentioned for other for next webinars and any hopefully see on on the app.js conference maybe next year bye
Info
Channel: Software Mansion
Views: 17,327
Rating: undefined out of 5
Keywords: React Native, IT, open source, reanimated, mobile apps
Id: IdVnnIkNzGA
Channel Id: undefined
Length: 96min 43sec (5803 seconds)
Published: Tue Jul 07 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.