Tinder Swipe Animation in React Native and Expo | DEVember Day 6

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up noj developers today is day six of November and uh we are continuing our one monthl long marathon of react native tutorials the topic of today's video is going to be the famous Tinder swipe animation and in today's video you're going to learn uh how to First implement the Tinder card the user interface then we're going to work on the animation and we're going to learn how to do that with react native ranimated in the end the result is going to be something like this we're going to have a Tinder cards and the focus is going to be on the actual animation today I'm joined by the special guest cathaline Miron uh who I'm going to introduce a bit later uh but before that let me quickly update about the demember event so during December we are doing one live tutorial every single day about react native and where we try to teach you important features that would uh help help you in your development um process we have individual projects every day and everything is happening here on YouTube and make sure to subscribe to the channel not to miss future videos also if you have ideas uh feel free to share them in the idea board the link to to the idea board you will find in the description below and vote for the other ones that you wouldd like us build dece November is not only about learning it's also about giving back because during this month we are running a fundraiser called education for children where we are uh supporting the save the children organization in their effort to provide education worldwide to our children if you're interested you can donate right away here on YouTube and we also have some incentives if you do so I want to say thank you Rogelio Val Travis and other people who already donated that means a lot and during during December we are also going to donate $100 for every thousand subscribers uh for every new 1,000 subscribers that we're going to get during December but now I think um we are all ready to go to get started with the topic of today video and allow me to introduce cathaline Miron cathalene here you are how are you doing yeah I think the whole Europe like is under the snow right now oh wow yeah we wanted to we were discussing for a very long time to do something together and I'm happy that during this event we finally found a found a a project that we can do together and I'm excited to to learn more about animations from you if you don't know Cataline Cataline has a YouTube channel about R native animations and he's also he also has the animate track native can you tell us a little bit more about that for yeah it's really an impressive it's really an impressive resource for for animations like it has like a really a lot of um uh here we we I'm sharing the the website and I'm sharing some of them have you done the that Tinder swipe animation before on the YouTube channel or oh you MH I see here I see here you have that uh tarot cards animation will that help us in today's animation because it also has like this radial swipe left and right oh yeah yep yep yeah the gesture otherwise cancel y yeah I also think so uh let's start with UI probably the first step is going to be to implement the card then to put them into a stack and after that figure out the the animation part so for everyone who is following along we have a repository uh on GitHub for this project and if you clone the repository and then simply move to the get checkout day six dash start uh we're going to all start from the same code base here we already have a couple of days uh uh oh that's bad yeah uh cannot hear Catalan is it in every scene where is it maybe no here it's enabled as well oh wow H yeah so mixer what's happening here it's coming from the collab track and it's enabled oh boy uh what if we quickly go ahead and join a zoom just to have it as a backup because that will uh at least that will somehow work one second it's weird because they see like in the mixer the the sound is working properly yeah yeah yeah in the in the OBS mixer and I'm going to put it somewhere here and in the coding screen instead of the collab we're going to [Music] do a window okay and waiting for Cataline to join Zoom yeah in a second Cataline is going to join Zoom here is Cataline yes can you open the camera yes you can just make it a little bit bigger so that everyone can see Cataline here we have can you say something oh boy I don't think it still works um everyone can anyone hear me yes now I think they will be able one one this thing audio at least I can hear you and and uh we need to a way for you to see my display right is it possible for you to to to open the the YouTube will it be much I think it should work and let me just quickly right do the same here we have two Catalin for a moment oh streamlab is holding up I'm doing too many things at the same time yeah for me it's not the case anymore because yeah I am on the M3 Max so he's going to handle it he doesn't want to to delete a scene come on okay here on the code part everything looks good it should be laggy for a second but hey guys can you confirm if you can hear us see everything cathalene you're here one two three yep I'm I'm still here yes doing live checks in doing sound checks in the live yes I see that someone said everything is good um yeah it's not caline's fault everything is on me uh but anyway I hope by the end of the tutorial like what you're going to learn is going to be worth a short wait here so here we have our project and as I said we have we are already at day six we have implemented some interesting features uh previously but today we're going to focus on this uh Tinder swipe animation so I have a home screen and I also have a Tinder screen where we will start working so if I go here go Tinder that that's the screen we're going to focus today for the card let's start by designing by implementing it into a separate component right away so let's go ahead call it day six and we're going to need the I don't know the Tinder card let's call it like that sry to interrupt you but can you can you also share the screen in in the streamlabs I I think it's better in there is a 15 yeah the the the link that you've shared initially because on YouTube on yeah on YouTube I have 20 seconds delay so it's going to be pretty pretty hard do you see it now yes okay that's good okay so we have a Tinder card uh it's a simple text let's simply render it on the screen in our our Tinder screen but I can see my zoom call not the code not the code oh it's display capture now is it display yes great yeah yeah it's amazing perfect okay so we have a Tinder card uh let's have a look at the UI the card is quite simple what do we do we need need an image and name age and that's it should we keep it simple yeah and and and and later we are going to add maybe no and yes if but but that's for later I believe yeah yeah that is for the animation like the yes and the nope okay so we're going to start with defining probably the Styles shet to already see something on the screen so as we said we're going to have an image uh the image needs a source with its your right that I don't have yet but we're going to find some images in a moment then we're going to have a text here for the name and probably that's it just keeping it simple let's give some Styles uh my animation here like when when doing the hot refresh uh get stuck on this screen there is a small bug probably there but I always have to restart it styles. name not this one image doesn't exist yep image doesn't exist quickly importing it and we have some some text there uh for the image uh do you have any images on your hand or I'll find something for my dummy data I I think D data it's it's better um you you yeah you can even render the same image uh by the way I I was just thinking uh it's better to share the screen directly in the zoom chat in the zoom let me see if uh only if it will properly work so share uh and I don't want to see my share screen I want to see you that's a bit of a problem you know like when I share I I cannot see you you become a popup yeah I gotcha yeah cannot share it for Zoom is it uh very laggy it's very behind no no don't worry about it you can yeah we can figure it out you you can uh reverted yeah uh okay we will need your input and your help during the the animations with a UI I'm doing it okay so I have some D datas but I'm really not sure what they actually are so okay here we have a here we have one let's do ad dami profile that later will be with receive through the properties now we need the image URL uh and the name and probably an ID so for this image we can use it in the to render it let's go ahead and render profile. image and for the name we're going to have profile dot name at this moment we're not going to see the image because we need to to style it so let's add the styles for the card let's add the styles for the image and the styles for the name so as soon as we are going to give some WID and height should I start with 100% Flex one I just want to see it on the screen come on I think I pasted it two times yeah the URL is wrong yeah now now it's better how would you style the sizes of a card I think I can um it's either based on the screen width mhm right so so y um or we can Define it outside as a constant I don't know hardcoded value or based on the screen size uh but uh it should be somehow outside so you can have access to it where you render the list itself and also for the card because uh based on this wi we can Define how much to move on the left and on the right right so recommend having a hardcoded withi exported from here yeah usually I use the uh Golder ratio so uh I I Define the width as uh let's say 80% of the screen width and height is going to be the width multiplied by 1.67 67 so with an aspect ratio okay so for the Tinder card do we go with a hardcoded I don't know value like this uh uh you can also import width and height from Dimensions uh you can import Dimensions from react native and do with con with height it's equal to Dimensions uh that get screen screen. wi multiply by you said you don't want full wave you want 80% or how much yeah yeah 80% do8 0 point and a good thing it's uh usually I name the constants differently it's definitely lowercase uh uh like Star case is is lowercase U and yeah something like that okay and and the height is going to be this Tinder card with multiplied by m 1.67 um multiply by 1.67 what's this 1.67 is it the is the gold ratio is the golden ratio uh what if we use the aspect ratio 1.67 without having to to multiply it or it's the other way around it should be 167 by uh by 1 I believe um divide by one but uh if yeah if it's divided by one by simply sending it like this like it's it's um but I think it's other way around one divided by this right yeah it's with with with and height then yeah this is the correct figure okay now for the image maybe we can use a flex one uh I I'll do directly in line stylesheet absolute F object and then uh I will add styles. image so you can do whatever with it would you do it like this here Styles shet do absolute field object or you would combine them together in an array when you send the Styles it's an array it's an array and I'll do it in line uh sty shet absolute F object it's in line uh there is no performance difference between inline Styles and styles you create besides the reusability um I don't and maybe to put the styles of the image afterwards yes okay uh perfect so we have something like this uh we need some some round corners that's definitely for sure I am an expert in that uh border radius 1050 uh and yeah it should be overflow hidden yes and overflow hidden because the image is overflowing and it's visible but if we say overflow hidden the image will everything that overflows will be hidden uh okay one thing here is that if you're going to apply any Bo Shadow uh is not going to work uh yes so in that case that's very true like if we go ahead and generate some Shadows which I think we will I'm always going to this generator not sure who built it uh but it's quite useful like something like this and I can add the Shadow and it's not going to be visible because the shadow is also something that overflows so we will have to uh disable the Overflow hidden and how I solve it is I add the same border rues to the image as well and now the image also is rounded but and the shadow is visible below okay so for the name the name is rendered after the image but I think we need the oh but that's the absolute F so for the name uh Aline self will it work justify Flex end that's going to be no to the right margin top AO I'll let directly to the card itself I will uh yeah I will I will align items flex and um so in this way uh all the content is I don't I think it's just F sorry justify justify yeah it's Direction row yeah it's always like that we try one and then we we we switch to another one if it doesn't work yeah and and and the thing now here is that you need to wrap the name into a view because you are going to add multiple things inside inside it right so so now it's going to work out of yeah that's true uh I will just change the font the color just for us to see it and if we will need to add some spacing we can add it on the name but as Cataline is saying like later we can add more things in that row such as yeah like basically like a footer so it's better to start by creating this view with style footer and that will have currently only the name inside but later we can add other things so for the footer we're going to have some padding and here we have it I'll I'll change the font family here to an inter bold maybe or semi but bold I think is okay and should we do some kind of gradient background transparent to to make the the name to more visible because right now like if the background is is light like it's not going to be very visible yeah sure we we we can definitely do it you first need to install Expo linear gradient yes Expo linear gradient let's go ahead and install that one I have also built in the past uh uh react native CSS gradient so you can paste CSS gradients I I think it's outdated now but uh yeah anyway yeah it's nice especially if you're shamelessly logging yeah yeah exactly cool so everything good on the stream I I'm not following the the live chat but I hope everything is good okay so now that we have a linear gradient let's go ahead and just copy it from the documentation and we will put it also as an absolute uh we need to put it be after the image to be rendered on top maybe but this is going to be yeah yeah I think uh in between the image and the view yeah and we will also do a absolute fi No No I um or you or we can um we can have the the content as Childs of a linear gradient or we can do it as absolute feeli self closing no no no Ju Just do absolute feeli and do top 50% something top 50% yeah on to basically cut it yeah here uh to the background Styles apply like a top 50% absolute F object Maybe oh you you should place it after afterwards because it's going to overwrite it it's going to be top zero that's true okay and we're going to go from transparent to a darker color and I think that looks already good the the text now is much more readable than if we don't have a gradient especially on light up you you also need to add the board border um border radius to the bottom bottom left and bottom right border uh border bottom left radius 15 and Border bottom right radius 15 and I think now it it actually can go into its own Styles yeah I we we can optimize this uh really really deep is like uh to to to avoid the the Border radius duplication uh you you can have a view that's going to contain the card and another view is a sibling that's going to have the the shadow anyway let's yeah yeah let's let's focus on the bigger picture uh okay yeah I think I think we are good with uh with a Tinder card uh probably the next step is instead of uh having the data here is to send this data from the screen so I will start by simply moving the data about the profile to the Tinder screen here and by simply sending the profile here to is it a user is it a profile is it doesn't matter it's going to be information about the user so I can do user and now in the Tinder card we're going to receive this user as a property and of course we can also Define the type for the user but I'm not really following like implementing all the types right now so user can be at least something that has a an image and a name now let's type the our properties with this one and we will use user. image and user. name here and now our card should display the same but it will get the data for the properties and now it's uh it's probably time to generate an array of these profiles and to to render them in a list right yeah so let's do users maybe I I should use chbt to help me with this where I will simply duplicate it a couple of times um let's just change some IDs uh I'm going to change some images I don't know what's there because they are quite old dummy data and I'm not even sure that they are uh and now in the Tinder card if I will just simply send user at position zero users at position zero that should render the first one okay so yes now it works um the next step is going to be to render the whole list the whole data as a list list of Tinder cards are we going to use a flat list for that or no no no just just a view and render everything inside it and positioned absolutely with uh with mapping just to map over everything yeah yeah you um and and uh if someone is going to think about performance uh uh you you can optimize it and and uh do a slice uh from from that array and whenever the animation is going to finish basically you move a card outside after a period of time you can remove it from the do as well uh from from the render but uh let's not think about the performance optimizations but thisa so I'm mapping through all the users and for every single user I'm rendering a Tinder card I'm sending the key from the ID of the object that we're rendering and the data about the user to our card now we have them in a all on top of each other we cannot scroll yet it's not as scrollable but Catal will tell us the next steps how think so first so so the first the first thing is you need to create a stack right so everything should should be stack on top of each other so the uh Tinder card should uh receive the uh the total count of users okay and also the current index okay what index is he rendered based on which we can uh uh you'll see so yeah first the the users count and then the index so when you map you get the index and uh yeah so the Tinder card uh card will receive number of cards uh and this is going to be users. length basically the length of the whole array of cards and the current index or something like that is going to be index now we're going to receive this as properties inside the Tinder card so besides user we're also going a number of cards as a number and we're also going to have a current index also as a number now we can destructure them from here number of cards and current index and based on that we're going to do some magic as I as I guess yeah yeah so um the the next thing is uh you need to position the cards absolute uh so the the card itself should be positioned absolute and because the mapping uh so Z index uh deeper you go in the three the the greater Z index become right yeah so this means that the the first card is going to be behind everything right so it's first card then on top of it is the second one and so on so forth but you would like to reverse it so in order to reverse it you need to apply a z index the card length minus the current index so you swap it right okay U so you are going to start from a greater Z index but decrease it right so in this way uh you see now Kelsey is the last card right because you positioned it absolute but if you go and add in line Z index uh uh to the Tinder card Z index it's equal to the number of card cards minus the current index uh for the first card the current index is going to be zero right so it's going the Z index is going to be number of cards for the next one is going to be number of cards minus one and so so forth so you decreasing do index you're starting from high number and decrease it um okay now now now because we have Define this uh we can either create um a stack kind of like situation uh like uh the first one is going to be really big and then the next one smaller and smaller and smaller and we can also send how many cards we would like to display because if you have let's say 20 cards you just want to have uh this like Tunnel right you first card second one and so on so forth but you'd like to cap it at a particular number okay I don't know we we can create this effect if you'd like uh but otherwise we can uh start with the gure I I don't know it's up to you okay first of all um first of all I'm going to go ahead and do a style here to align it in the center because that bothers me a bit justify content Center okay and I will even go ahead and hide the stack uh do screen I will hide the header so options so but you you were explaining me like this stack or like to to be visible that there are cars behind but how they will be visible if they will be smaller than this one will we shift them somehow like to the left to the right or because if the yes the cards behind will be a little bit bigger like we will be able to see them yeah we we can scale it uh we can scale it but also TR uh and move it up or down uh so uh what you can do here uh we are going to create the same like meth formula um you can define a maximum number of visible elements we can we can actually display everything all together but create this infinite like uh scale it but also move it a bit right so I I believe it's better to start with the scale and move a bit and then we can Define how many items to be displayed yeah and as I understand like this scale will depend on some uh parameters so I'm going to do them here in line so just for us to to see how that would work without like a lot of math that's going to be a transform right we're going to use a transform yeah and we're going to scale for example uh to make them lower do we will we want to decrease the size from the corrent size or will we want to increase it uh we need to uh decrease it yeah to decrease it so if I'm do 0.5 the whole card and every card is going to be uh half the size but we don't want all of them to be decreased in size we want the first one to be full size the next one a little bit smaller and so on so it's going to depend on the current index uh I can calculate based on the current index how much I should decrease from the full size so if I do one minus current index multiply by 0.1 every uh when the next card will be 10% smaller the the third card even smaller and so on right I hope yeah it's uh this this thing it's called linear interpolation or lurp for short so um you you uh um so so the the the how to explain it um we are decreasing the size linearly yes yeah exactly so um so you can Define the range right so um um how to say it um we can have like um an array of different values and based on the index to take them from where yes so you you basically have the current index of the uh of of the card of the card right yep and um so 0.1 yeah I think I think this is yeah if weac I think this is okay if we decree opacity this is okay to see like through them like we see that every next card is smaller and smaller and smaller yeah yeah it it's okay but but now you you also need to translate y to translate why uh in order to see them a little bit on the top right yes so that's going to be another object here in the transform Translate Y as well something related to current index and multiply by how many pixels we want to translate every card so 10 probably is going to be too too little and it should be minus because you want to translate them up okay uh and you can also keep for for the moment the opacity as well because it's okay okay yeah so uh this is moving quite quite nice yeah I I think uh uh uh you can decrease a bit the the Gap itself right um maybe 0.1 is too too much I think that you also need to translate first first you need to translate and then you need to scale first to translate that that has a difference yes yeah because the scale is going to be apply to the translate uh maybe you cannot see it here but uh yeah the the the order matters because now you can also add another translate and it's going to apply the translate to the scale as well there was a missing um image but now it's there so it works okay looks good so far I I think that you can uh do multiply it by 30 let's say or 35 um it's it's too much I believe okay something like this 30 yeah something like this yeah yeah and and now you you also need to lower the opacity right deeper you go mhm yeah deeper you go uh shorter it gets so it's going to be uh if one is for the first card uh that means that it's going to be one minus current index multiplied by something uh even more than that yeah yeah something like that and as Catalin is saying like if you would uh improve a performance here as you can see we only can see like around three four or five cards uh after so to increase the performance you would simply stop rendering the the other components if they are too far if their opacity will become basically zer Z or insignificant but we're not going to focus on that I I would like to like stop here a little and integrate animations uh so as you can see there is a lot of math and a lot of hardcoded things right uh and uh meth especially around the linear interpolation it's it can be really complicated yeah uh and instead you can use the interpolate function yep from reanimated for example to define a particular range uh and after that range when the interpolation is going to be extrapolated the meth is going to be done by by that function right [Music] so what I mean by that is you need to create the active index as a shared value and send it down to each individual Tinder card MH right so you are going to define the top level uh a shared value let's say active index which is a shared value starting from zero yeah here uh I use Share value from reanimated starting from zero uh and we're not going to need the index anymore right because we are going to need it because based on the index we are going to define the input range yeah the index is it's simply it's position in the list but active indexes which one is we are currently looking at which one is the first yes exactly B based on which we can Define some some interpolations and some animations and this active index is going to be the truth right yeah uh this this active index is going to determine hey this is the active uh the active Tinder card but also is going to Define uh some animation with within each individual Tinder card basically if you are going to swipe right or left we can uh uh uh animate the active index from 0o to one let's say with 0.1 0.2.3 and so and so forth so everything is going to be animated right okay now now inside the Tinder card let's let's create the the interpolations and then we are going to move to the gures so Tinder card is going to receive this one right active index it's not number it's uh it's a shared value by the number as a number shared value Yeah by a number and uh what we are interested now we have the active index which is saying which card we are looking at but uh the Tinder car can be an index we don't know exactly the index right but we know its own index so we can Define the input ranges index minus one and index + one right this is the the range that we are interested for each individual card and uh apply some different styling like U opacity for example so if you go to um uh uh let's create a a use animated style because we are going to land it into the reanimated world so Define a a style as use animated style and and uh this is basically a Styles sheet create like a but but it's reactive to uh the animations to the shared values right so whenever a shared value is going to change the use animated style is going to be triggered and recalculate everything so here you you you can return no no just return directly on an object yeah and uh let's uh Define first the opacity let's see so opacity is going to be an interpolate and we are going to interpolate the active index yeah let me quickly say 0.5 and assign the animated card the animated style to the existing list of styles that we have here I think it's going to come probably here and I'm not sure what's happening here with the use animated you you need to return an object do I need to it's a method it's a method it's a method that's going to return an object an object like this and now I will delete the opacity from the hardcoded one from the static Styles because we are added it into the animated Styles and let's just see if the opacity is applied and then we can move on to think about the interpolation it's value um yeah you you you you are missing the most most important part and that's the view should be an animated view yes that's exactly whenever we have animations we need animated. view so where is it here let's import animated and let's transform our view that we want to animate to a animated. view I need to disable probably the the intro animation there for for the splash screen yes so as we can see the opacity uh is applied but now we can apply the animated values here that will move from from one value to another very smoothly so what we want to do is we want to calculate the opacity also based on the on the which card is currently active which card we are currently rendering and based on that to get the them yeah depending on how close it is to the current one the opacity should increase so an interpolate uh yeah we are going to interpolate the active Index right interpolate the active index which is the truth right which one is the active dot value dot value and then the input range is going to Target the uh uh the neighbors it's index minus one index and index plus one so uh Tinder card let's say Tinder card number three is going to Target uh the Tinder card two three three and four right the neighbors and what it should happen with the opacity when uh we are in this range uh so for the opacity this is where uh some things are going to change in terms of math so for the opacity we would like to start uh when the index uh when we are at index minus one is basically the next item we would like to decrease decrease the the opacity so we are going to no no no decrease the opacity so we are going to say uh one let's say uh and then minus uh one divided by let's say five items we would like to display five items oneide by five yeah and then the rest we can keep it at uh at one at one and at one okay I Chang I Chang the name to to index just for us to to to to to talk about the same stuff uh here index so uh let me let let us see this one okay yes the first one is one the next one is a little bit less and less and less so how this works is Tak taken that currently active index uh well when when you understand interpolation it's so easy but expl yeah sorry yeah let let me let me go through it because uh uh I I I I gave a talk at tjs last year talking exactly about this this scenario so index minus one is the next item right because right now you are uh uh what what uh index minus one is the is the next item in terms of the the current Index right so uh uh you're moving in in the future with the index minus one index plus one is saying what is going to happen when the current index is going to be decreased uh how to explain it properly if we if we're past that so I don't know maybe I can I can bring like some cards we can show like some some expl but yeah basic but but in a natural index minus one is the next item from the current index um uh basically when when you animate uh uh any active index from zero to one right y uh the the the the index is going to move on the right hand side so it's on the index plus one range and when the index uh index active index is going to be decreased you are going to SP you are going to come from a bigger number to a lower number in terms of index yeah how many is so hard without me having some physical yeah but but but the idea here is that now uh now uh you you you're just specifying because this is uh uh the extrapolation it's uh extending it's it's going Beyond this range right so uh the reason why um let's say the fifth item is still visible is because the interpolate uh was uh guessing the number not guessing but approxim approximated it's it's an approximation is not the it might be the the real number but it's an approximation what's going to happen when I'm index five uh right it's it's going to so now you have oneide 1 - 1 / 5 but for the next item it's um 1 - 1 divided by five minus the previous the previous the previous value so this is going create a linear a linear um graph let's say of opacity yeah yeah it's it's it's exactly like Fibonacci right it's adding the previous value to the current value but but now if you are going to add a scale let's let's go with the scale because it's easier to visualize it okay so with the scale it's it's going to interpolate the same active value the same input range index minus one index and index plus one so if I had here this scale this scale scale is going to be also an interpolation of the active index value the first uh array is the input range so it relates to the active index so we are going to have like again like the previous card the current card and I mean the next card the current card and the previous one so how should exactly yeah how should the card here in the second range we're specifying what what should be the scale value like to what range we want to map so when for example in the middle this is the the easiest one because in the middle it's how do we want uh the scale of the item that we currently see in in front of a stack to look like the scale should be one so I'll put one here for the first range how do we want it to look at um based on the how do we want the next card in line to look like the next card will be smaller in in size so probably it's going to be also something like 1 - 1 / 5 no no that's the trick that's the trick so the thing is that we we did the one minus one divided by five because we would like to cap uh the the items to five visible items so that five it's how many items you'd like to make visible yeah but with the scale is different we would like to let interpolate do the math for us so we will say if you are the the the the next card uh you are scale 0.95 so here 0.95 yeah yeah something like that and now the interpolate is going to say okay so we are at active index zero we are the the index right index minus one is going to have 0.95 the next card is going to have 0.9 the fourth card is is going to have 0.85 because this is how interpolate works right unless we um we say that this should be the only range unless we how is it called capping yeah extrapolate clamp but we don't want to clamp it yeah we don't want to clamp it and that's good because you you think in a very short range and you say like everything else like calculate based on what I can visualize in my in my uh memory in my head so the one that comes in front do we want to leave it as one or do we want to increase it a bit in size yeah just leave it as one okay leave it as one yeah okay but do we need that one and one I think we need or the other solution would be to clamp it on our way but I don't want we will not get into that we we can clamp it so extrapolation uh can can have extrapolate left and right so we can say extend on left but clamp it on right but keep it as it as it is now cuz on index plus two is going to be one as well because the previous value is one so there is no math to do right yeah so I will uh remove a scale that we have here and let's see our interpolation for the scale yeah uh and and uh I I believe the trans form it's it's uh is not working in this case now oh the second one maybe I'm overriding it because it's it's also transform ex and it's an array you have two transforms yes so so let's let's move the translate as well uh because uh so Translate Y is going to be the same interpolation but this time for the index minus one we can say I don't know minus 30 okay so Translate Y is going to be interpolate uh we are going to interpret the active index value from the same range yes uh to the values so again like the the one in the middle is the easiest one uh it should have zero translation it should be exactly in the position it appears the previous one should be a little bit to the up so that's a minus right yeah yeah minus 20 or minus 30 minus 20 andever one we will keep it zero as well yeah so in this way the next one is going to be minus 20 the second one is going to be minus 40 so it's like it's uh based on the previous so I I believe yeah you can uh so now you see there is no math involved you just Define arrange and based on which yeah is going to be yeah especially like in in in more challenging uh map interpolation like having the interpolate function like makes more sense like after you understand like how how things work okay yes yeah uh um so so now we we have this uh the cards right and and now we um the thing is that uh in the future we might need the uh Translate Y to be different right so how how do we how to say it uh is the panure going to work only on the xaxis I don't know um I think so I I don't know how Tinder is working let's do it only on the x-axis yeah like if you swipe left like it will move left into yeah okay cool uh so so now we we need to include the pan gure right yeah so uh the P gure we are going to use gesture Handler from from softer Mission as well so on the Tinder side so uh we are going to wrap the entire Tinder list with a gesture detector so the entire so the entire list we are going to put it into the gesture detector yeah this one is going to work only with one child I believe so I I think that you either can wrap the entire view or just the wrap the the map into another view whatever works for you I think this one will work and we can simply not to have a stack information there I'm not sure if it will have any implications it's not going to affect it's it's a it's a shadown yeah okay and so gure detector it's is a component that's uh going to receive a gesture so the gesture can be a list of gestures can be whatever but it should be some gestures and uh the for the gure we are going to use the the pan gure so you can uh uh import uh gesture detector but also gesture from gesture handle gesture or directly P gesture no no no no no the gesture okay and we Define it in our component as a constant const pen I don't know it's a Handler so it's going to be gesture dot pen here which is a method and yes it needs yeah it has some call back functions or it also has directions I learned about that recently uh oh that was that was a fling no no no that was a fling animation so yes yeah only the fling has has Direction um with pan is different so uh what what we can do here we have couple of methods right we have on on begin on finalize on start on end right so we uh uh each individual function here is going to receive the event the event is going to be where where where the the touch happened um so uh to to remove any confusion is like there are uh two methods that have a counterart method as well like on begin counterpart of the on begin method it's on finalize so if you are going to do let's say uh the pan it's active you are going to set it on begin you need to unset it on finalize and the same applies for on start you have on start and the counterpart it's on end uh those are the gestures that are going to Define start and end right and then you have the on change event uh and also there is on update I believe but on change we're going so uh uh I hopefully there is not that much uh uh is everything okay so far uh I think so okay yeah yeah I'm I'm listening I'm hear I I hear about this I'm doing a console log just for to to show people when this things are being called um what's the difference between the on begin and one start yeah so on on beginning it's exactly when you touch the screen okay and on start is when the the pure is triggered okay because yeah not all maybe like a tap is not going to be detected as a pen gesture so on start will be called only when the gesture is being detected like okay we understand this is a when when when yeah exactly when when when the the pure is going to be cold actually so uh yeah you and and now because we have created a gure we can pass the gure uh yeah exactly so if we look here we're GNA not here come on we're going to say I'm going to start panning so we see at the top on begin being called then the the pen pen gesture is detected and the on start event is called then as long as I'm panning this function is being called with the event that contains information about like how much we moved where we moved on the screen and at the end we have as Catalin was saying like the counterparts of the first functions so first like the last one was on start so to finish it it's going going to call the on end and the on begin is going to end with the actually on on end here I'm not sure it's on finalized yeah you you you misspelled it so yeah the the last one yeah yeah uh yeah exactly okay so so basically on finalize is saying there is no pure anymore okay so which one will we need probably not all of them so not all of them but uh I uh the the most important one is is definitely the uh the on update pretty much so on change on change so so so there is a thing right um uh how to say it so on on change is going to give you like uh everything that's that has changed but there is another there is another method called on update that's going to give you how much was updated so in in addition to the onchange uh event uh payload uh you are going to have access to two different uh quite important variables which are uh change X and change y uh in the past a lot of uh developers that are trying to do uh gures uh on uh for the on start event they had to or on begin event they had to memor memor memorize the position right and pass it as a context pass it as a context and when the unchange was trigger uh uh you are going to add on the translation X or Y the context but we don't need to do that anymore right uh you have translation X and translation Y which are going to to do this math for you but you also have the change X and change y uh do we still have it on the own change event you said that that's going to only be in the own update but I see from the types that it's there so I just want to to have a look at uh I I think on update you don't have the change X and change y on the on update oh yes you you meant you meant that's why we need the on change because it it also has the change X okay we we can use anyway either of them it doesn't matter because we going we're going to use the one that's easier yeah we we are going to use from the event only the translation X because this is what we are interested in right okay so uh the event is going to have a translation X and it's going to say as long as the gure is active how much have you moved on the x-axis mhm so uh yeah you can conso look here the uh translation X and you are going to see that if you swipe let's say you are going to have like if I swipe left it moves like to a lower number and if I swipe right it moves to a higher number and it doesn't matter where I start even if I start very very far right and I move like it detects like how much I moved there so it's relative trans uh it's relative to the point where we start the the panning or no uh can you give me more info what do you mean by where you start so if I start from the middle of the screen and go halfway to the right that's going to be like I know half of a screen um the transation will be yeah yeah if I start beginning it's this is going to calculate based on the start position and uh the the start position is zero right so uh yeah this is how it is the translation translation X and Y is going to keep reference uh for the beginning right yeah perfect so with this translation x uh what we can do now is uh we can Define another shared value let's say translation x uh that's going to start from zero and uh while we are receiving this event uh for the uh from the gesture we can uh change the value of that translate X to be the event translation X so translation. x value it's equal to event translation X yes amazing and and and now we basically modify right we modify the translation X to be where the finger is yes and uh we can move we can pass this translation next Share value to each individual Tinder card and do some something with it okay so I send it there let's go to the Tinder card add it uh as an extra property here translation X again I'm doing the same mistake and let's destructure it from our array and based on that uh probably we're going to translate on the x axis the first card only the first card right yeah yeah yeah exactly uh so uh uh here you can add a translate X and translate x uh we can say if active index. value it's equal to index which means that we are uh where we are [Music] mhm uh we can uh we can say uh if this is the case it's uh translate x. value otherwise it's uh it's zero and this way because we have a conditional it's only going to be applied to the first to to the card that is currently on top of the whole card initially this is the card at position zero but as we swipe we're going to move so just like that we can drag and drop this card on the screen yeah but but notice that you you can move it let's say yeah like that um uh so you if you release the gesture uh you're not going to come back right so we can add this as well so if you go back to the gesture M we know that uh we are going to enter let's say um on uh finalize in the on finalize just do on end on on end let's reset the translation x value to zero but not like that you can do with spring oh with spring to zero of course so and going because if it's like that it's going to simply jump back when I release but we don't want it snap directly into place yeah so the with spring if you define with spring to zero what's going to happen is it's going to animate from the previous translation X which is I don't know 20 100 to zero with a spring so just like that it doesn't jump it moves there yeah for for me it's really hard to see the simulator it's but hopefully the animation is going to work yeah yeah it's it's smoooth yeah like the spring animation works perfectly okay cool um so so now the card is coming back right and what we would like to do is we would also like to rotate based on the position right so if you pan it to the left we would like to uh rotate it uh with a minus some degrees if you move it to the right we would like to rotate it with plus some degrees let's start it simple so a rotation is also a transform right yes yeah it's a separate transform rotate do we rotate x y z uh that's always yeah so in 2D you need to rotate z um okay uh uh oh man if I had some something to draw so basically Y is vertical X is horizontal but Z is what you see basically rotate around that Z it's I I need time to that it's saying Z is saying move it like this yeah Y is saying move it like this okay and X it's it's saying move it uh like uh like a a roll yeah okay so now if I have rotate Z 30° I see that it rotates right if it's minus 30° it all of them rotate States left so we're going to need to interpolate from or no we can use directly the translation X right because that is a shared value yeah yeah we we can uh but still interpolate because yeah we we we can interpolate and we can define a range uh from I don't know minus we divided by two zero and we divided by two right so this is the maximum range that you can swipe yeah so we so the wi of the screen sorry we interpolate the translation X yes and the values that is going to so the translation X can be can we do Z minus one zero and one but no no no no no it should be minus screen size we we we we we can do it right it's you need to define the the Caps the the the the uh tail and the head yeah so you can Define let's say how much you like to move basically if you move it all the way to the left which is weave divided by two let's say uh you would like to uh when when you are with a finger at minus with divided by two you'd like to have a minus 30 degrees right but in between You' also like to animate it so if you are starting from zero it's zero but then uh further you go you'd like to have it maximum 30 degrees so can I use the Tinder card WID divided by two not exactly the screen WID of course you can use whatever right and the on the left is going to be minus 30 in the middle zero and then 30° and we simply append like the degree here is there a different way or that's how it works no no no this is how it is okay so now if I swipe left yes all of them are are uh Rota so we need to yeah because the same the the same in active in this uh yes if then is going to be this one yeah we could add it also like inside here but yeah think we can you you can move it even deeper yeah so you can uh you can only affect the current uh the current one only by yeah but but it's more more meth to do more more things more props to pass but I believe this should work right yes it goes what what does your designer eye say it's too much I think yeah that's why it's better to not rely on on the card but rather on the uh screen with so you can say you know if you are with the finger at the edge of the screen with I would like to have it I don't know 50° or something right because you don't know exactly the card with uh or maybe you you can also Define it based on the yeah uh so I can go with a screen wave uh yeah because it it will make more sense because the gesture is happening on the screen it's not necessarily happening on the card so I can do screen with screen with and maybe as you said 30 is too much 15 yeah I think 15 it's it's okay shouldn't be that much it's more natural we can of course do meth right so longer you go from the the initial Point uh we can uh calculate the angle using arc tangent but I think it's too much for this live stream definitely we can definitely do it okay so now the movement the gestures are working properly I think my in my opinion The Next Step would be to understand and to to change the currently active index basically to yes to display the X Card yes so so uh uh one one thing uh what we can also do change the active Index right while we pan it so we need to define the ranges it's minus screen wave divided by two to screen wave divided by two right that's the range so uh closer you go to the edge of the screen uh we are going to increase the uh the activ index so if you go to the gure pan here can I just ask you does that mean that we shouldn't think about active index as 0 1 2 3 we should think about like how close it is to one so a 1.5 is going to be the moment between the first and the second card in the middle and that will also because we are using the active index to drive animations as we will swipe the next ones will start basically moving towards Us increasing in size decre increasing opacity so this way like the active index shouldn't be like a very fixed like 012 but a value that moves through this uh through this range right like a progress yeah yeah so based on the translation X we can change the active index yeah from incrementally like uh with decimals right yes so for the onchange event what we can do now is is uh let me think about it for a sec cuz um okay um we are going so we need to also clamp it I believe no we don't need to clamp it okay so will it will um will the solution be if now we we don't do that we simply change the active index to one two three to have like these jumps and after that we can think about how we can animate or do you think it's better to start with animated no no yeah yeah Ju Just just to move from one index to another and then we are going to do this interpolation so uh that should happen when end animation right no uh uh we we need to to yeah yeah sorry sorry yeah uh you're behind yeah so for the on on end event we need to get the on end event has the velocity So based on the velocity we can calculate hey is the user actually pan it really fast uh if it's if it's the case we can uh uh uh move it away right we can uh change the translate x uh using the decay uh well actually it doesn't matter uh yeah we can we can use Decay so we can say uh on finalize we are going to get the uh velocity yes and we we are going to say if the absolute value of that velocity because velocity can be negative as well uh so velocity is acceleration right yes so we can say I conso loed it uh I conso lo it and I showed uh when I I drop I mean I lift the finger when I'm swiping very slow the value was minus 175 and when I did it very fast it was around 3,000 yeah so based on that yeah I think I think 800 I I think 800 it's it's a nice spot so we will say if if the absolute value of the Velocity X it's greater than let's say 400 let's let's do 400 for now we we can play around with it now we are in the case where the users pan really fast so we would like to change the translation X so we are going to say translation x. value it's equal to with Decay towards towards an extreme right we need to to swipe it like either to the right or to the left completely depending on yeah this is uh done by the velocity X so the DK it's it's velocity acceleration based so this is an object right so an object and where we can pass the velocity so as the key velocity x [Music] m and pass the velocity here and yeah just just try like that because we need to clamp some variables and things like that so like if I drop it very fast like it moves like really far but if I drop it slowly it can yeah continues to move but it stops yeah it stops yeah it's okay uh so what oh so with Decay I I just realiz I I didn't use the with Decay but that basically means like continue the movement uh starting with this velocity but reduce it like until it reaches zero right so it looks like a a ball that is rolling and started to slow down exactly yes uh okay uh but but but what what what we can do is actually use also with spring here m I'm not sure if uh let me check the documentation uh yeah we cannot use the we timing but what we can do is we can uh we can use with spring as well and pass the velocity there so uh uh uh if if you say with spring let's say let's try that with spring and the with spring you you need to go to a value right and in order to find the value you need to get the uh the sign of of the Velocity which is minus or plus so you can do math. sign event velocity to understand if it's moving right or left and then this is getting minus or plus by byy some value and I think the value can be the screen withd so we would like to move it away from the screen I don't have it here but I can just do 500 or something yeah you can hardcode it for now uh okay and does it also have so now we move it and and for the config you can pass the velocity okay velocity velocity it's even that velocity X okay yeah now at they are moving away from the screen think it looks nice yeah it's it's it's better so I I wanted to show the Decay because in this way uh maybe you don't want to make them outside of the screen always visible but yeah okay so now when when this uh uh this spring actually ended and we can uh there is a call back function on the wh spring on end yeah but we don't want to use it okay that's the thing because the spring uh uh it's it's really hard is not deterministic M so it's really hard to actually determine when it's going to finish so it's not deterministic and instead what we can do is uh we can interpolate uh the translation X and uh change the active index based based on the uh 500 and that would happen also in the on end or outside uh on end yeah on end so we need to change the active index do value here I didn't understand fully so active index. value we need to change it to the next one yes yeah yeah so so here you you can do interpolate as well you are going to interpolate it Translate uh uh the which one to interpolate yeah you can interpolate the translation x value and the range is going to be minus event velocity multiplied by 500 uh zero and uh the absolute uh you can do yeah you don't care right uh actually you care no no you don't care about the direction right so it can be inter one yeah so you can interpolate directly the absolute value of velocity X and zero yeah so what we want to do is like when the translation is all the way till I side left or right we want to move to the next index and the output is going to be active index. Value Plus One and zero active index. value + one and zero I'm a bit skeptical that this will work and if it does maybe I don't understand something but let's see so we are on the Danny card if I throw it away and I'm I'm going to explain in a moment like why I'm come on I I'm not seeing like 60 FPS but for some reason I also don't have 60 FPS uh after swiping the first one uh it it stops uh you know what why I think it's it's the the reason is because because you haven't multiplied with 500 so you can Define here the translation xit is different right translation x uh [Music] you translation here do I need to multiply uh yeah so so the translation X is going uh from velocity X multiplied by 500 right no so translation X you can interpolate translation X but the input range is going to be the absolute value multiplied by 500 yes yes yes and uh I believe in order to make it even more realistic you can decrease the 500 to be half or something but let's let's see if this is working no it stops let me let me let me explain like my uh my my my thought why this might not work basically this one end event is being called only once here in a way we are kind of scheduling that change of translation X and we are calling and we are using the translation X right away to chck to to calculate a single value so it's not going to update every time the translation X changes and that's why initially I thought like maybe it should be outside like whenever it changes or like a effect or yes or you are right yeah you are right so we need to extract it outside this interpolation in a derived value so we are saying uh you can use uh so if active index is not going to be a shared value but rather a derived value is it use derived no no no no no you you can leave it as a shared value but then you can have a use the right value don't assign to anything okay okay sorry sorry uh just here use the right value for example maybe at the top use derived after translation X yeah exactly this is a method that's going to return another value which is going to be a shared value but we can also change things uh here yeah so here it's an object and you can return the interpolation uh the active index. value it's equal to no no no just active index active index it's this is more like a use effect okay so I don't have to return I have to just set it yeah does it also have some dependencies here or it knows what it depends on it knows you can also Define the dependencies but now you don't have access the velocity so instead what you can do is uh you can have the input ranges let's our code everything minus 500 Z and 500 and uh you can also interpolate the absolute value of translation X and just do 0 to 500 translation x 0 to 500 here oh okay okay I I I got what you mean so instead of having two things here I can do MAF do absolute right absolute value it's going to go from Zer to 500 if it's zero it should stay zero if it's 500 it should move to the next one yes oh come on and what do we do with this use the right value uh nothing really oh okay this should change the active index when translation X is going to change hopefully something is happening with the with I see that something is happening with the previous ones they are coming up but with the first one something broke the first one on change the translation if I don't have this one it work but if I have this use the right value maybe the active index oh yeah you know what the active index changes and it become the the checks that we have in our Tinder card where we check should it apply animations or something here where we do active index. value equal equal index now because the active index is not 012 3 it's it can be 0.5 it doesn't work like this so probably we should look if the difference between them or how if it's close enough if the difference is more less than one uh I cannot see the screen exactly I I I don't know exactly what's what I I know what's happening kind of like I'm trying to like uh compile it into my head the thing is that when you change the Translate translation X the items are going to move closer to you that's that's for sure but uh you I think yeah I think uh I think you can uh you can do it differently so on finalize actually when you have the spring thing but anyway I think the uh the problem you just comment com comment this this part here because uh it's not needed just comment because we are going to bring it back yes but now if you go on the uh I think it's on end here on yeah on the on the with spring let let's do the Callback here yeah let's do like if if I need to go thr wave a card and simply increase the uh the active index do value to active index do Value Plus One yeah yeah but you you have the call back anyway for the with spring if you'd like to use it so you can uh have the third argument yes uh as as a as a call back and this call back it's uh I think you also receive the is finished as a as a param so you can check if it's finished increase the index finished yes so if finished and and instead of snapping directly to uh active index plus one you can do uh with spring as well active index Value Plus yeah but if I if I'll do that um I think we're going to get into the the previous problem but we we can think about how to fix that as well so we can do the with spring towards that direction and if I go there active index it should work is not working or I cannot see like there are so many dropping frames uh it's something is working uh but first of all the problem that we currently have is that now that the active index is a floating number our checks that we are doing inside the Tinder card whether to animate even like for the gestures they are not going to work like and the because the value is not going to be exactly equal to the index it will be something close to the index but we have equal sign here so as soon as the active index become not zero but 0.1 this check is not going to be applied it will think like oh it's not the first card and so for that reason I think that we need to do if active index. value minus index if that is less than one that means that we are maybe not less than one but something like that like if it's in this range and I will actually extract it into a variable should I do it but the thing is that you animating the active index only after the spring has finished I'm animating on the spring is finished so it shouldn't impact that much I I don't know exactly what's happening so was what the issue because uh okay so translation X is not working or let me share the screen on Zoom maybe for a second no no no no can see I'm trying to compile it uh yes I can see it okay wait a second uh an index equal to index so this one works if I drop it yeah it takes a lot of time for the other cars to move up uh to move towards because spring is not yeah okay okay and now what's happening and now the the one on top stays on top probably we should simply not render it right uh because we see that the one behind is is started to animate I think in the Tinder card we can check if we we can interpolate the active index uh for the translate Tex now I I get the the issue so what we we can do if uh uh we we can say interpolate active index. value where what but what if we say that if this card if current index is larger than the index of a card simply not render anything for example if active index. value is more than the index return returnal what's going to be the problem there maybe I'm not seeing something uh no activ so you need to keep in place the the previous V right so you need to move uh the next uh if you have already went from the first index to the next one yeah the previous index should be out of screen right so what what you you need to do is uh you you need to interpolate the active index uh uh for the translate X so instead of this equal sign instead of this uh equal sign you can interpolate the active index pass the ranges uh index minus one index index + one and and index minus one uh should be uh index you're okay you say it yeah sorry the so the output range uh should be uh for the uh index plus one it should be uh minus screen with minus so it's outside yeah and for the index minus one is going to be translation x. value uh for the current index so it's zero for the index minus one and for the index it's trans trans. X okay I'm going to stop a bit this sharing to to see your face uh but this is not going to work isn't it it it has a very beautiful uh animation do you see it yeah because you need to clamp it uh so the current index should translate on app and I believe that that now you can do the uh uh let me think about uh yeah you can say uh do this interpolation only only if the active index value it's less or equal than uh index otherwise it's zero otherwise zero so that's weird if active index am I sending properly where the index is there hopefully yeah so active index value is is zero starts from zero no if probably if it's more or equal more or equal uh yes now only this one is applied if I throw it the cards come in front I don't know what's happening exactly it's is this working hard to to to to explain but yeah let me refresh go to Tinder so here now it works properly targets only this one if I throw it away it takes a bit of time for the spring to to finish it takes more time but after that happens the cards are moving forward and something it's there there is a blink there I think that the opacity of the first card is still not properly set and I think we will have to do the opacity not based on the active index but based on the or No it should be on the active index can can you can you do it again here to to see and when I started the swiping the the previous card or another card appears oh no actually we see they are only the second card okay so so can can you go back to the Tinder TSX and instead of changing the index uh instead of changing the index on finish uh uh do do directly active index that value it's spring after the translation value with spring so not not as a call back but uh change it right away okay after doing this with spring we can also change the the index for some reason uh okay it moves to the next item but it's hidden and this one that we see currently on the screen this is actually the second one that's why it has this opacity so basically the when the next item when the second item is active it's it's hidden here and if I start panning it appears and it stays here so probably some translation yeah the trans after we finish we set the translation to zero uh oh yeah yeah okay yeah oh damn yes Trend yeah we need the because now we don't have any uh any uh yeah it makes but uh uh now you need to also move this translation x uh with spring zero this one here uh on the else statement so the the first the first line after the on end you setting the spring to zero okay yes so this should be on the else branch on the else but what if it's finished it should go to zero yeah this is okay so this is okay but the uh this spring should be on the lse branch here on the else yes no no no here on the main if stat oh on the main if statement yes so if if there the velocity is not big enough just go back to zero yes we just have to otherwise do something y perfect yeah so now the I'm going to test first uh not swiping it all the way it should come back now swiping it all the way uh but why why is this I don't know exactly what's happening you know what's happening like we said the translation X to Zero only when the spring finishes and the spring takes some time to finish and while we are waiting for that and the reason for that is um yes I think uh we need to add a different prop property something yeah [Music] yeah let's uh active index let me f it thank you I understand like it's it should be hard for you when you're not like hands- on with a code uh yeah it's it's difficult like because when when you your hands on like you're testing trying different stuff until it works but yeah like having to to think I Hadad like everything like must be challenging is that we we we have two values right that we are playing with and based on those two values we are animating everything the translation and the active index yeah so so uh I think that so the the thing is that you can U you can achieve it differently but I didn't want it to have the gesture on every uh Tinder card mhm but instead I wanted to have a single gesture that's going to wrap the entire list right M this is the problem uh and what you can do instead is move the entire the entire gesture to each individual Tinder card and uh enable the gestures only when the active index it's equal to index that's it right so uh I I believe um I I cannot compile that much in my head what's actually happening so if you if you swipe to the left the translation it's changing and what's actually happening if you can explain it to me uh let me yeah uh so sharing the screen if I swipe to the all the way to the left it takes a bit of time for the translation X to change back because the spring animation takes some time for example it takes a second so the active index will be changed to one but the translate is not yet reset to zero so we will have to wait until the first card moves all the way to the left and only then reset the translation X to Zero to show the next card got you yeah yeah this is a more complicated uh part uh so I believe uh you you can fix it by having two different indexes and two different translations X for the current card and next card so in this way you are not going to affect anything but what you can do instead just move directly the entire gesture uh copy paste everything uh for each individual Tinder card the gesture to mold it on the Tinder card uh let's do it probably here yeah that's also import you can also create a hook for example but this is yeah uh too much maybe for the live stream uh but and we're going to WRA uh we're going to remove basically the gesture detector from here and to the Tinder card instead of the yeah probably I should simply wrap everything around with this gesture detector where the gesture is going to be the one that we Define above and at the end we close this one yes so now with it has some missing parts as well which is the translation X I believe so far it looks like it has everything yeah translation X it's it's a prop so you should remove the translation X is a prop so the translation X is going to work on the individual card so we're going to move it from the screen to the card as a shared value and instead of taking it from the properties every card will be responsible for its own translation value I think that makes makes makes sense probably I'm not sure like in terms of performance but logically with translation probably is every car should be responsible of it uh yeah there is no performance impact uh because if you are going to disable the gure and we will disable it with can we do it on gure detector no no no directly on the gure so gure has uh enabled cool enable if the uh active index it's an reanimated value so [Music] uh I would say if active it's one let's try it like that try like that because uh we the the thing is that active index is not going to be updated here because it's a reanimated value okay so you you need to have it as a um as a prop or as a state right so uh as a prop or as a state e uh the value of the prop State um let's try without uh enabled uh because I'll think about a solution here so so now if we go here everything works here if I swipe yes yeah this is a feature do you see it like after the the car changes just it it swipes left and right like very slightly it's not a bug it's a feature you know so wait I cannot see it properly uh even when I share on um on Zoom but now you don't need this translation x uh if statement the if St now you can add uh now you can add directly the translation x value do not interpolate not do anything anything right translation X do value yeah and uh Interpol this one it's okay uh the and and and also for for the active V for the rotation you don't need it for the rotation I don't need the check yeah yeah just do directly the interpolation because the translation X is going to happen only for the current uh yes every car will have its own so yeah we don't need to check if okay perfect it works there is a flickering what why is the flickering yeah there is this flickering uh I think think I think I know yeah yeah I know because uh we mov back with translation or what yeah now that the cars have their own translation a you don't need you don't need yeah you don't need to bring it back but uh definitely yeah and you can now use uh yeah like this uh and we change yeah it should work we change the active index here as a global active index it should work yep now if I reset it comes back okay and if I swipe left there is no flickering it works and I can interact with the next one yeah I'm very sorry I wanted to make it uh uh too much I think you wanted to make what I wanted to Target multiple things at this is one one problem which I have like daily is like I wanted to optimize as much as possible the things no I think that's fine like uh it's always like that like we that that shows like the the real development part of of these kind of animations because not all the pops but but don't don't remove don't remove that part with the commented code so bring it back and now yes so so now add that part uh to the Tinder card to the Tinder card somewhere at the top yeah because I I really like the part where you move left right and the the the cards are coming right so I think this should hopefully work no no because it's a bit it's a bit weird that the active index is global but it's being changed from all the Tinder cards uh no no no it's it's okay this is how this is the the beauty of a shared value you can Define it globally and then any any component can change it and this is going to be reflected but every component will change it with a different value based on their own personal translation translate X yeah but yeah it makes sense uh uh so maybe yeah but the translation X it's happening only for the current index so anyway yeah I think I think I think that what you can do instead is you can uh uh uh you you can move this uh interpolation inside the the pan gesture uh on change event let me open the window please on change yes on change active index will do translation yeah I think that makes more sense because this is happening on the event itself yes yes it works yeah so sorry I I was thinking too much again um but now this is happening on an event and because the event is only happening on the first item the active index will will be changed from here so now if I move to the left the next card is already starting to come into place this is both increasing the scale increasing the opacity all the way until it's here by the way you don't need to add active index plus one but do it active index plus 0.8 so in this way the opacity is not going to go all the way to one okay that makes sense I think I I have a missing photo that's what that's what what's the problem and I think I think it's uh above L is here Danny fre J jpg there is a JPEG jpg maybe which one which one is not there let me see so the first one with Danny Works uh there is a j yeah that one I think is correct okay then there is this one but I think doesn't work no this one is working oh boy give me just one second sure no for for some reason some something is going on there I don't think it's the problem with the with the images DV is right yeah but one second maybe I'm I'm wrong so we have Danny I move him then we have John like the on the third one the opacity already is not full uhuh okay and even like I see the scale like it doesn't come all the way to towards us uhhuh uh on change this is because of this active Index right yeah I think think so because active index value on end we are moving to we are simply doing active index plus one but what we should do is because active index value is not going to be a index plus one it's index plus one right yeah because you are already changing the index uh on change and so you might end up in a situation with three 3.2 or something yes now they move all the way till the front yeah you you could also do MTH floor uh let me share the screen index and you tell me if if it's the way you wanted it to look like do you see yes it comes back it if I go slowly the other ones are coming into play it looks like it's see more the farther we go we are traveling more because we are starting wait a second let me think somewhere we are resetting a value but I think that's a feature that's not a bug no no no it's it's a bug no you you'll not be able to sleep um like we are traveling slowly slowly but when I release we are kind of moving back where they should come from when I release what's happening the gesture and it goes here active index value um X+ um yeah this is really weird uh translation translation X but the the let's see first of all the the traveling is coming from probably the including the scale the scale depends on the active index so for some reason active index a capacity is okay right I'm sorry no capacity it's okay I think all of them are uhhuh we're like traveling for from their original position towards us uh and because can we remove the spring for the active index it just do directly active index it's equal to uh index Plus one yes let's do that active look when I when I start moving it at some point it when we change it works but then when I start moving it it's a bit weird so that means that we have a if statement here in our styles that we don't need probably but we don't active index value where else do we change the active index on change and on end oh yes in the Tinder screen we never change it right no uh sa the translation next spring and how how are we animating those which one wait a second so this one I think because when I start the on change event it moves back yes when I start one change event it moves back uh which means that the active index value uh shouldn't go from zero to to this one but it should go from maybe index wait um because active index for the third element should never be zero it should go from index oh got you uh it should if it's if it is if it's a zero it should be index otherwise it should be active index plus 0.8 or maybe even index uh oh got you yes because we had the the logic from from the screen yeah Dam and now it still comes back yes yeah that that was definitely the problem the problem was and I will move back to the with spring in order for us to have like this nice fact feels bad man this is like a half an hour animation I'm I'm completely honest with you but is uh we actually showc bed some really uh real case scenarios right like what's going to happen when you encounter this issue right yeah so yeah we we have debug it yeah that was definitely the the issue perfect yeah because we didn't care that much right in the in the Tinder list yeah and and now be yeah um I think the only thing that you need to know uh is to have it as a state the active index and I think that we can wrap the tutorial afterwards so basically what you can do is uh in in the Tinder main list in the Tinder component you can create a state here uh by the way you can stop sharing the the screen on zo uh why uh why should it be a state because based on that state you can U uh slice the array you can fetch more data and you can do a bunch of other things will it still work because at the moment it's a Share value because it drives the animation so yes you're right but we can trans transform it into a state so how to do that well you can create a a US state with I don't know uh something and set something I don't know exactly how things okay should I leave active index here and just change uh change the yeah yeah you you can leave it leave it because it's needed um index it index yeah uh starting from zero again and uh now we can leverage another Hook from reanimated okay and uh that hook is use animation reaction and that's going to be in the Tinder card yeah no no no no not here here no oh based on active IND yeah we have the active IND we have everything we know here okay use animation Rea animated reaction use animated reaction yeah and and this is going to have a prepare and react so on on here uh whatever you are going to return from this method is going to react to it so you are going to return here the active index. value and uh the next uh the next the next method is going to receive this active index like the current the current value and the old value so you can uh say here uh current value and old value or previous yeah uh and you can check if if uh those are uh if uh uh meth the the floor of the current value no no wait wait a second uh yeah if if MTH floor of current and math floor of previous is different then you need to set set the index uh with the map. floor of current yes yeah so as I was explaining previously actually no no no no no wait no no it's it's uh uh uh no so if if the current value is different than the index then uh set the index with the current even math floor is different than yes index it doesn't matter if it's floor or not because index is always going to be uh the the is going to be thetive index yes okay but but that's with decimals right it's an integer it's not a natural number so it's not one two three four five so only when when the current it's equal to index which is uh basically saying you have swiped if that is it is it correct as I have it here because the current is a floating number but our index that we just created we want it to be as a integer 012 three so yeah no no no it it should be uh c c it's different than index it's it's a special Yeah by way fun fact we are with Cataline from the same part of the world he's from Romania I'm from mova but in our society we are LS we are we are brothers and we are speaking the same language yeah yeah ex almost the same language with different he's laughing because this is a bad word in Romanian yeah I think I think you can do value uh value uh and previous value but I I want you to reflect that you have access the current and the previous value right but you the the statement should be if the value it's is different than the index it should not be the floor because you are going to modify it one by one only when when the animation has finished right so this is going to crash the app don't save it actually you can save it but uh don't don't do any swipe because uh in this use animated reaction in this callback you are on the UI thread yeah and you're trying to call some JavaScript something on the JavaScript thread so in order to make this happen you need to uh uh import run on Js from reanimated yes and we need to and you need to wrap the set index with run on JS no no no directly no no no directly on the set index run on JS uh pass set index's first argument and then call all the method function no no no no no just uh so run on GS pass set index close the parenthesis and uh open it again so set index we close the parenthesis and then we call yeah yeah okay understand so run on GS yeah okay and by [Music] the corre value uh uh no no no wait a second so the value if the value is always going to be different yeah you you're right actually so if if a floor value is different than the index oh wait a second yeah I think we shouldn't update the index the Flor if the floor yeah it's okay it's okay okay let's see yeah and we will need that one the index for uh I don't know maybe at the cons you can cons index yeah oh yeah that's right so if I go here I don't know where it is but probably behind the the notch I think you can can pos position this absolute as well and bottom I don't know 20 or 30 or something and text text Al line Center top okay so current index zero oh yeah when I move through them when I simply swipe it doesn't change only when we actually move to to the next kind of integer only then it moves so so this is State now right and you have access to it on the JavaScript world so you can uh do slice you can do whatever you can call uh let's assume that if index it's close to the users length with I don't know if let's say you have five users and the index it's two or three uh you would like to fetch more users right so if you're getting close to the users length you'd like to fetch more data like pagination right so so you can uh yeah you can uh last two cards remaining fetch yeah more and index should be inside the square brackets so now I I can even do it as a as a war so you can see it on the screen uh with this one uh like if we are almost to the end of the list yeah it's probably free but you get the idea so last two cards is being called because we are reaching the end so probably here you're going to have some logic of loading more items from your back end okay can we do it now and that's it right yeah no just do const uh users uh set users it's equal to us users initially create another state and and that's it then then we are going to like uh users set use use State initially we can initialize it with dami users let's call it dami uh uh type of but it's okay and you want when we reach the end to Simply push uh to this array once again the same users because we cannot fetch more but what we can do is we can yes exactly we can have users and then uh return the structure users and then uh yeah you can do uh users uh Dum users sorry Dum users. reverse to have it differently right so dumo users. reverse dumo users and this one's again I'm rushing with with typos and so on but now when we reach the end we should load kind of more users and this way should be infinite yeah you have the same key uh yeah you you need to instead of users. ID you also need to pass the index index yeah so for the key I can do I can do it like this you can directly index yeah index okay so now we have our infinite list of cards that we can swipe left and right and maybe uh just to have like two methods that will be called when we uh Decline and when we accept a card I think this is going to be also important we're not going to implement any logic or any animation for that but as a way to understand or as a function that is going to be called when we swipe left and one we swipe right that I would guess is going to work out of the box the animation so uh just create two buttons that's the beauty you know if you optimize everything just create two buttons two buttons where or below the the list yeah yeah yeah and one is going to the button for what accept uh yeah accept and whatever okay deine just do one and the other it's the other way yeah I uh but we can do that later as well so on press if we press on the yes we need to change the active index or what the active index yes so active there is no animation right active index. value + one oh active index equal to this one and at the same time maybe some math I don't know I don't know where is this button I'll simply add inside the a footer that is also absolute position just for us to see it yeah um bottom 20 come on we don't have what yeah this is definitely not going to work because now translation exits inside each individual stack card but uh I I I didn't mean about the buttons uh probably what's more important is a callback function when a card is uh moved to the right and when the card is moved to the left because in that situation I believe that um like if you would implement this in your application You' have to call a function like okay the user said yes create a connection so from the Tinder card probably that's going to be on the on end um and it's going to be somewhere here and we will decide which call back function to to call so most probably yeah yeah going to have two it's it's really nice no no no just one just one one response yes and let's do uh is yes console uh you you can do a type right type yes or no yeah I can do that as well uh yes and and no so console log now this function streaming for two hours three hours this function this is the last thing that we're going to do uh this function we will send it to every single card we're going to receive it here uh it should be have a parameter but anyway and when we end the gesture here we can do we can call this on response with the value we should send here true or false that will specify if it was left or right so we can take the same logic here no no no the if the velocity the sign of the Velocity or yeah the sign of a velocity or velocity if velocity is greater than zero it's yes otherwise is no yeah that's true and this one response is just I didn't add here the the Boolean but it's not a Boolean oh it's not a right yeah yeah yeah it's yes or no that's correct I I will do it a bullan I will I will simplify it I'll do true or false uh okay because it's even yeah easier here and we'll change the Boolean here so if I swipe where let's see um but but you need to call it right uh I called it in the tnder C on the one on end so if I do right we run on GS oh we need to run on GS because we are inside the UI thread so we need run run on GS we need to send the function on response and then we need to call it right afterwards yes let's see now if I look here response true and if I go to the left it's false and in that function you can you can have some logic like to to save something in the database or so on all right I think I think we are good it was a tough one but it was a rough rough rough rough start see uh yeah but um I'm pretty happy with what we have in the end and I think a lot of people will will get a lot of value just from from from us going through all of these difficulties all of these changes um it shows the the real way of how to to design them and so on all right uh anything else you'd like to add in V about this gesture about anything related to animation I I don't know uh if if you're into animations uh check animat native.com otherwise uh uh subscribe to vadim's uh channel uh you're doing an amazing job I'm really happy I I have watched the the dev Amber videos demember uh so yeah I think uh you you provide quite a lot of value and yeah everybody should subscribe to this channel thank you very much I really appreciate your help uh and um we the community misses you on YouTube yeah uh I know uh but I I I don't know I I will see what I'm going to do uh but otherwise I'll be at abjs I already have the workshop prepared yeah you're GNA have a work if anyone is yes about animations with cper uh from reanimated Team uh and there is also going to be the creator of reanimated Kristoff yeah uh to help us there with any with anything so if anyone would like to join uh go ahead there is 30% discount or something but otherwise I don't know hopefully to see you there we're we're definitely going to see each other there it's right at my birthday this year VJs so it's going to be a fun fun experience but yeah thank you very much for for joining today uh make sure to to check out uh the the website is animater native.com right yes yes for exciting animations that you can use in your application just take it from there put it in your application and you're good to go your application will become will look much better instantly all right thank you very much Cataline hopefully we're going to do more things together in the future um probably I'm going to better prepare technically using some other software uh but anyway I think this was very valuable and thank you very much yeah thanks thanks a lot V for having me it was my pleasure okay uh and I'm going to do the outro all right guys that was demember uh that was day six and in this one we implemented the Tinder swipe animation uh thank you for being here
Info
Channel: notJust․dev
Views: 6,993
Rating: undefined out of 5
Keywords: vadim savin, not just development, notjust.dev, react native live coding, javascript, react tutorial, react native tutorial, javascript tutorial, react native ui, react native for beginners, React Native, mobile development, DEVember, mobile app tutorial, learn coding, coding challenge, fundraiser, Tinder Swipe, Expo, UI Design, Swipe Animation, Reanimated, Tinder Clone, React Native Animation, Gesture Handling, Custom Animation, Swipe Gesture, React Native Expo, App Animations
Id: H2Xr_id5JuE
Channel Id: undefined
Length: 157min 38sec (9458 seconds)
Published: Thu Dec 07 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.