Liquid Swipe - “Can it be done in React Native?”

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] react native developers this is the liquid swipe slider an iconic user experience that we are going to build together so let's get to work [Music] guys i hope you are well william here recording from beautiful switzerland in this video we're going to look at the liquid swipe example a delightful user experience that was originally designed by the kubernetes agency we've already made a video on this topic a while back and at the time this was just a proof of concept but in this video we're going to build a fully fledged slider using this technique and you're not going to believe how easily such a user experience can be implemented in react native so how would you do this in react native well this is a two part problem first we are going to need to implement the masking of the slides that are on top of each other and then we are going to build the wave animation so first let's talk about the mask we have a slide component that represents the content of a page there's a previous slide on the left the current slide is in the middle and the next slide is on the right we could have the slides translate over each other but that would be no fun instead we're gonna use a mask the way it works is the following we underlay a black shape under the content wherever there is a black pixel under the slide it will be visible we overlay the left and right side on top of the current slide once we've implemented the slider we can build the wave animation we start by drawing a rectangle and we add an imaginary circle this imaginary circle is going to drive the shape of the wave and its animation we can draw two points at minus two times the radius on the y-axis and from there we draw a new point we move to the right by the ranges divided by 2 and done by radius same for the next point and for the next point we move to the left by radius divided by 2. and same for the last point now let's draw a line across those points doesn't look very sexy but we can smooth out the points to transform these lines into nice curves there are many algorithms available we ship some of them in re dash but let me show you a very simple way to do it we transform the lines into curves and we can play with the distance of the control points in correlation to the radius and the value that works great is zero five five two two eight four seven four well that's no coincidence this is a constant used to approximate a circle with bezier curves i will link to a great article on this topic in the video description now let's animate the wave and let's remember that this wave that we've drawn so far was entirely driven by this imaginary circle and now we can animate the radius of the circle depending on how far it is from the ledge or the wave but what do you guys think can it be react native let's have a look before we get started one thing if you're interested to learn the fundamentals of gestures and animations in react native i hope that you will check out my online course at start breaknative.dev in the course we cover all the fundamentals that we will be using in this video bezier curve svg animations gesture handling so if you're interested to learn the fundamentals i hope that you will check it out at start react native.dev we are into vs code here and i have a boilerplate project which you can download from the video description in case you want to code along with me i have a list of slides with some informations and i have the slider component i have the index as a state to know where we are in the current index and i have the slide the current sliders children previous slide next slide if it exists at zero there is no previous slide and on the last slide there is no next slide and i give it the index and the set index function to know when the index has changed and if we go in the slider component we simply display the current slide and the left and the right side left slide on top of it and we have the wave component which is completely empty now and i think we're gonna do this in three steps first we're gonna use the mask to display the previous and next slide then we're gonna add the gesture so we can move the slides around and finally we're gonna build a nice wave animation using the exact same techniques that we just explained before so let's build a simple mask for these views and we're going to use the mask element from react native so masked view children is a child we're gonna also use absolute fill and we have the mask element attribute which is a wave we are going to animate and here we will do the wave later let's do it step by step so i'm simply going to draw a rectangle in svg so the mask element we're going to write an svg component again here using absolute feel and so we're gonna have an animated path so we're gonna pass some animated props and um we know that the fill is black so whatever is black on the mask element is gonna be visible from the children so i'm gonna do fill black so now we need to create the animated props so use animated props and so we're gonna return a simple path for now i think so we're gonna create some svg path commands so i'm just gonna return the equals we're gonna join them with a space so the path commands so we're gonna move at the top left corner so move at zero zero and then we're gonna draw um so we're gonna start with really the path is simply a rectangle that takes the whole space so i'm going to draw a vertical line a horizontal line sorry to the weave of the canva and then a vertical line to the height so you see you have the h command v command the fact that is uppercase means that we are using the absolute values if it would be lowercase it would be relative so the height so we draw down and then we need to go back to zero so we can do horizontal line to zero and we can close the shape okay and let me check so i think here we don't see anything because they are overlaid on top of each other maybe if i do weave divided by two yeah you see perfect so we have our base mask element now let's animate the slides so we're gonna go to the slider and wrap everything into a puncher chandler and we know that the first and unique child of a punjab chandler is an animated view so we're going to use it here and we need to create the on gesture event animated from react native no not vanilla animated but from react native reanimated okay banja chandler and let's create the own gesture event so use animated gesture handler and so let's create three animation values first we're going to create an animation value called active side so when we start swiping did we activate the left slide or the right slide or maybe if we swiped in the middle we didn't activate anything and then we're going to create x and y value for the left side and x and y value for the right side so let's create active side so use shared value and the default side is none and then we're going to create we need x and y value for left and right so i'm going to do left is use vector which is a redash function that simply creates two animation values one for x one for y so i can import it here this one as well probably this one too so i do left and right now when the gesture starts we want to check which side we activate so we're going to look at the x value and if x is less than the margin width which is this small margin on the left and right side we know that we activated so the active side is left and for the right side it's if x is greater than the wave minus the margin so with minus the margin wave so here we will be on the right side so active dot value equals left and if not it equals right and i guess here for good measure we can write if not it's none and i think one thing we can do maybe is pass the position here to the wave and use it already in the mask so here position equals left and position here equals right and also if the gesture is active so on active we simply gonna assign x and y to the left or right side depending on which side is active so get the x y value oops and so if active side equals left so x left dot x dot value equals x left dot y dot value equals y and if it's a right side left dot x dot value equals so we're on the other side so we've minus x and for y oops it's right here and for right y doesn't change anything so that looks good let's add the position property so we know it's a vector of shared values so of vector of animated shared value okay so we have it here and maybe here i can do position dot x dot value and one thing we can add here is that when we initialize the slide so use effect so here we want a default value which would be the margin width or i think the margin width and we wanted to animate nicely when it appeared so that's why here we set it at zero and then we use set um use effect to animate it from zero to margin wave let's try let's see how it looks so when we initialize oops we can do left dot x dot value with spring to margin with and same for the right side so here we see the left side the okay so the first thing we only see the left side of course because they are overlaid here on top of each other so if it's the right if the side is right i want to revert it on the y axis so i'm going to add a style here a transform and we will rotate y and if side equals side right i'm gonna rotate by 180 degrees if not zero degrees okay so now i sit on the right side and it moves nicely let me also update the current index so we can see both because here index is at zero we only see the right side but if i update the index to one yeah you see you have the left side and the right side so one thing we can do already is that you see here the left side because they are children it's always the so if we go here the right side will always be on top so if the left side is active it should be on top of the left side on the of the right side which is what you're seeing here so we're going to create an animation value called zed index and we're going to create add a style to the left wave here so it can go on top of the right wave if it's active so i create i move this to an animated style so i can call it left style so use animated style with a z index no so i don't need to create what am i doing i don't need to create as an index value the z index if um active side dot value equals left then it's 100 if not it is zero let's have a look so you see up and see now the left side can go on top and the right side can go on top of the left side perfect so now it's pretty clear that i can add the dependencies here the next step is to transition when the gesture ends now so on end and then once we've done this we will do the nice wave animation so on end we're going to look at x and i'm going to need the velocity x and velocity y for the springs animation so velocity x velocity y so if so here actually you will see that the slider component the logic is going to be super simple but every time we do something from the left side we we need to do it for the right side and maybe there is a way to factor this nicely but actually the logic is very simple the code looks a bit uh but if you look at the code it's always because we do things twice one for the left side one for the right side but if not the logic is super if you look only at one side the logic is super simple so if the value is left and we're going to need to do something if the value is right so we need to snap somewhere right so what are the snap points on the left side on the left side it's going to be [Music] margin weave here and all the weave so left or right side and the destination so ray dash as a function we're given a position a velocity and an array of points it's going to tell you where to snap so this we're going to use it's called this it's a snap point function so we're going to use this function um so we give it x velocity x and the snap points on the left on the right side so if it finishes it's zero if not it's with minus margin width so now we can spring to the destination on both sides so i can do here left dot x dot value oops equals with spring to the destination and we're going to use the velocity so velocity equals velocity x and same for the right side here we know that so since we take x we need to do with minus x from the right side and um shall we just try so here yeah it seems to to work nicely perfect and now what we need to do is that when we snap to the one of the points where we need to update the index we will do it so we have a callback a callback here when the animation is finished so we need to change index here on the left side if the destination is with so if destination is with we need to update the index so run so here we are on the animation thread so we need to call back to the javascript thread and use apply set index and since we're on the left side we're gonna do index minus one so these are the arguments the argument we passed to set index so we're calling back to the javascript thread and on the right side it's if it's zero so this destination so destination zero and we do plus one yes perfect and you see it's a bit slow so this i really like it's a bit slow to finish so here because it's nicely bouncy it's great we love it but if we go it's like the tinder example if we go we swipe to the left or to the right we are bouncing outside the screen and you see there is some delay before the right side appears and so like we did in the tinder example if we are going to switch the page we want the spring configuration to finish super quickly because it's it's gonna bounce but we're not gonna see it we are we want it to be super bouncy only if it's visible like for the tinder we we want it to be bouncy only when the car goes back to the stack if we swipe left or right it's we just want to apply the side effect as quick as possible and so this is exactly what we're gonna do here and it works super well it's kind of a cool um cool technique so here the first so we need to see if we we transition or not so i'm going to create one animation value because we're going to need it so here for the spring config we're going to date in order to do the wave animation so i'm going to put it into an animation value so i'm going to create is transitioning left default value is false and is transitioning right so here is transitioning left is true if destination is with so far so good up and we're going to update the config accordingly but let me do the right side before so is transitioning right that value and now we can update the configuration so if we are not transitioning we keep the default spring config it looks good we could make it even more bouncy if we want if we are transitioning we want to have no overshoot clamping meaning the value cannot go above the destination value and we want the spring to finish quickly and there are two values we can so rest displacement and rest speed displacement so it's a threshold when we reach this threshold we can consider the spring to be over and so if we are transitioning we want these values to be very high so it no it finishes the spring very fast so overshoot clamping if we are transitioning to the left side we want to clamp the overshoot so it's true or if not it's false then we have rest speed threshold so at which velocity we consider the spring to be finished if it's transitioning to the left at a very high speed let's put 100 if if not very small speed we want we want to bounce so zero zero one we can just play with it and then we have rest displacement threshold which is the same for the position and yeah let's just use the same values and let's do the same for the right side so you see every time we write something for the left we need to do it for the right but the code if you look only at one side the code is actually pretty i would say fairly lean and simple so here but it's transitioning right let's have a look and you see here it appears almost instant it's instantaneous so far well perfect but if i move back you see it's nice nice bounciness perfect so [Music] now let's animate the wave right so here it's a straight line that's no fun let's animate a fun wave so here we go back to a simple rectangle and we're gonna animate it into yeah something fancy so we know based on the description earlier in the video that we need to draw five points based on a radius of a imaginary rectangle smooth the points so we have nice curves in between these points and then depending on the x and y position of the finger animate the righteous which the imaginary rages which drives the whole animation so what is this radius i think we can take here we have the mean ledge and the margin width so the margin wave is the part which activates the gesture but then we have mean margin on the left side so i think we're going to do margin weave so the part that activates the gesture minus the mean ledge so this is our radius and i think that on the x so i'm going to create step x and step y so we're going to move left and right by some amount and we're going to move down on the y-axis by some amount and so on the x-axis this amount i think is radius divided by 2 and on the y-axis it's going to be radius and so we can define our five points based on this so p1 so we're gonna start from the center so p1 is actually the top point but so i have a function here vector2 is simply a creates a x and y vector so the center is that here it's going to be position.x that value and i guess here we could take position.y dot value also but here the default y value is zero we want it to be in the middle so i'm gonna do height divided by two okay now so the x position is good on the y so since on the y value we need to go up and we need to go up by two times step x step y right because p3 so this is the y position is going to be the y position of p3 so we have p2 so it's going to be minus step y and then we have p1 so two times minus step y and now p2 p3 p4 p5 are inferred from p1 so everything is called so we define the radius and everything is constructed around this ranges value so this is the radius this is a position the center of this imaginary circle and the whole wave design and animation is going to be based on this imaginary circle so p2 is p1x so on the x axis we're going to move up by step x we're going to move to the right by step x and for p for y we're going to move down by step y i think it's the same for p3 but based on p2 of course and then we have p4 where we moved on by step so p4 sorry where we moved on by step y but now we go back so we've reached the apex and we're gonna move back to the left side so p4 and same port for p5 but here with p4 and let's draw these points so here we're going to draw a line to p1x and then a vertical line to p1 y and now we can draw points so i can do it quickly line to p2x p2 y so here p3 p4 p5 it doesn't look good no i think actually it looks good we just need to draw then the line the vertical line to the height that actually doesn't look too bad i'm just wondering here if we should use mean ledged instead [Music] yes okay looks pretty good and now we need to [Music] smooth out the so you see we can even move it up and down but one thing i think is that also we need to spring back the y position so that's something we didn't do so here i need to do right dot y dot value we simply spring back to 0 to height divided by 2 and we can use the velocity and same for the left side so let's smooth out the lines so these lines are going to become curves and we are going to use some control points and so right now if we want the curve to look exactly like the line the control first control point is going to be equal to the source and the second control point is going to be equal to the destination so let's write this uh quickly so we have point one control point one sorry so c one one so here it means the first one means for the point one and the second one means control point one and so again here i'm gonna use um p1x p1y and for the second control point we're going to do p2x p2y now let's do it for point two so it's going to be p2 p3 bear with me a second while we do this so third point so it's going to be p3 p4 and the fourth so here actually the second one maybe it's clearer if i do two two three four five and it's going to be p4 p5 and now if i use these as curves the lines are going to look identical but obviously we're going to update these values here i have a helper function to write the c command based on some vectors so let me do this quickly so we have a curve so c11 sorry ch1 c2 and p2 so here p3 [Music] and p5 so it should look identical and it does um let me see i think here again i want to update not use margin with but mean ledge and probably same here on the right side perfect now let's move out the curve all right so i think that looks good so now let's do this moving so we have the c constant here but i will link to the article that explains where to this value comes from and we can use it here so i'm gonna do actually let me just c and i'm just simply gonna multiply by r so this is assuming a radius of one and we are going to apply this value to the control point so here i think so for the first control point we are going to add so we're gonna go down to [Music] c for the first point and here we're gonna go down by c go up by c and i think here probably go up by c yeah looks good doesn't it yeah perfect and so now we're going to animate the radius of the circle depending on the y position and i think here we can do so the radius can be we're going to clamp i think the value this is a minimum value but i think we're going to take position dot x dot value as the radius and the maximum value let's take with divided by two clamp and it's position so let's have a look looks good and maybe to make it look a bit organic here the r value is clamped but for the x so i think it's good for the y the x axis but for the y axis we can use the unclamped value but it still needs to have the max so the mean so this value has mean so i'm gonna do here math max of position dot x dot value and still use this one that looks good and now if we are maybe also the no i think that looks good should we make it even smaller divide it by three maybe and yeah i think yeah that looks much better actually and we can definitely play with these values but now let's transition when we release the gesture and maybe you see three is too harsh so maybe it's uh 2.2 i don't know 2.5 sorry um let's let's deal now with when we release the gesture so we have these uh transition left transition right so which we're going to pass as property is transitioning so here it's transitioning left and is transitioning right if we are transitioning we want so the everything to go back into a line so basically what we want is a step x to be equal to zero so everything is going to be on the transition to the same line and we want to transition to it so we want a spring animation which means that i'm gonna need to extract because you see step x depends on the radius so we're going to transition from this value to 0 which means that i need to extract this into a use derived value because we're going to use a with a spring and since r is also used here i'm gonna extract r as well i mean maybe here it's actually faster to duplicate the values yeah so let me maybe just do step x use derived value and so we use we return with spring if we are transitioning we spring to zero if not we spring to r divided by two and here either i could extract r into a use derived value or copy paste it here copy the paste [Music] this one i guess is less clean because we duplicated an expression but might be actually slightly faster so now step x is an animation value on the so this becomes that value that value so let's have a look so here i'm moving around the wave and you up it transitions nicely to a straight line when i'm transitioning and because we have a nice spring config the change between slides is actually super fast isn't that cool i think the width divided by three is a bit too harsh so you see in some position i feel like the apex is too big but we can tweak the values nicely isn't that fun guys i hope you enjoyed this example and i hope that you've been surprised on how easily such a user experience can be implemented the masking animation is a bit slow on android because it's all done on the cpu so instead of being hardware accelerated so i might update the example to use an svg mask instead of a must view from react native or i might not use a mask at all for android in fact the kubernetes agency we implemented the example also on android and ios didn't implement the masking 400 here things are a bit more complicated if you want to use hardware acceleration but then the wave animation which was completely driven from an imaginary circle and we animate the radius of this imaginary circle was a really nice driver to easily implement a seemingly complex shape animation but that is in fact actually fairly easy to do so i hope you enjoyed it let me know what you think in the comments below i am looking forward to talk to you soon and until next time happy hacking [Music] bye
Info
Channel: William Candillon
Views: 38,276
Rating: undefined out of 5
Keywords: React, React Native, Can it be done in React Native?, JavaScript, TypeScript, gestures, animations, reanimated, Native Apps, Apps, Mobile development
Id: 6jxy5wfNpk0
Channel Id: undefined
Length: 44min 25sec (2665 seconds)
Published: Tue Jun 22 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.