Learn React Native Gestures and Animations - Tutorial

freeCodeCamp.org · Beginner ·🌐 Frontend Engineering ·6y ago
Skills: React90%

Key Takeaways

Adds declarative gestures and animations to React Native projects

Full Transcript

hello freecad campers welcome to this workshop on declarative gestures and animations in react native i'm william maker of the can it be an iraq native youtube series in this workshop i would like us to do five things first to discuss why the topic of gestures and animations is so peculiar in react native and what are the strategies and apis we're going to use in order to implement user interactions that run smooth as the butter from there we can look at transitions transitions are the easiest way to animate components in react native and we're going to build a component with two states one state the cards are overlaid on top of each other second state they are nicely found out and we're gonna declare a transition to animate nicely from one state to the other and then we're gonna build a simple timing animation that we can loop pause resume pause resume using bare metal animation apis getting to know these low level apis will be the key to success for us to harness gestures and animations in react native and then it will be time to add gestures into the mix and we are going to build this nice wallet user experience so we can swipe for cards nicely and they animate very nicely depending on their position finally i would like to show you that these gestures and animations integrate very nicely with svg and we're going to build this really cool circular slider using gestures and svg animations this workshop will only be scratching the surface of the exciting world of gestures and animations in react native and to conclude i will give you all the resources that i know of in case you are interested to go further with this topic in the video description you will find the github repository with all the code examples as well as the boilerplate files in case you want to cut along in the video and also available in the video descriptions are the timestamps for each of the different chapters of the workshop so free code campers are you ready to discover the powerful world of declarative gestures and animations in react native let's get started [Music] building gestures and animations the key to success is to avoid frame drops we want the user interaction to run at 60 frames per second which means that we only have 16 milliseconds to compute everything and this is a very simple diagram of the react native architecture we have the javascript thread which runs the react code and the ui thread which interacts with all the native components and they talk to each other using what we call the async bridge they asynchronously send each other json messages so if your gesture or animation relies on communication between these two threads it is very hard to guarantee that the animation frame can be computed within 16 milliseconds and you are likely to drop frame there are a couple of reasons for that first because of these asynchronous messages that needs to be passed and serialized you might drop a frame on the low end device and the javascript thread might be busy doing something else for instance processing the response of an http request so maybe you have a so the ui thread says to the javascript fred should i grant the gesture and the javascript thread might be busy processing the response of an http request so it's not able to reply within these 16 milliseconds and you're going to drop a frame and the user experience is not going to feel uh very smooth so the way we are going to circumvent this problem is by declaring all of our gestures and animations beforehand which means that there is no communication between the javascript thread and the ui thread so it doesn't matter if the javascript thread is busy doing something else because the ui thread is going to be able to do all the tasks he needs to do for each frame and plus because there is no communication between the two threads we are sure that we are able to compute the animation frame within these 16 milliseconds and i would like to show you an example of what this means concretely so here i'm dragging around this component and we implemented this example using the default gesture and animation api provided by react native i call it a vanilla animation apis and as you can see here the gesture depends relies on communication between the javascript thread and the ui thread so to grant the gesture we need to execute some javascript thread when we move the view around here everything is done on the because we use this animated event everything is done on the ui thread so there is no communication between um the javascript and the native side and when we release the gesture we also rely on javascript code and so because we have this mix of imperative code and declarative code if the javascript thread is busy this user interaction is not going to run smoothly and in fact what i can do is to modify the code so that we [Music] have the javascript fret we make the javascript thread busy so i'm gonna loop 5000 time and maybe like print something like gs thread vz and now you see i cannot move the ball around because the javascript thread is busy and so we are not gonna use these apis because these apis rely on communication between the ui thread and the javascript thread and what we're gonna use instead so [Music] is two libraries react native reanimated for animations and react native gesture angler for gestures and what these libraries do is that they enable you to implement all the gestures and animations declaratively on the ui thread which means that when you have your gesture and animation running there is no communication between the two threads that is involved so here if i make the javascript phrase busy it doesn't matter because there are no communications between the ui thread and the javascript thread so this is the same implementation but using declarative gestures and animations using react native gesture handler and react natively animated and now so everything is done declaratively and now i can make the javascript thread busy up so gs thread busy so now the loop is running but because i don't rely on the javascript thread you see i can still move the ball around smoothly and so this is the heart of the mallard declaring all the gestures and animations beforehand and this will guarantee us to build user experiences that will run at 60fps even on low-end devices [Music] in this example i would like to show you the power of transitions in react native transitions are the easiest way to animate components in reg native and the way it works is that we can attach an animation value to a change of state in a component so here i have a very simple component with a very simple state toggled is true or first if the toggle is true we apply here a rotation which is index minus 1 times alpha so alpha is 30 degrees pi is 180 degrees divided by 6 and here i do index minus 1 minus one times alpha so if index is zero zero minus one is minus one times thirty degrees so we'll have minus thirty degrees if index is one so the card in the middle we would have one minus one zero times thirty degrees zero so there won't be any rotation if it's the third card we will have index two two minus one is one so we have thirty degrees so we see here here we have the cards constants which contains six cards we select three and we calculate the rotation when pressing this button we toggle the state so to its opposite value and so if toggled is false we have rotation of zero and what we can do here is to use a hook called use transition that will give us an animation value that will go from zero to one when toggle changes so if toggle is false the animation value will be zero if toggle is one the animation value will be one and the way the transition from 0 to 1 1 to 0 goes can be a timing function can be a spring function and can be any configuration of the animation functions that you want so let's get this animation value here we're gonna call it transition and we're gonna use a function called use transition use transition comes from a package called react native redash so we are going to use react native reanimated and react native gesture handler for the declarative gestures and animations and i created an open source package called react native redash i see it as being the low dash of reanimated that provides us with a lot of utility functions such as this use transition hook but you don't have to be intimidated by it these are just helper functions on top of reanimated and gesture handler you can look at the source code of some of these functions to see how it works behind the scene but these are usually very simple helper functions so this function takes two arguments the first is the state we want to transition on and here it's toggled and then we can pass an animation configuration so for instance here i by default choose transition is using a timing function and maybe i want the duration to be 400 you can set some easing you can have a spring function instead so here we have our transition and what we want to do is to interpolate the rotation based on the transition so here you see we have the view component here we use animated.view animated.view is an animation wrapper around view so that in these style properties we can use animation values so here we pass a string which is a rotation value in regions but now because we use animated.view this style property can also accept animation values so here rotate is going to become an animation value and we are going to interpolate it using transition so you see so we can write it using interpolate from react natively animated so the animation value is a transition input range is 0 1 and output range is if toggled is zero the rotation is zero if toggle is one the rotation is index minus one times alpha so i need to import interpolate let's have a look so you see here it nicely transitions from one state to the other it looks very cool again speaking of helper functions in re dash we are gonna have a lot of these uh animation values that go from zero to one and we're gonna interpolate always from zero to one there's a helper function called called mix in redash so here we import mix from a dash and it's the same implementation as mix in opengl so we can pass directly the output range like this so from zero to index minus one times alpha so just a nice shortcut and yeah it is and the last thing we can do is to change the transformation of origin so here you see by default is the center of the card and the way we transform the origin in react native using the transform api is that we're going to translate to where so from the center of origin to where we want the new origin to be do the transformation and translate back so here we want to translate to so the default origin is half of the weave of the card half of the height of the card we want to translate to minus half of the wheel of the card do the transformation translate back to half of the width of the card so we're gonna write translate x is minus card width divided by two we do the transformation which is rotate and translate back so translate x is card with divided by two and so here you see it nicely changes the transformation of origin and here again we have a nice utility function in re dash to perform such a transformation of origin it's called transform origin and the first parameter is a new transformation origin so here we have x which is minus card divided by two y is zero we don't change it and the transformation is rotate and so here it is so transitions are a great way to animate components in react native with little to zero knowledge of gestures and animations so just a great way to animate changes in your component states [Music] in this example we are going to build a simple timing function using the bare metal apis from reanimated and getting to know these low level apis will enable us to build incredible user experiences so here i have a chat bubble component that takes a progress property which goes from zero to one so this is a state at zero we can look at the state at 0.5 1 and so we're going to go from 0 to 1 1 to 0 and there is a state play which is true or false so we want this looping timing function to be possible and resumable nicely and in order to implement this timing function we are going to use all the concepts that react native reanimated has to offer or almost all of the concepts and one of these concepts are clocks so clocks are animation values which update themselves across time so by default the value of a clock is zero you can invoke a function called start clock on it and the every frame the clock animation value will update itself with a timestamp and this is this will enable us to build animations across time then there is a stop clock function to stop the clock so the clock animation value will stop updating itself and there is a function called clock running to check if the clock is running or not and so the way you can create a clock is like this so it's clock from reanimated we want here because we're gonna have many rerenders when the state changes we want we don't want to recreate a new clock every time we want the clock identity to match the life cycle of the component so we want to always have the same clock for the every instance of our timing component and so we can use the helper function for that again from re dash which is use clock and here for progress we can use an animation value so you would do new value year 0 from again react native animated but we also want the identity to be preserved across rerenders so we're going to use use value from redash and these are simple wrappers using a lazy use ref to have so i need to import from redash so what we are going to do is that we are going to use a hook called use code which allows us to declare animation nodes to be run for every frame on the ui thread so the function signature the hook signature is very similar to use effect the first argument is a callback that returns here an array of animation node the second parameter are the dependencies here we have none we want this these animation nodes to have also the same life cycle than or timing component and so what we're going to do is use the clock to control the animation if the clock is not running the animation is paused if the clock is running the animation is running and so by default here we're gonna want the animation to run so we're gonna use a start clock and what we're gonna do is assign to the progress value some timing function so some function that we're gonna call run timing and pass the clock as parameter so let's create it here so run timing is a function that receives a clock as parameter and we are going to return some uh progress value execute also a bunch of animation nodes so you can use a block in order to do that takes an array of animation nodes as parameter and will execute these animation nodes sequentially so maybe i return zero so the last node in the array's value that is returned and so you know you see here i'm not [Music] writing progress equal run timing because these are not imperative instructions that are run on the javascript thread but declarative animation nodes to be executed on the ui thread so this is here it's not a code that is executed but it's a declaration for code to be executed on the ui thread so we are not going to use the if-else syntax from javascript we're going to use a condition animation node we're not going to use equal but set animation node and so on so reanimated provide us with all the animation nodes we need in order to declare complex animation states and interactions on the ui thread so let's um write or run timing function so i need to import this one from reanimated so if we look at the timing function from react natively animated we see that it takes three parameters the clock so to you know see where how we evolved across time the animation state so finished position your position will be from 0 to 1 right time and frame time so i last clock values for the last evaluation and 0 to 1 if the animation is finished or not and then the animation configuration so the target value duration easing so you see if you are familiar to the vanilla animated api from react native it's a bit more complex to execute a simple timing function but this so the barrier to entry is higher but this is a way more powerful functions so this is why i really want us to look at the low level of all these functions work because this will enable us down the road to go much much further because these functions are incredibly powerful so let me copy paste here the function so timing from reg natively animated and so the clock we get this parameter let's create the state [Music] so i'm going to create it here state so i'm going to assign an animation value for each state [Music] position frame time time and we have the config [Music] so two values we are gonna update it depending right two value is if the position is zero the position is gonna be our starting value if the starting value is zero the destination value is one and if the position is one or the destination value is going to be zero duration i don't know let's pull three seconds and easing we can put whatever i think in out and it does not like the configuration so i have how is the syntax of the using here i'm importing easing from vanilla react native but i need to import the one from reanimated so that should be good this is where typescript is so useful so here we execute the timing function for every frame and what we want to return is the position so state dot position so you see it animates nicely from zero to one at one nothing happens so what at one what we need to do so if state dot finish equals one so you see here we are not right again we are not writing if else because this is not javascript code that is executed imperatively this is a declaration so we use the condition animation node that is a declaration to run on the ui thread so if the state of the animation is finished we want to reset these animation values position we will leave but we need to update the true value so let me reset the state so is finished is zero we want to loop frame time time we reset as well because we're restarting the animation position we keep if it's one it's still one we want to continue where we were so state.time but what we want to change is the destination value so config 2 value is going to be the opposite of state.position if position is 0 the two value is one if position is one the true value is zero so here i need to import these nodes so you see it loops nicely from one to zero and now from zero to one now let's make the animation interruptable so you see here you might be under the impression that this is a lot of boilerplate code to write a simple looping animation there are utility animation functions in redarge that allows you to do these in a few lines of code because all this boilerplate can be done for you but i find it to be extremely understand important to understand how these clocks and animation evaluation work because this can really unlock the power of complex uh declarative gestures and animations that will run at 60 fps so this is why here we are doing all the boilerplate manually so here we have the state play which becomes true or false and the first thing i want to do is to have an animation value that matches the state of play so if play is true i want my animation value to be one if play is forced my mission value to be zero so here we're going to create a animation value called is playing so default value is zero here default state is false so that's good and we're going to create a hook or again a use code hook that will set the animation value is playing to match the state of the play variable so and you see here i could write it here in news code but i'm i'm having different dependencies now so let me show you so i do is playing so if plays true it's one if not zero and here the dependencies is play so when play changes this uh instruction changes because it depends on the play variable and this is why i'm putting it into a separate use code block because i don't want to have a dependency on the play variable here what i'm gonna write the instructions i'm gonna declare here are valid for the whole lifetime of the component so i don't want to recreate these animation nodes if the play variable has changed only is plain so now we should have the is playing variable that matches the state of the component and so we're gonna test that actually so we're gonna write two conditions so the first condition is if the state of the animation is playing and the clock is not running so not clock running and here you see you have to count the parenthesis we want to start the clock we want to start the animation and the other way around if the animation is not playing [Music] and the clock is running we want to stop the clock so i need to import stock clark and the end let's have a look so here i play and i can pause resume and you see it doesn't resume at the proper state but i can pause and i can start the animation but when i restart the animation the state of the animation is screwed up pardon my french so here if the clock is not running [Music] so if we pause the animation we want to reset the time variable of the state so that when it resumes it resumes the animation properly and if not we run the timing function so let's pause and now it resumes exactly where it was pause super and it loops nicely so a really cool timing function but so very low level apis clocks and all these complex animation states but these are really these low-level primitives are really worth it in order to build complex user interactions and we've seen how we don't write imperative javascript code but use these animation nodes which are declarations on the ui thread and so all the primitives we have in javascript if and not we can the semi column to have sequential instructions so we have the block here so we have equivalent for all the javascript construct as animation nodes and the only construct that is so you can have variable assignments sequential executions conditional nodes the only primitive that is not available are loops but here but that's okay because here it's code to be evaluated for every frame so i hope you enjoyed this example if this makes sense to you then you really have unlocked the power of uh declarative gestures and animations if you are able to to switch from the imperative mindset to the declarative mindset and uh understand how you can use clocks and animation states in order to build different user interactions then the world of animations and gestures in react native is your oyster i think you can really go very far with these primitives [Music] so we have looked at transitions animations now let's play around with the gestures we have a bunch of cards here and let's assign some gesture handler to these cars and play around see what we can do and so here i'm looping over my cards and maybe what i can do here is wrap a pan gesture handler from react native gesture handler so we can maybe move these cards around and we need to pass two properties for the gesture handler to work and we're gonna have use again the utility so it's quite some boilerplate so there's a lot of animation values to be created a two [Music] properties to be assigned on pangasia handler so we are going to use a utility function again from re dash in order to have all this boilerplate done for us but you know again don't be intimidated you can look at the reda source code or add the react native gesture and source code to see um you know what kind of boilerplate is required for these uh gesture handlers to work but we're gonna get the gesture and learn from a function called use pan gesture handler and it gives us couple of variables the gesture handler that we can assign here and the translation vector of the card the velocity so when we release the gesture the velocity of the gesture and the state of the gesture is the gesture active is the gesture began and and so here we assign the punches channel i probably need to move key here and the punches handler takes a single children which needs to be an animated view from reanimated so here we use animated w from react native reanimated so we get the translation vector here i think we can assign it this transformation to see if we can move the card around so we're going to use a transform and there is a utility function in redash called translate where we can give it a vector and it will apply translate x translate y a simple shortcut so here i can move the cards around but i should create one punjabi channeler for each gesture handler so i'm just going to move it here so you see i can move the card but now if i start the gesture again it starts from the original position so we need to save the position in an offset value when the gesture ends and again in a re-dash we have a utility function for that so i'm going to create translate x equals with offset and the first parameter is the animation value and the second parameter is the state of the gesture so that we know when to save the offset so translate x we're going to do the same for y and yeah we're going to apply the transform so translate x translate y let's translation so here i can move the card around and it remembers its position across time and you see when i stop the gesture it's kind of abrupt there is no like physical momentum so what we can do here instead of using wheel offset we can use with decay which will add some nice decay and this is where the velocity comes into play because the decay is calculated according to the velocity so we value with translation x velocity is velocity dot oops velocity dot x state is state so same for y [Music] so now you see you have this nice up nice momentum when moving the card and you see it's interruptable as well so now let's have a nice wallet animation using these concepts of punjabi chandler and dk so i'm going to move this outside the loop [Music] and we're going to move the punjab chandler to be unique [Music] to the view and we want to translate only on the x axis actually so just want to scroll oops we just want to nicely scroll our cars so something is not working because we forgot as i mentioned the single child needs to be an animated view but what i'm gonna do because i want to keep this one i think i'm gonna wrap it here [Music] and put an animated view let's see how it looks it's not translate x but translate y okay so it translates nicely and we have like the nice momentum effect from decay so now we want to clamp the values we're going to use a function called diff clamp so it clamps diff clamp clamps a value with a min max but we call it diff clamp meaning that you know if we go to -100 pixels just a delta of one pixel will be taken into account so it's uh with it's much more responsive if you want if you scroll far back in one of the lower upper bound and want to go back to one of the weaving the bounds of the clamping so we're going to add a diff clamp here and here there is a trick so there is currently a bug in the div clamp implementation of reanimated so we are going to use diff clamp from redash so in order to not have this bug so the maximum value is uh zero right when we are at this state here and the minimum value is gonna be [Music] so the length so the height of all these cards minus this height here so this would be minus cards dot length times card height which we have defined here perfect minus the container height which we calculate using on layout so let's have a look so here so you see this is where this clamp comes in if i use only clamps so here i'm scrolling scrolling scrolling scrolling scrolling then if i want to scroll back like this i would have to do all the opposite scrolling that i did but even though here maybe i'm like 500 pixels right now can just immediately go back up and this is what this clamp does i mean i can show you quickly with clamp so here i'm scrolling down scrolling down scrolling down scrolling down scrolling down if i want to scroll up again i need to square up scroll up square up square up scroll up and nice close ups with the clamps diff clamps it's going to be automatic scroll down square down scroll down but you see immediately scroll up and let's look so the lower bound is not correct it's plus container eight sorry so zero and perfect and very cool so now let's animate our cars so um maybe we want to add so we want actually now we're going to clamp so i'm going to call this y so if the card has reached the top i don't want it to go above i want to clamp it's its value so translate y we're going to interpolate from the y animation value so the input range goes from zero and if we translate to so for the card to be at the top if it's here at 0 if it's [Music] minus card weave so that would be minus card so card 8 sorry times index so this would be our clamping value so the output range would be the same value but we're going to use extrapolate clamp meaning so this should be the maximum value the card can go so to not go outside the screen and so by using so here we use linear interpolation these values match one to one but when we are we have a value for instance that is lower than minus card eight times index we want to be at minus card height times index not a lower value so we're gonna write extrapolate extrapolate dot clamp let's have a look so you see the card moves on top of each other um you can even add maybe just you know if you want to build some effects here maybe it's minus card 8 plus 16 or minus 16 sorry you see how you are 24 anymore so you already have like here a nice wallet animation so now we want to calculate the position of each card and so the position y is y plus the index times card height and we're going to use this value to do a couple of interpolations so if the card is disappearing its position is at least at least minus height so from minus zero to minus height minus count height sorry right so the here the card its position is zero so if the card is on top its position is zero if the card is at the bottom here so what is the position on bottom it's the number of visible cards in the screen times the height of the card so there would be visible cards times card height what are the number of visible cards so visible cards we do a math floor of the container height divided by card height and so this is the number of visible cards so this is so minus 1 for the range and is appearing is the number of visible cards times card height so is but tom [Music] is appearing so now we can create some scale transformation so the scale of the card so we interpolate from position y so the input range is is disappearing is on top is on bottom and is appearing and the animation values are so zero five it's disappearing one one if it's in the visible range so end zero five when it's appearing let's try that so here you see it disappears nicely in the background and it appears nicely here what we can do is add some clamping that looks good let's add some opacity so same story for opacity so i can just add it here and um [Music] here one perfect oh actually same value no what we want to do here is to not clamp i think so you see here it disappears nicely and so one thing we can fix is you see when the card appears it's too far away from the top card it's it's not super smooth so we can add some extra translation here so here we can add so you see here we don't do a plus again we're using the add animation node so uh let's call it extra translation why so which we're gonna interpolate from position y so actually let me move these up so we interpolate from position y oops so input range so we go from ease um is on bottom to ease appearing output range so at bottom the translation is zero at is appearing we want we know that at ease appearing the size is uh scale is 0 5 so the height is card i divided by 2 and we want to move it by half of the card height so it's gonna be card height divided by four and of course here we want to clamp so we don't want to go outside these values extrapolate clamp let's have a look no it's not it's minus card i divided by four and you see now it looks very cool and one thing we can do here and that you see the scroll is not completely over so we don't want to stop the scroll on i'm being very picky here but it doesn't feel nice that the end score position is this so the last card should be at least as the full position so here maybe instead of container we can do visible cars now what do we need to do so we add container height let's try visible cast times card height yes so that looks good so here and square position looks much nicer so you see a pretty cool user interaction using the pan gesture handler from react native gesture handler but they are of course tons of uh different user interactions you can build using these apis but i hope that this uh nice wallet user interactions really uh gave you some inspiration on the kind of gestures and animations you can build using these apis [Music] these gestures and animations we just looked at integrate seamlessly with react native svg and this allows for an interesting range of fun and creative user experiences and components and this is thanks to an incredible community and open source work right so we looked at react native channeler react natively animated which allows us to declare our animations on the ui thread and then there has been a tremendous amount of open source and community work which has been spent in order for these libraries to nicely integrate with react native svg and so i would like to show you a simple example which is going to be a circular slider so here we have a svg circle here the circular progress and so we have the white one here and we're gonna animate the stroke of this one to to show some some progress and here we have a cursor component which we are going to be able to move around and its value will always fit the bounds of the circle so here we have a data animation value and we are going to move the cursor around to update this value so theta goes from zero this is the position at zero or actually here we have a rotate of minus 90 degrees so zero is going to be here let me remove this one for now so we're gonna have zero here we move pi minus pi zero and so maybe here we're gonna normalize because this goes from 0 to pi minus pi 0 we're going to normalize it to go from 0 to 2 by 360 degrees and the way we're going gonna do it we are gonna set so we have a theta value zero this will set the position of the cursor onto the circle how are we gonna do it well we have three coordinate systems to work with in react native there's a canva coordinate system so there's the x axis which goes from the left to right and the y axis which goes from top to bottom this is our canva coordinate system then there is a cartesian coordinate system where we have a center of origin somewhere here our center is going to be the middle of the circle and the y-axis goes from zero from bottom to top so the opposite of the canva axis which goes from top to bottom and then we have the x-axis which is identical goes from left to right this is our cartesian coordinate system the third coordinate system is a polar coordinate system so here we also have an origin [Music] and given a x and y value in the cartesian coordinate system we're going to get a angle in a theta value in regions and a radius so we take the uh angle we call we convert it to the so we have a polar coordinate so we have a radius and an angle we can convert it to a canva coordinate which will give us x and y position on the canvas so that will position the cursor onto the circle then we move the circle around so we have x and y coordinate which we can transform to a polar coordinate in order to know the angle theta and so we can assign the data value which will drive the animations of the uh stroke value and also maybe we can animate the color of the progress so maybe we want green at the beginning red at the end and so if you go on my youtube channel i will put the links in the video description i have videos on how we can convert from one coordinate system to the other here we're going to use again utility functions from re dash to seamlessly go from one to the other so let's get started so we're gonna start with our cursor and once we have so the cursor is going to write the data value and once we have it working we will look into animate the circular progress component that we have here so let's look at the cursor so the first thing we're going to do is to wrap a pan gesture handler so we can move it around so pan gesture handler from react native gesture and we need the gesture handler we're going to use the helper function from redash so we have gesture handler use and channeler and we're going to get the translation vector and the state of the gesture oops some typo here and [Music] so here we're gonna add some translate but what so what we want to do okay let's add some translate so translate x we're going to use so we want to remember the position across different gestures so we're going to use with offset so translate x state translate y up translate y translation let me apply the transformation translate x translate y so i can move the cursor around super but now it needs to be you know whatever is the position within the bounds of the circle so this is where we need to convert these values into polar coordinates so i'm gonna create x y and we have a center vector which is the middle of the screen so let me create [Music] a vector so center is [Music] x is width divided by 2 y is height divided by two which we need to import from the dimensions api so we have weave height from dimension get window so let's convert these into polar coordinates we have polar equals so here these are cartesian so we're going to use cartesian tu polar if you're interested the math behind this function is super interested i have some videos on this topic so if you're interested i definitely recommend you check it out so first argument is the point so we have x y and we probably need to cut it no polar that's correct and so we get [Music] the tether angle which we can assign to this animation value the radius here the ranges doesn't matter what we need to do is to set the ranges to be the radius of our circle and convert back these coordinates to cartesian coordinates so we are going to have x translate x y translate y so we are going to convert polar to cartesian teta is a polar dot no problem but regis is not the rages of our cursor but the rages of the circle so that will bound the cursor to only move around the circle and the second parameter should be polar to coordinate to cartesian no that looks good is this regis regis is r so you see we have an issue so translate x with the center the origin of so i think i should set center here sorry okay it's not cartesian to polar but convert to polar my mistake so canva to polar and we can set the center of origin here so center and here it's canva two polar to canva i was confused why it didn't need to use the center of origin the origin that didn't make any sense so now still actually doesn't work we have a weird so actually here the center because it's not [Music] the container so it's not the window but the content which is the size here this container of the circle so if here i put background color red so you see our center is not height of the screen divided by two but outrageous and outrageous so let me update this so center is regis and so now it animates nicely so now we need to set the data value and so you could set the value to be polar theta directly but polar that theta goes from zero to pi and minus pi to minus zero so here the value would be minus pi divided by two and not a three quarter of two pi's so we want to normalize the value to go from zero to two pi so we're gonna create use code and we're to assign up and we're going to assign data to be polar dot data but we need to normalize data so normalized data we take data so as an animated node so if theta is less than zero so it's uh minus zero minus pi we need to add 2 pi so theta is less than 0 it's theta plus 2 pi if not it's the theta value so from zero to pi theta is okay and now if let's say we have minus pi minus pi plus two pi would be two pi three quarter of two pi's so it's gonna be two pi minus alpha one pi so this should give us proper values for theta and here let's see we're going to interpolate the colorant data to see what we we get so let's choose interpolate so colors are numbers and we have interplay color functions in redash so we can interpolate on theta and so input range so teta goes from zero to two pi so we have zero let's say pi and two pi we're gonna use three colors output range we can use style guide palette secondary primary and primary let's have a look so see here the color updates nicely so now let's animate our svg circle and we're gonna use the dash stroke array to animate the progress of the circle so we want the dashboard away to be circumference of the circle so we want one empty uh stroke to be the circumference of the circle one full stroke to be the circumference of the circle so we can animate really from zero completely empty to one completely full so the circumference of the circle is um two pi times the radius and um the length of the arc of circle is going to be regis times the theta right and so this is going to be the offset the dash stroke offset so let's uh so we need to calculate the circumference which is going to be 2 pi times the radius which we get here yes as property so we can assign dash stroke array to b so circumference circumference and we can calculate the so here okay so the dash stroke offset and here so we're gonna have a couple of animation values so it's not a circle but an animated circle an animated circle we use the create animated component in order to have the wrap animated wrapper that can accept animation values as property so now we need to calculate stroke dash offset which is actually the same formula than here but instead of having the full angle which is two pi we have we use tether so it's going to be multiply theta by regis let's have a look it looks good but also very strange so the struck color appears to be good background color um we need to add stroke weave and now there is a strange uh of set value here so here it looks like at zero it's correct and then there is you see some offset value that goes further and further and i think here i wrote it down because i wrote rages is the rages minus the stroke we've divided by two that makes sense because we want the center to be here so i should probably replace radius here yeah now that looks good up it's fun isn't it i could play with these always for hours but really a nice example of how gestures and animations seamlessly integrate with each other [Music] free code campers i hope you enjoyed this workshop on declarative gestures and animations in react native let me know what you think in the comments below if you're interested to go further with this topic i will link to resources in the video description we discussed the heart of the matter why is this topic so popular in react native and the apis and strategies to use in order to build these very smooth user experiences we looked at transitions the easiest way to animate react native components and then we implemented a simple timing function using the bare metal reanimated api and we've built this timing function to be uh interruptable so we can pause resume but also we can also loop the uh function across time then we built our first gesture so we had these cards and we could move them around and swipe them and we've used the gesture api to build a nice wallet user interaction and finally we've looked at how svg can be used to seamlessly integrate with these gestures and animations and that allows for a range of really fun and creative user interactions to be built if you go on my youtube channel i have dozens of videos on this topic for instance in the case of the svg example we used functions which leveraged trigonometry behind the scene right where we converted from polar coordinate system to canva and vice versa i have videos where i really explain the math behind the scene and trigonometry is very important in animations because as soon as you have something that has some sort of rotation it's gonna involve trigonometry and i have quite some uh videos about this topic and i have also more advanced videos on the topic of svg animation for instance you can use svg animations to morph from one svg path to the other and there is a also really interesting examples with bezier curves there is really we only scratch the surface there is really tons of great things you you can build using svg animations we looked at the pan gesture handler but there are of course different kinds of gestures in react native the top projection handler the pinch channels rotate the channeler and i also have videos on this topic i will link to these uh resources in the video description and we use the transform api to move things around and we even did um transformation of origin the transform api from react native is incredibly powerful and we've not even looked at all the things it has to offer and i also have videos on these topics on how to build advanced 2d transformations how to save the state of complex transformations across the gestures and i even have a video where we go to the third dimension so if you are interested i hope that you will check it out so i'm really looking forward to talk to you soon and in the meantime happy hacking [Music] minus pi minus pi plus two pi would be uh two pi uh three quarter of two pies so we would have so minus pi plus two pie is pi but so ah minus pi divided by two so minus pi divided by two plus two pi is going to be three divided by four of pi of 2 pi so it's going to be 2 pi minus alpha 1 pi

Original Description

In this React Native course, you will learn how to add declarative gestures and animations to your React Native projects. 💻 Code: https://github.com/wcandillon/react-native-gestures-and-animations-workshop ✏️ Course created by William Candillon. Check out his YouTube channel: https://youtube.com/wcandill 🔗 Learn more about React Native here: https://www.youtube.com/watch?v=frvXANSaSec ❤️ Try interactive React courses we love, right in your browser: https://scrimba.com/freeCodeCamp-React (Made possible by a grant from our friends at Scrimba) ⭐️ Course Contents ⭐️ ⌨️ (0:00:00) Intro ⌨️ (0:02:44) The Heart of the Matter ⌨️ (0:09:18) Transitions ⌨️ (0:17:06) Animations ⌨️ (0:35:09) Gestures ⌨️ (0:56:07) SVG Animations ⌨️ (1:15:28) Closing Notes Other interesting resources on this topic: 🔗 Simple physics with Reanimated: https://blog.swmansion.com/simple-physics-with-reanimated-part-1-9d55d36f73cd 🔗 Advanced transformations: https://www.youtube.com/playlist?list=PLkOyNuxGl9jxl0wmkADBH9eJPWR_58VeU 🔗 Pinch, Rotate, Tap gestures: https://www.youtube.com/playlist?list=PLkOyNuxGl9jys0MAs2tV_wS70Ey_iFLA0 -- Learn to code for free and get a developer job: https://www.freecodecamp.org Read hundreds of articles on programming: https://freecodecamp.org/news
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from freeCodeCamp.org · freeCodeCamp.org · 0 of 60

← Previous Next →
1 React: Production Server Setup Part 2 - Live Coding with Jesse
React: Production Server Setup Part 2 - Live Coding with Jesse
freeCodeCamp.org
2 cookies vs localStorage vs sessionStorage - Beau teaches JavaScript
cookies vs localStorage vs sessionStorage - Beau teaches JavaScript
freeCodeCamp.org
3 Browser history tutorial - Beau teaches JavaScript
Browser history tutorial - Beau teaches JavaScript
freeCodeCamp.org
4 Graph Data Structure Intro (inc. adjacency list, adjacency matrix, incidence matrix)
Graph Data Structure Intro (inc. adjacency list, adjacency matrix, incidence matrix)
freeCodeCamp.org
5 React: Parameterized Routing with Next.js - Live Coding with Jesse
React: Parameterized Routing with Next.js - Live Coding with Jesse
freeCodeCamp.org
6 React: Dealing with jQuery Issues - Live Coding with Jesse
React: Dealing with jQuery Issues - Live Coding with Jesse
freeCodeCamp.org
7 setInterval and setTimeout: timing events - Beau teaches JavaScript
setInterval and setTimeout: timing events - Beau teaches JavaScript
freeCodeCamp.org
8 Browser and Device Testing - Live Coding with Jesse
Browser and Device Testing - Live Coding with Jesse
freeCodeCamp.org
9 Last Minute Updates - Live Coding with Jesse
Last Minute Updates - Live Coding with Jesse
freeCodeCamp.org
10 Post Launch Updates - Live Coding with Jesse
Post Launch Updates - Live Coding with Jesse
freeCodeCamp.org
11 React: Setting Up Google Analytics - Live Coding with Jesse
React: Setting Up Google Analytics - Live Coding with Jesse
freeCodeCamp.org
12 React: Masonry Layout - Live Coding with Jesse
React: Masonry Layout - Live Coding with Jesse
freeCodeCamp.org
13 Load Balancing Digital Ocean Droplets - Live Coding with Jesse
Load Balancing Digital Ocean Droplets - Live Coding with Jesse
freeCodeCamp.org
14 try, catch, finally, throw - error handling in JavaScript
try, catch, finally, throw - error handling in JavaScript
freeCodeCamp.org
15 Load Balancing: SSL Passthrough Setup - Live Coding with Jesse
Load Balancing: SSL Passthrough Setup - Live Coding with Jesse
freeCodeCamp.org
16 Graphs: breadth-first search - Beau teaches JavaScript
Graphs: breadth-first search - Beau teaches JavaScript
freeCodeCamp.org
17 React: Masonry Layout Part 2 - Live Coding with Jesse
React: Masonry Layout Part 2 - Live Coding with Jesse
freeCodeCamp.org
18 React: WordPress API Live Search - Live Coding with Jesse
React: WordPress API Live Search - Live Coding with Jesse
freeCodeCamp.org
19 Creating WordPress Custom Post Types - Live Coding With Jesse
Creating WordPress Custom Post Types - Live Coding With Jesse
freeCodeCamp.org
20 Dates - Beau teaches JavaScript
Dates - Beau teaches JavaScript
freeCodeCamp.org
21 Miscellaneous Front End Updates - Live Coding with Jesse
Miscellaneous Front End Updates - Live Coding with Jesse
freeCodeCamp.org
22 Merging a Pull Request from GitHub - Live Coding with Jesse
Merging a Pull Request from GitHub - Live Coding with Jesse
freeCodeCamp.org
23 React + Prettier + Standard JS - Live Coding with Jesse
React + Prettier + Standard JS - Live Coding with Jesse
freeCodeCamp.org
24 React: Sortable Responsive Table - Live Coding with Jesse
React: Sortable Responsive Table - Live Coding with Jesse
freeCodeCamp.org
25 Geolocation Sorting by Distance - Live Coding with Jesse
Geolocation Sorting by Distance - Live Coding with Jesse
freeCodeCamp.org
26 Tradeoff Matrix - Agile Software Development
Tradeoff Matrix - Agile Software Development
freeCodeCamp.org
27 The Definition of Ready - Agile Software Development
The Definition of Ready - Agile Software Development
freeCodeCamp.org
28 Getting first React job without experience - Ask Preethi
Getting first React job without experience - Ask Preethi
freeCodeCamp.org
29 React: Google Analytics Click Tracking - Live Coding with Jesse
React: Google Analytics Click Tracking - Live Coding with Jesse
freeCodeCamp.org
30 Submitting a PR to an Open Source Project - Live Coding with Jesse
Submitting a PR to an Open Source Project - Live Coding with Jesse
freeCodeCamp.org
31 Should I go back to school to get CS degree? - Ask Preethi
Should I go back to school to get CS degree? - Ask Preethi
freeCodeCamp.org
32 Hero Section CSS Changes - Live Coding with Jesse
Hero Section CSS Changes - Live Coding with Jesse
freeCodeCamp.org
33 Working Agreement - Agile Software Development
Working Agreement - Agile Software Development
freeCodeCamp.org
34 A day at Pennybox with Co-Founder Reji Eapen
A day at Pennybox with Co-Founder Reji Eapen
freeCodeCamp.org
35 React: Sorting and Filtering Data - Live Coding with Jesse
React: Sorting and Filtering Data - Live Coding with Jesse
freeCodeCamp.org
36 React: Sorting and Filtering Data Part 2 - Live Coding with Jesse
React: Sorting and Filtering Data Part 2 - Live Coding with Jesse
freeCodeCamp.org
37 React: Building a New UI - Live Coding with Jesse
React: Building a New UI - Live Coding with Jesse
freeCodeCamp.org
38 Definition of Done - Agile Software Development
Definition of Done - Agile Software Development
freeCodeCamp.org
39 Getting started with jQuery (tutorial) - Beau teaches JavaScript
Getting started with jQuery (tutorial) - Beau teaches JavaScript
freeCodeCamp.org
40 Making a React Blog with WordPress Content - Live Coding with Jesse
Making a React Blog with WordPress Content - Live Coding with Jesse
freeCodeCamp.org
41 React, NextJS, CSS - Live Coding with Jesse
React, NextJS, CSS - Live Coding with Jesse
freeCodeCamp.org
42 jQuery events - Beau teaches JavaScript
jQuery events - Beau teaches JavaScript
freeCodeCamp.org
43 React/NextJS Routing and WordPress API Custom Types - Live Coding with Jesse
React/NextJS Routing and WordPress API Custom Types - Live Coding with Jesse
freeCodeCamp.org
44 React: Working with API Data - Live Coding with Jesse
React: Working with API Data - Live Coding with Jesse
freeCodeCamp.org
45 React: Refactoring Components - Live Streaming with Jesse
React: Refactoring Components - Live Streaming with Jesse
freeCodeCamp.org
46 jQuery effects - Beau teaches JavaScript
jQuery effects - Beau teaches JavaScript
freeCodeCamp.org
47 More React Refactoring - Live Coding with Jesse
More React Refactoring - Live Coding with Jesse
freeCodeCamp.org
48 animate in jQuery - Beau teaches JavaScript
animate in jQuery - Beau teaches JavaScript
freeCodeCamp.org
49 "Finishing" My React Site - Live Coding with Jesse
"Finishing" My React Site - Live Coding with Jesse
freeCodeCamp.org
50 Starting a New React Project (P2D1) - Live Coding with Jesse
Starting a New React Project (P2D1) - Live Coding with Jesse
freeCodeCamp.org
51 React Project 2 Day 2: Learning Material UI - Live Coding with Jesse
React Project 2 Day 2: Learning Material UI - Live Coding with Jesse
freeCodeCamp.org
52 The Agile Manifesto - Agile Software Development
The Agile Manifesto - Agile Software Development
freeCodeCamp.org
53 jQuery: get and set with http, text, val, and attr - Beau teaches JavaScript
jQuery: get and set with http, text, val, and attr - Beau teaches JavaScript
freeCodeCamp.org
54 React Project 2 Day 3 - Live Coding with Jesse
React Project 2 Day 3 - Live Coding with Jesse
freeCodeCamp.org
55 The INVEST approach to product backlog items
The INVEST approach to product backlog items
freeCodeCamp.org
56 React Project 2 Day 4 - Live Coding with Jesse
React Project 2 Day 4 - Live Coding with Jesse
freeCodeCamp.org
57 Chickens and Pigs - Agile Software Development
Chickens and Pigs - Agile Software Development
freeCodeCamp.org
58 React Project 2 Day 5 - Live Coding with Jesse
React Project 2 Day 5 - Live Coding with Jesse
freeCodeCamp.org
59 jQuery: add and remove DOM elements - Beau teaches JavaScript
jQuery: add and remove DOM elements - Beau teaches JavaScript
freeCodeCamp.org
60 React Project 2 Day 6 - Live Coding with Jesse
React Project 2 Day 6 - Live Coding with Jesse
freeCodeCamp.org

Related Reads

📰
I Built 174 Free Browser-Based Tools Using React + Vite
Learn how to build a suite of free browser-based tools using React and Vite, and why this matters for developers and users alike
Dev.to · Utkarsh Bharti
📰
How I Merge PDFs in the Browser with Vue 3 and pdf-lib
Learn to merge PDFs in the browser using Vue 3 and pdf-lib, streamlining document management and reducing server load
Dev.to · sunshey
📰
Trying Declarative Partial Updates: A Future API for Replacing HTML Later
Learn about Declarative Partial Updates, a potential future API for replacing HTML, and how it can improve frontend development
Dev.to · nyaomaru
📰
Debugging React: From Taking a Deep Breath to Finding the Root Cause
Learn to debug React applications by taking a systematic approach to identify and fix issues
Dev.to · surajrkhonde
Up next
The masks we wear | Zora Krstić | TEDxLuxembourgCity
TEDx Talks
Watch →