Instagram Stories in React Native with Reanimated | DEVember Day 18

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up no developers welcome back to a new live stream today we are continuing with November series a monthong of react native tutorials today is day 18 of our uh series and uh in today's episode we're going to focus on one specific feature we're going to build the Instagram stories component uh that will allow us to view images in a Instagram like way so we're going to be able to move through from a story to another and by doing this we're going to learn how to build everything with Frack native and Expo how to navigate through different stories we're going to learn something about time based animation so that we can show the progress bar of the uh story and also when it finishes to automatically move to the next one and uh then we're going to move into a more advanced animation for the story transition and here I'm talking about the cuboid like uh page transition for for different stories we're going to use the latest version of react native 073 that was launched uh this month and the expose the k50 which is uh at the moment of recording this it's in beta so we're going to test them out but if you're watching the tutorial later uh this should be the this should be already everything that we're going to use should be already available um so let me quickly remind about demember every day we're doing some a tutorial about re native focusing on one specific aspect and everything is available here uh on our YouTube all the tutorials are separate so you can pick and choose uh something that is interesting to you if you have ideas you can submit them to our idea board all the links you'll find in the description and demember is not just about learning it's also about giving back during November we are organizing a fundraiser called education for children during which we are uh supporting the efforts of save children organization to provide uh accessible education to all children in the world uh if you would like to donate uh to this cause make sure to find this donate popup on the YouTube and everything is set up for YouTube everything goes directly to save a children uh non profit I'd like to say thank you to Rogelio Stuart Sagar Val Travis and others who already donated anyway hello everyone in the live chat uh hopefully my stream uh software connected correctly and I see that it did hello Dana how are you doing so um what we're going to use today as I was saying we're going to use the latest version of react native 073 just because we need access to a new property that was added in the latest version and here I'm talking about the property transform origin before before 73 transform did not have this transform origin Property that uh and now yeah now it's available and it allows us to change what is the what is the center of our transformation and it is great for uh rotate for rotation for translation and so on so for example in this situation uh this transform origin is top if I move it to Center which is the default one the square will move based on the center point that's going to be the origin if we however do top it's going to move based on the top Axel if I for example do an array here top left zero no we're we're going to learn how to do it probably it wasn't like that but it's going to uh it's going to help us this transform origin is going to help us to rotate our Instagram story story uh in a threedimensional way um we could use a r native CLI to initialize a r native 073 073 uh but I usually like to work only in Expo uh so that's why to use rack native 073 in Expo we need uh to use the SDK version 50 were above at the moment of recording this video this is in beta and it was launched previous week haven't tested it yet but we're going to do that today uh we're not going to dive deep into like the the update and new things from SDK 50 but we're going to use react native 73 to take advantage of that um transform origin let's go ahead and initialize a new project with um using npx Create Expo up we're going to go with a template blank at beta uh I'm using at beta uh for now to use the beta version in your case you can if you're watching this when XD key 50 is public you'll be able to do template blank for me I still have to do beta let's do IG stories now Expo will create a new project hello Amir hello caum how are you doing guys oi Solomon let's go Universe experts love from pakista hello Pakistan sorry I missed misread that hello hello so here we have it our application is ready I'm going to open it in a a visual studio code here we have it let me move it a bit out of our way I'm not going to need that terminal anymore so I can close it because we are going to open a terminal inside our Visual Studio code from the top or with a shortcut from here let's go ahead and do npm start to start the development server and while that is happening let's look at package.json package.json uh here we will see that we are using the Expo version 50 which is currently in preview and the react native 073 the one that we need perfect let's go ahead and from the development menu here we can run either on Expo go by scanning this QR code or on your local simulator or emulator I'm going to run into an iOS simulator here it should be this is a different application I'm working on famifi for financial management if you're interested it's available Play Store and app store all right anyway uh here is our application if we open upgs here everything is working fine it complains about something so I can make sure to import react here even though it's not needed anymore so here is our application and we are ready to get started we are mostly going to work in this up uh folder file sorry and we can go ahead and start rendering something the Instagram UI is heavily based on full screen images right so let's start by displaying a full screen image react native we have a image component that we can import from here and instead of rendering a text here what I'm going to do is I'm going to render an image the image needs a source and the source will have a URI and here we need a publicly accessible URL to display the image I will provide you with some dummy where are they here they are I have some vertical images uh let let let me Define it here at the top um you can check the URL not just D do s free us is to Amazon aws.com vertical images 1. jpg now if I provide this URI here we are still not going to see anything because an image needs style and for the style we can style them here at the bottom so let's do styles. image style. image what do we need here we need some whff so a whff can have 100% of the parent component which is going to be 100% of the screen and let's do the same for the height so if we do 100 100 our image is displayed full screen here for the status bar instead of Auto maybe I can do light yes now it's better okay that's good that's already a starting point of rendering one image let's go ahead and now create an array of images or maybe an array of stories um let's go ahead and do that together maybe we're going to do that in a separate file just to keep our upj clear so let's do stories. GS and here let's start start by export default an array and what's going to be the array created off I think the way Instagram works is we have a list of users and every every user has a list of stories so let's let's actually Define it as a const so const user users stories is going to be equal to an array of users for example user ID one will have some stories then there will be another user maybe he will also have an um let me see name if I go there it's a username and that user will have some stories then there will be another user with id2 then the third one now the array of stories will contain the array of stories should contain information about the stories one story for us is going to most probably be an object with some data for example it's going to have uh the image URI let's paste here uh the dammy U from here like this and if we want to add one more we can add it here in this array I think I will like to separate them like this and I can add another image here and for the third one as well let's do three let's do the same stories for this for the other person and for the third user as well we're only going to change some names let's see one two three four five six 7 so we have one two three then we can do four this one is like this then we have five six let's do three six and seven Okay so we have an array of users and all the users have an array of stories let's go ahead in our app.js and import this array let's go ahead and do import user users stories from the file that we just created called stories we are not exporting at the moment anything here so let's simply do let's transform back to export default now user stories if we want um to display some images we're going to have to look in the user stories that's an array so we can take the first user and then we can look into the stories and then we can take the first story or the first user then. U URI let's see what do we see here we should see the first story of a first user come on unexpected token in the stor is where do I have an unexpected token here I forgot to add comma okay now yes now we see if we change to the Second Story we're going to we are supposed to see the second story then third one and so one well it doesn't have free stories only two and the same we can change whose users we are looking at okay good so that means that we're going to have two State variables one to know who who is the active user and then what is the active Story number let's try to add them M State variables user index set user index equal use State let's start from zero now let's also keep track of the story so story index set story index equal use State let's also start from zero now I'm going to get access only to the user by looking into the user stories at position user index that we have here and maybe I also will take his stories for us easier to access them here by doing or let's do story equal user at position story index so now with this user and with the story we can render the user interface for example the image now will be simply story not story index but story do URI here should be user. stories at position this one yeah okay so now we see the the story another thing that we can do is uh to render something on top of this image for example like um like the name of the person who who posted it um we I'm I'm thinking whether we should use a background image or a simply simple image with position absolute Let's uh let's create a view that will have the styles of a header styles do header in this view I just want to render the name of a person the username of the user so user do username let's give this style styles. username and let's go ahead and style this we're going to have a header and we're going to have a username uh the header let's position it absolute to be positioned on top of the image uh probably it's not going to be rendered on top of the image because we first have to render the image so that it will be below our header hopefully uh top 100 yes we see that so our header let's start with a background color red just for us to see where it is I want a wave of 100% definitely and I want probably top zero in order to position it there but at the same time I want the content inside it to be rendered in the safe area view so what I can do is I can transform the header or maybe I can use here a safe area view from reck native that is supposed to add some podding in order for the text to be rendered below the safe area view now it works properly save area view header now if I'm going to add something to the header like Ping that's going to not work as we [Music] expect ping 10 no it's going to work yeah okay okay so we need pting 10 and for the username I'm going to do color white font weight bolt maybe that's it I'll remove a background color red perfect but maybe I can leave here and something like a 0 0 0 with some opacity like 0.5 that looks okay it can be improved by adding a linear gradient instead of a hard um background there I see it um Instagram is actually not even displaying the story full screen it display even the story inside the safe area View and everything in the background is black if you do this with image and videos it will be legendary I plan to do it only with images but but we have covered a lot in this series about videos so it wouldn't be very complicated to integrate videos as well when would you make one with recognitive skin how to think about using that with animation map actually I was I was looking today for for skia and it's hard for me to to come up with an interesting idea I don't know I'm still thinking about a good tutorial for that maybe like building in building Instagram stories with being able to drag and drop stickers on top of images uh texts adding Styles adding filters yeah I think like a best example for rec native scale would be the story builder in a way wait you can do that with safe area view what what exactly the safe area view yeah well simply is a component that adds pting on top and the bottom depending on the height of um of a notch so on some devices it's going to be zero because they don't have a notch on some devices it's going to be as as long as the notch is so it doesn't have to be only on the root view it can be anywhere uh but I'm thinking whether to actually put this one here because that's how maybe not there but yeah let's try uh safe area view style Flex one and background color black actually I don't need this container so I'll move this to the container and simply send it to the top safe area View and I don't even need the maybe that's going to be post container if we need that later because it contains the not the post but story container and the on the top that's the page container so that that's something that Instagram has and they uh they round a bit the edges of uh of the image so they have border radius then something like this and at the bottom they have also like a like an input so for the story container there is also a a a footer that we can add right now um and the footer contains like the input we're not going to cover the the the that one but I just want to show you how to add it and to style it footer so if I go there for a footer I can also position it absolute maybe I should have done the other way the image absolute and the header and footer to be properly but that would also work bottom zero let's do a height of 100 and a background color black but the footer shouldn't be absolute footer should actually be should actually be there and that's why where is it I don't see it okay it's at the top uh Hooter should it be okay okay okay okay I'm going to move back the problem is that the image has height 100% instead of that I can do Flex one you don't want that oh boy wait a second yeah let me make the image let let me make that one position absolute still no still no uh okay I'm still looking so we have a image with everything on top and the footer is completely separate of the image so that means that the footer will go even outside here and the story container Flex one yes so the story container text takes all the available space leaves some space for the footer which has the where footer which has the background color black and here in this footer we will probably put for example an input I said I'm not going to do that but in order to to see that it actually works let's do here an input that we will only style and not implement the logic of it so for the input I need a border radius not border radius border with one and Border color gray okay we have a input varer uh it needs it's sping 10 and Border radius to make it Circle to make it round border radius 50 okay and the footer itself will have a ping 10 and maybe it will not specify the height because it will take as much space as it needs and the footer will have um placeholder send message and the placeholder color will be white just like that and then we can start typing and we can we should also do change the color on the input itself to change the color of the text that we write so white okay just like that we have this footer as well uh and our story container is this one above that has the image the image is not absolute but the header is absolute positioned and on top of the image with a username and anything else that it will need there perfecto okay cool what's next now we have a UI of one story I think I think it is time to add some navigations between stories what we want to do is whenever we press somewhere on the screen on the right side we we want to move to the next story for that we need to handle click event press event to do that we have a component called pressible in rack native that handles these press events what we will do is we will have two presses one for the left button and one for the previous button let's style them with Styles Dot uh left right button or navigation nav pressible uh and let's do one more below or maybe we're going to focus on only one so let's go and style this navigation pressible and I'm going to start with a background color red just for us to see it if I'm going to say that the WID of this one is going to be only 30% of a screen and the height should be 100% of a screen okay but we also need to make it position it absolute to put it on top of the image just like that and we see that 30% of the screen here is this PR deible component and when we press on this one on press what we can do is we can go to the next story or previous story previous story let's call this function let's implement this function for now it will simply say console war previous let's do one more function like this for go to next story and console war next so if I press on this one we see prev let's go ahead and add one more for the next story if I simply duplicate it it's going to put it also here on the left however I want to keep all the Styles except I want to position it on the right so I will add an array here and say WR zero so now if I press here that's going to be also previous because the onpress event here should be go to next story and whenever you have like the syntax like this an arrow function that call calls another arrow function and they have exactly the same parameters you can simplify this by sending directly the arrow function that you need so now it's simply and we can go next and previous that's cool all we have to do is make sure that we don't have any background color red now we don't see the buttons but they are still there and they are still handling press events now let's see go to the next story what do we have to do we need to increase the story index so let's do a set story index um index and we're going to do index + one so we're calling the setter and we're giving an update function having the current index we only we we can we should increase it by one so now if I'm going to press next we should see that the image the next image loads it takes a bit of time just because it takes time to actually load and download the image uh now if I'm going to press one more time we see cannot read property URI of undefine why because we we navigated to the third story but our user doesn't have that many stories there so what we can do here is we're going to add some logic when we update let's make it as a function body and this is going to be a return uh the logic is going to be the following if current index is equal if we are currently at the last story but how do we check if we're at The Last Story we check if the current story index is equal to user do Stories the array of all the user stories do length and it should be minus one because if the index is at free and the item has free okay if for example uh we are at the last item here for the first user that's going to have a index two because we go 012 and the length is going to be free so that's why we are checking if the in IND is equal to the length minus one that means that we are at the last story so we don't have to increase the index what we have to do is we have to go go to next user we're going to call this function let's go ahead and implement the function const go to next user and we're going to see what we have to do there but here we're not going to return anything and yeah we can do return zero because we want to start from the zero story index here now when we go to the next user we're going to start from by simply increasing the user index so set user index we're going to take the current index and we're going to Simply increase it to index plus one now if I'm going to go ahead and click once we're going to see the Second Story click second time third one and now we should go to the next user and the username at the top should change so if I click once the username changes and now I can look through this users pictures and then I can see the the last one perfect so go forward works but we can still get out outside of this array when we increase the user index to a value more than that we currently have users so what I'm going to do I'm going to add some logic here as well by checking if the index of the user that we are looking for is equal to the last user in the array of users stories do length minus one if that's the case I'm going to return zero to reset it to the first user otherwise I'm going to return this one and in this situation we don't need an else statement because in the if we have a return so it will never never reach here if the if statement will go inside so now we should basically be able to Loop through them if we reach the end of the whole list after Alex if I click a couple of more times I should go to the my first story and we should be able to do it do it again okay cool perfect so we have a possibility to go next next next let's do the same to the same logic for go to previous story uh I'm going to copy this function to the from next to previous because what we will have to do is quite similar at the end we're not going to increase it by one but we're going to decrease it by one and our if statement should protect us from going below zero because if we go to an index below zero that will also trigger an error so we should check if the current index is at the moment at zero what we should actually do is go to previous previous user and I will return zero to start from his pre first one because at this moment I don't know how many stories he has let's implement this go to previous user in the similar way to how we did go to next user go to previous user set user index again we are going to do minus one and we're going to check if we are at zero then we will go to the from V way we are going to return user stories do length minus one to start back from the last one so now if I go back I go back to elen here I should go yeah I'm going back to my uh stories then I'm at the first one from Alex I can go next next I can go back back and then I'm yeah so now all the navigation between stories next and uh back and forth are implemented we have four methods probably you can do this in a better way in just two methods instead of having go to pre next and so on just to to update with things but that's okay as well can you please also show how different Android vers verus iOS is in terms of the key things to just look out for so that one would not waste time especially for new Apple environment users seeing them side by side would be great also I like your consistency keep up keep it up thank you very much Justice uh I'm we are going to uh run this application on Android as well to make sure it works okay guys so we have basic navigation between stories I think it's time for us to display the story indicator at the top here I'm talking about these lines at the top that shows what current story we are watching how do we do that well that's going to happen inside our header so where is our header the header is here and above the username let's go ahead here and say um we're going to have a view that will do indicator row that will contain all the indicators then inside here we're going to have multiple views simple views with style equal styles do indicator so we are going to every line is going to be a view inside this indicator row so if I'm going to have three of them here uh then we can go in our styles to provide some styles for indicator uh row and indicator itself I'm going to start by styling the indicator to do that I'm going to give it some width like 100 and height it's going to be small it's going to be a line of five pixels or something like that we don't see anything because we need to give it also a background color we can start with gray okay we see a line that's already good actually that should be free lines if I add some I I don't want to add padding to the indicator I will add a gap on the above on the parent and that will add some spacing between these three lines we see currently that the lines are one on top of each other let's put them in the same same row with flex Direction row on the parent container now they are threee lines we don't take the full amount of space because we have given a fixed wave what we want to do is we want the the row to take full wave so I can check that if it takes full WID yes it takes full WID and I want the space inside the row to be equally uh split between the indicators to do that instead of specifying the wi I will do Flex one and they will take the necessary amount of space and at the same time allow others to to coexist with them so let me add here to the indicator row maybe uh margin bottom 20 um and at the same time for the whole header I don't want basically any pading at the top because I want this view to be almost flush with the top yes something like that now the indicator itself they are rectangles currently if we want to make them rounded we will do border radius 10 now we are better perfect perfect perfect let's go ahead and highlight them well no instead of highlighting them I don't want to render them here manually I want to render as many indicators as Stories the current user has so that means that I'm going to have to Loop through stories or user do stories. map and for every story I will render one of these indicators I will delete the ones so now we should see exactly free just because in our stories GS we have fre stories here if I'm going to add one one more you're going to see that it automatically adds one more line at the top so now we are Dynamic now I want to highlight them to highlight them I will simply give a white background so I will add a conditional style here that will set the background color and it's going to be white only if the index of the story that we are currently viewing is more or equal than the index of the indicator that we are displaying so I will need the index of the indicator and it's going to be white if the index is less than story index or actually less than or equal if that's true our background with a question mark is going going to be white otherwise is going to be gray maybe not full white but gains b or maybe ghost white yeah ghost white is better and this one maybe light gray no there is not enough contrast dark gray is okay okay perfect so now we are on the story uh with ID zero and in the array of our indicators only the first one is rendered as highlighted if I move to the second one now the second one as well and so one the third one and if I go here and then I go to the next one boom boom boom h how to do it it it it's not very visible to be honest maybe gray like this will be okay maybe we don't need anything here oh we're going to need something there okay look I'm going to take very not a lot of time I'm going to only install Expo linear gradient because a gradient Veer will look much better so let's simply install in our application Expo linear gradient come on and we are going to render this gradient let's first import it at the top and render it where inside the header inside the header let's render the linear gradient m I will remove this one from here and our linear gradient where is it I want it to be Styles absolute fi and now we have a proper linear gradient there at the top I think it looks much better when it's like this and it starts from uh 80% transparency and at the end it's 0% transparent perfect maybe from 60 70 that's good all right guys so now we have the header story as well I think we can decrease the height of those to three just like like this um what I'm going to do next is prepare us for for animations because at the moment um with the way that we style the indicator the indicator is one simple View and we can only have one background so it's either the whole indicator is gray or the whole indicator is white we cannot have like a progress bar where let's say half of the indicator is white and half is gray to do that we're going to have to split the indicator into a background and foreground so let's let's let's leave indicator for the foreground and let's wrap it inside another view that will have the style styles. indicator indicator indicator dot indicator BG for background okay okay now let's go ahead and add indicator background above our indicator and we're going to have to move some of the stuff from our indicator to the background such as the flex one is about background the height is about the background because the background is actually the whole component the background color will always be gray like this and yeah also the background the background uh indicator will have border radius 10 the indicator will only have background color white and that's it background color white and maybe also height three or better height 100% okay so now the indicator has this height 100% but if the wi is going to be let's say 50% that's going to show as a half progress bar cool perfect the only thing is that now the way we are going to the the conditional the logic is going to be different because we are not going to decide the background color now we have the background that is gray and the foreground indicator that is white that's it we' no longer change the colors we only play with a wi of our indicator depending on so if we want full white we're going to have with 100% that means that if index is less than this one we're going to have a 100% with otherwise it's going to be let's say 20% but that's going to be later improved so just like that uh we updated it and now we can have a progress based animation that will drive this progress of moving to the next story as you can see here uh yeah as you can see here the the one that we passed is full white and vals are at 30% in a moment we're going to add actually progress there so that we can see how it moves from one to another then [Music] okay perfect overflow hidden for back indicator background overflow hidden if I don't want yes yes yes you right um overflow hidden our back indicator background has this border radius 10 but the indicator didn't have it so it's either we are adding border radius to the indicator as well but this will add in two places on the both ends where we are doing overflow hidden and it hides everything that overflows this component nice okay Next Step hello kenry our next step is uh starting with animations the animation of the progress bar that will that will automatically switch to the next story after some time and it will be represented by this progress at the top for that we're going to need ranimated so let's install that inside Expo uh let's go ahead and start by installing npx Expo install re native reanimated let's do clear and start with npx X Point install react native reanimated okay now let's see what other things we need to do we must add the Babel config plugins reanimated plugin let's go ahead and add that to our bable config under presets next we need to restart let's start try to restart our development server with clear but I'm going to go actually in the reanimated docs to make sure if we did didn't uh if there is no extra steps that we have to take so let's go ahead and get started installation okay then we add the plugin then we don't need web support so yeah that's that's it that's it I will simply have to do npx Expo start-- clear let's run it on iOS and before moving on I will fix this error uh each child in a list should have a unique key property that is coming from our app.js from where we are rendering the stories story indicators uh whenever you are doing do map the first component that you're rendering should also receive a key property which should be unique to this story so I'm going to do it's going to be a combination of no actually it's going to be simply index I'll keep it simple for now and use the index as the ID okay cool now that we have reanimated installed should we look at one simple all right we're going to take it step by step together I'm thinking how to do it uh in a easier way anyway we're going to need a couple of things first of all we're going to need a shared value that will represent the current progress the current progress of viewing a story shared value from reanimated R native reanimated he use shared value is a value declared on the UI State no it's not like this we need progress is equal use shared value it will start at zero based on progress this value is going to go from 0o to one 0 to one where zero we just started watching and one means that we finished watching no matter how long that means like 10 seconds 5 seconds and so on this is simply a progress 0 to one or 0 to 100% based on this progress we're going to be able to create animated Styles let's import use animated style and using the use animated style hook we can H for us when we're going to start like all of them will move at the same time so let's let's just simply say um indicator animated style is equal to use animated style and here it's a function that returns an object so returns an object like this here it's similar to a Styles sheet so we can animate different properties for us we will animate the wi because if you see here the wi is the one that we are interested so it should go from it should be a percentage for example it can be 50% Now using this indicator animated style we have to provide it to a component but that component should be an animated component for that we're going to import animated from react an animated not D structuring but everything and most default components like a view is already part of the animated so we can simply replace a view to animated. view I'm going to do that on the indicator background actually no that shouldn't be indicator background it should be the actual indicator animated. view now an animated. view can receive an animated style let's take this animated style and I will replace it instead of this uh object with a whff so now our animated view has some static Styles but also some animated Styles as we can see all of them are at Midway at 50% because we have hardcoded the wave here to 50% in animated instead of that if I'm going to transform it to a template string and instead of 50 if I will use the shared value that we Define above progress but because progress is going from0 to one what I'm going to do is I can interpolate where I can simply multiply it by 100 and the progress should be accessed by progress. value so now our style for the indicator is going to depend only on the progress if I go at the top where we declare the progress and we say that hey it's 0.5 we're supposed to save M half if it changes to 0.7 I'm not sure why it's not changing in real life but we're going to see that in a moment so we see that by changing this progress value it changes how we see the indicators if however we want to um to to animate this what B yeah in order to animate the progress here logically what we have to do is to animate this progress value not animate but start moving it from zero all the way to till the one till one in a specified amount of time for example in the next 10 seconds slowly increase from 0 to one to do that we have things uh we have wave timing that we can import from RE animated and with timing allows us to run time based animations where do we where will we trigger this let's go ahead and Trigger it in a use effect when the this component mounts we're going to change some some of the things I just want to to us for us to get started in a use effect when the component mounts what I can do is I can change the progress which is our um which is the shared value that drives our animation and the value I will change it to to one for example if I do that if and if it starts from zero you'll see that it right away jumps to progress one we don't want to jump to progress one we want to move in that direction so let's wrap the one into the with timing and now if we do that as you can see it moves there we can slow it down using that duration using an option in the timing called duration let's add it as a variable at the top called const duration or story view duration equal to how long 10 seconds or yeah 10 seconds multiply by 1,000 milliseconds so story view duration we're going to pass it to this with timing now the story should start loading and it should take exactly 10 seconds for them to reach the end boom and we reached the end perfect that's already good if we simply restart it should start over yep um some of the things that we can do here is for example when we change the story index either going back or forth we want to reset the progress so what we can do is we can do a use effect that will be executed when our story index changes so when that happens we can reset the progress value to zero now if I go to them if I wait a bit maybe I will reduce from 10 seconds to 5 Seconds um yeah a story index changes initially [Music] well I can do or maybe I should simply do the way I will put this one no I will bring the progress value here so that we will start the animation and we don't need the previous use effect we will start we will reset the animation and we will start it whenever we change the story index so now if I change the story index it starts again it's not the correct one but we don't worry about that at the moment we simply want to see the the progress bar going there nice perfect the default using with timing is not linear maybe you should change it that's correct uh thank you very much for that's exactly what I was looking for at the moment um the easing is basically the function that is used for the timing if it's linear that means that the progress will change linearly from zero to one by default the wh timing has a different um easing and this is visible where if you pay attention maybe I will do one big story instead of three as you can see when it's in the middle it goes faster and when it reaches the end it slows down this is a yeah now it slows down in order to change that we will provide to the with timing the easing and we can access different eings methods here from RE reanimated eing dot let's do linear now that that should happen linearly very constant progress all the way till the end okay okay okay the think is that the next step I want to do is I want to fix this issue that we treat we we animate at the same time all the bars and not the the current the current one [Music] what can we do maybe we should add this indicator animated style conditionally I was thinking of extracting into a separate component which probably is going to be better and handle handle them separately but a simpler way if we are still here is to add the indicator animated Style only if um the index of the of the story or of the indicator is equal to the story index only then we're going to add the indicator style so now this one is loading if I go to the second one the second one is loading and the other ones are stuck at 50 where is this 50 coming from I think we have coded it here as 50 in the indicator should well this wave for one that is not currently active is going to be different depending on whether it's before or after the current the current story so what we can do is we can check if index of this story is more than the story index then I want to say that the Wii should be if if current the wave should be zero and if index is less than story index then the W should be 100% so everything before the the current active story we'll have full foreground so basically they will be look white that everything after will have zero they will have only the background and only the current story will have this indicator animated style let's look here if index is less here it works him go to the next one yeah yeah yeah it works so we reach here and we stop then we can move to the next one it moves moves moves it stops and we come here well you know what uh when I go back the progress doesn't restart only when I go forward it starts from zero and that's because when I go back the story index remains zero so I need to change this both when the story index changes and when the user index changes right so so if I go back it starts from zero yeah there are also some jump Cuts uh when I move to the next one it looks like it's full first and then it moves to zero it it has that jump and I believe that's happening because when we move from one user to another our indicators they will share the same key because we are using the index as the key so basically the first indicator from this user will share the same component with a first indicator from the next one that's why we have these jump Cuts uh I will probably simply assign uh use a combined key here from the index of the store together with the user index so if I have user story user do stories yeah user do user ID now if I restart it still has this one yeah because at the end of the day like we are looping so we still get there in a real situation we would not see the same story twice and um that that small issue is not going to be present now it's present only because we are looping through them progress can be story length multiplied by 100 what do you mean let's see the default eing for okay we implemented that it will be easier to separate indicator to component and provide their progress it will be easier to separate indicator to component yeah we could ex yeah definitely like whenever we we already have a lot of stuff in this file so a better approach would be to extract this one to a separate component and keep all the logic about indicators there but I'm going to still keep it here maybe at the end we're going to look how uh at refactoring it but now it works correctly perfect uh another thing that I want to do is the next step is going to be automated next page basically so when the progress ends if we reach one I want to move to the next story to do that what we have to do is we have to basically listen to these progress changes when it arrives at one we need to call this go to next story what we can do in reanimated is we can have a reaction to a if we go to Advanced use animation reaction allows us to respond to changes in a shared value it's especially useful when comparing values to the previously stor values so what we can do is use this use animated reaction and let's implement this animated reaction inside our component uh I'm going to add it somewhere here so what value do we depend on WE depend on the progress do value and because it's only one value I can remove a return and I can remove the cly brackets for a shorthand and auto returning Arrow fun Arrow function now we're going to have current and previous value we can check if they are different which means that if it's the first time and if the current value is equal to one then let's do here go to next story let's see if it works I'm not doing anything I'm not clicking anything if we reach the end the application closes perfect for more re animated tutorials subscribe to the channel I'm your guy uh what happened there why did it crash completely instead of go to next story let's go ahead and do a console log progress finished let's run it again let's see what happens when we reach the end it says progress finished but I didn't like us calling the go to next story because yes I remember I remember the lesson from Cataline in day six when we have done that one we cannot call a function like this we need to call it the the use animated reaction will be executed on the UI thread the goto previous story is in our JavaScript thread that handles like uh State and so on so by calling it by calling it here we are trying to call a function from the JavaScript Fred when we are running in the UI Fred that's why the application crashes what we can do is we can import a separate function run on GS from reanimated and this function will have an X syntax in the use animated reaction we're going to do run on GS we're going to send V the function that we want to run go to next story and at after that we need to call that what run on just returns so we are simply running on GS but go to next story let's try again and it's the same problem r on GS where is uh Cataline Miron when we need him uh run on GS let's see use animated reaction the value return from this function is used as the first parameter of react argument the react function has two parametry the current value K and the previous one use animation reaction valum result as ensuring you do not motate the same value in the result function that you have used in the prepare function as this will lead to an infinite Loop maybe we are in an infinite Loop because we update this one where the progress changes we go to the next story but it's not going to be no no no it's not going to be because we only execute this one when first of all they are different and when the current value is one go to next story let me oh Cataline is here hello cathalene I was screaming for for for you ver caline so um not sure if you've been following but we need your your help it is actually added before the Declaration of goto function so that means that the it should be simply added below the functions that I'm running there if that would be if it's that the solution i' would be surprised wait I have to wait yes it works thank you go subscribe to calin's channel guys he he is the master of of animations okay so when it reaches the end it moves to the next story okay but if I abandon one of them I saw there was a bug YouTube sent you a notification it understood that I need help uh so what's the next steps cannot read property U find ify that's the next step please please no bugs I I'm not in I don't have resources for bugs today look what why are you stopping there come on what I would also like to try you know what is hold or long press to to stop the the storry or maybe we can do that later let me try to implement them that Cube animation for transitions between different users that's going to be fun uh okay let me go ahead and do what do what I'm a bit uh lost we want the cubid animation or I don't know how it's called a 3D animation when we move from one user to another that's going to be fun you know so okay good to know about that thank you cathaline but anyway I remembered I remember from from from your lesson to to use the r on GS and in the animated reaction okay look what I want to do is probably I'm going to I want to start from scratch just for us to focus on that animation and after that we will think how to introduce it here so what I'm going to do is I don't know maybe yeah let's let's start extracting some of the stuff in components and that way it's going to be easy to just comment it out so let's create the components folder and the first component is going to be an actual the the whole Instagram story UI so let's create a new file IG stories. GS I'm going to move most of the things from upds actually I'm going to move everything from upgs there and I'm going to remove some of the stuff that should be in our upgs and not in IG stories for example the safe area view no actually I'm going to leave everything maybe the status bar is not here here back in our up. GS let me simply remove everything from safe area view we're going to get our ABDO back to normal uh and I'm going to remove our functions here they are not about our application they are for the Instagram Stories the Imports can also be cleaned up a bit so now what I can do is I can import the IG stories I just have to rename it from from up to actual export default function IG Stories the data that it Imports will changed relative to this folder so I have to go up one folder and I have to import it in our upgs from components IG stories and if I simply render it we are back to to what we had before everything is still working but now it's managed by this component and what I can do as I can comment it out and now we can focus on the animation uh and later we're going to think how to integrate that in IG stories so for the animation what do we need I don't know let's start with a simple view that will have uh some withi let's calculate the WID as I don't know 200 pixels initially uh it will have an aspect ratio of RA ratio of 9 over 16 or by other way around and a background color The View should be imported from RE native and and yeah basically we have now a a container I will add here a line items Center and justify content Center so that our box is in the middle okay do you know a better color than Simply Red I will pick something from here from the documentation even it's going to be this one okay so we have a view what do we want to do is we want to rotate him in a 3D way we can accomplish that using some transforms for example if I will use a transform which is an array of different transforms I can rotate this view on different axis um if I want to rotate it this way that's going to be rotation around that axis so uh 45° on this axis will look something like this and minus 45 it goes the our way um we don't want on the Z we want this one to move around the Y AIS so if I do y we don't see anything changed but actually something changed because if I will do here 45 that it get it it is getting smaller and if I will reach 90° then we're going to see that view from the side that's why it disappeared so this is the rotation that we want on the x axis the problem is that there is no like perspective like when it's 55° we don't really understand that that's a view rotated 55° we can use a perspective a perspective transform and if you give it uh a value that's going to be the perspective from which we look at that view what should be the perspective value actually it's that distance from the camera to the object is that what it means and if that's the difference from the camera because I imagine yeah if I increase it we basically move further away from the object and the rotation looks smaller if we go close to that object the rotation looks like really huge it's basically like object is here and the camera moves back and forth and that is going to be the perspective that's how I understand it and um should it be should be what I don't know let's try to leave it like this for now now our rotation work uh looks better and it's clear that that view is rotated if it's minus 45 it's going to be the way around if it's almost 90 as well we're going to be able to see this this rotation okay that's it that's everything I know uh no uh wait a second wait a second 70 Dees now talking about the transform origin that we that we depend on at the moment the rotation happens based on the center of our plane this is going to look uh make more sense If instead of rotating on the Y I will rotate on the Z with 20° or 45° by default it rotates but it keeps the center in the middle so if I will change this value you'll see that it simply rotates around its axis where the center is the origin of our rotation from R native version 7 073 a new property to the transform what was added and this is the transform origin the and it shouldn't be inside the transform I think it's a separate one transform origin and by default that's Center so if we set transform origin Center that's how it's going to work it's going to rotate based on this one if however we say that the center the rotation should happen based on the top part of our view now the rotation as you can see looks like this it basically rotates around the top point the transform origin uh can be an array of fre value use for example the first one is where is the origin on the X let me look at in the documentation to do not left center right two value syntax that's for I don't know what yeah the first one is X the second one is y and if we use free values that's going to be x y and z z for x and y in our case we can leave it as Center on y we can leave it as Center but on z z axis we want to to rotate around the point that is behind that is the center of a cube right so we have a cube show me a cube we have a center of a cube so when we rotate the cube we should rotate around the center of that cube in order to have this 3D animation the center of a cube will be the width of the cube divided by two and I think it should be minus because we want to move the center to be behind uh the The View itself what happened transform origin exp position must be a number you don't want you don't like Center uh yeah it can be in Array style I think it doesn't accept like Center it accepts percentage so I can do 50% and with the with here I'm going to move back to rotate Y and now the yeah the transformation should look a bit differently let me actually go ahead and start animated this rotation like crazy with with a animated value uh let me do it like this I'm going to import animated from animated this one is going to be animated. View and I think I [Music] can let's add here um a progress that progress is going to be a use shared value let's import your shared value from from there uh what I'm going to also do is I'm going to define the the animated Styles so const animation equal use animated style as well imported from reanimated uh so let's Define this animated style and we want to animate there the the transform so let's go ahead and take take this transform object in our animated style and let's pass the animated style as another style to our view here animated okay now we we can uh change the degrees here based on the progress and I will use here like this and the value of the rotation is going to be an interpolation we are going to interpolate the progress do value it will go from 0 to one and the when it's zero we want minus 90° and when it's one 0° I don't know we're going to figure this out later I just need some movement on the screen now we need to start moving this progress and we're going to do that when the component mounts uh or maybe on a button I think it's going to be easier if we simply render a button but here run and when N1 press what we are going to do is I'm going to let's call a function instead so when I run animation I simply want to move a progress. value uh to one using the with timing maybe I will reset it progress value to zero and then move it to one with timing let's import it as well so now if I press run nothing happens of course progress value run run run run on press run animation value progress value animated style progress do value 01 - 90 90 uh why if it's going to be zero here it's going to be here oh because the button is probably on top of this animation so style a button cannot have Style what's going on bottom 50 let's see if the button is at least pressed yes it's pressed so now the question is why animation is not running with timing because our view is animated view Tories progress heyim how are you good good uh working 90 come on what's what's going on if I change maybe something else like scale X not scale but I don't know opacity to progress. value and if I press run no it doesn't start moving progress that value change to one okay but why with timing is not working couldn't termine the version of native part some issues with no there is some issue here but why I believe uh maybe I'm not sure but I would simply have to because I'm using the beta version of uh Expo maybe very something not working there uh yet but I'm not sure so I would I would do npx Expo run iOS to build the project locally and I hope that will fix this issue so while this is installing probably we can work a bit more for the other stuff to to think about the the logic of how it will work or we'll probably have to wait hey seun thank you very much appreciate it oh that it's it's going to be be interesting because we're going to have like multiple sides or pages planning the build in a second we're going to be up and running let's go ahead and put some music while we are waiting well I think you cannot hear the music for some reason let's go oh boy we are almost two hours in and I have meetings in one minute let's hope that the team will understand me let me write them a message so yeah let's let's try to wrap up uh quickly so that I can join the other meetings also have um group coaching call today with Academy students so that's also important let's see if this will work uh most probably I'm not going to finish the animation of this Cube animation I want to give like a starting point for you to understand like how we could implement it what properties we're going to use like how to use this transform or origin um and then I will leave it uh to you to try to integrate it with the rest of the stuff that we have built today for the Instagram stories this is complex task generally split it two days yeah we are we are covering like a very wide range like starting from Basics like rendering images and so on we didn't have like anything pre-made so and now we are getting into like a bit more complicated stuff so we have our application built locally let's try to open it there and see if in this situation reanimated would will work with us if I press run yes yes it works so let's go ahead back here that progress value is going to be zero now if I do run it works I don't need to animate the opacity I'll keep it like this I need to only do this maybe the duration let's do it uh longer just for us to see like what's happening so now we see how the animation goes I think that we should not be this is the back side of our card I think we should not see the backside uh and I'm not sure like how to to fix that uh r native rotate view hide uh the back I don't know like it's so disable rotation for no no no no no hide backside of a rotated div using CSS maybe uh the CSS property back face visibility okay so let's try to see if we have this one in re native back pH visibility false and if we do that is should it be a string hidden and now if I run yes we do not see the back side of our view okay perfect I think that looks quite nice what happens if we will make this view full screen I don't know but yeah maybe we're going to think about that a bit later now let's think about how are we going to do this animation through different from multiple items we need to somehow merge them together right at least two of them so we're going to have like one more of these or maybe we're going to have an array of pages const Pages equal I don't know zero let's let's let's have Pages as colors here give me another color and this is going to be this one now this animated views they will be pages so we have to Loop through pages map page and for every page we're going to render one of these animated views animated for the color we can use the page color I just want to I just want to have multiple views like this okay maybe they will be a position absolute and that means that they are now on top of each other now we will also need to keep track of the of the currently active page so const um page index that's going to be a use shared [Music] use shared value maybe it's going to actually be a state I don't know so initially it's going to be zero page index now the animation for them H I think we will have to extract them to separate components the pages animated page equal to this because they will have different animations animated page let's copy this animated view to our animated page here uh the wi we can Define on top for for a moment the page color is going to be something that we receive page color and the animation we're going to move also from our application to the page itself it needs the progress so the progress uh progress should this be a value that we also receive let's try now let's go ahead and under this animated page where we Loop through all of the pages we need the page color and the progress but we will also need the page index the active page index because based on the page index we will know which one to show here in the center now when we run the animation we change the progress maybe the progress shouldn't be from0 to one actually maybe the progress or that should be a page index float page index float uh that will specify like yeah like the the progress of moving to the next page so it's not going to be from zero to one but it's going to be from zero to the amount of pages um so run animation let's see progress here it's not going to be progress but page index we don't even need the page index we need only one the page index float which I will keep it name as simply page index as you can see so now the page index we will send it here we're going to receive it and we can use it for our values we will also know what is the index of a current page because with with that we're going to understand if we are currently the one that we should display we can get that by taking the index when we map and sending it down to our animated page now our animation will look as following um the page index will um will go from index minus one to index to index + one and we need to specify how do we want to the previous item the current item and the next item to look like so in the output we will also have three values in the middle we want zero rotation here we want 90° rotation and and for the previous one minus 90 minus 90 or maybe even not 90 let's try or yeah let's try 90 boom we have something I just St so when we press on the button that should be probably next or something like that so yeah it simply switches from zero to one I can add here like more I don't know red yellow blue and when we press on run it should not be run but should be next uh when we do we don't have to reset it to zero we will do page index. value with timing towards uh page index dot Value Plus one and I will actually take the the mf. floor to round this to towards the next item so from the green uh and another lesson from Cataline was why do we see the last item as the first one where it's not even the last one right yeah it's the blue one we see it as a first one well we can change that by decreasing the Z index depending on the index of a file that of a page that we are rendering so in the animated page the Z index will be equal to the index or to 100 minus index now this is the first one then we can go to the next one the next one is green then it should be red it works oh my God to be honest I didn't expect this one to work like right like now oh my God and all you have to do is decrease that duration here to maybe one or even less and just like that you have animation and yeah it looks beautiful you can move from one screen to another The Next Step would be to probably the animated page to make it not with 300 but maybe with 100 the the Run button is not working anymore animated page duration no this one is too little and the same way we can go to the previous one so I'm going to add two buttons next and then I'm going to add another one previous go back so go back is going to be similar to our run animation but what it will do is it will simply do page index. value minus one so next previously it should be V way around right here go back next next yeah it should be our way and other way in the rotation I think it's like this next yes next next next next next previous oh yeah oh my God it's so cool and now now all you have to do is this animated page go ahead and add here uh the children property that you will render inside inside your animated view so if I will expand this one to animated view like this and put here uh render here with Children what I'm going to do is is in the animated page I will send here some children for example these pages instead of pages let me do images so I will import all stories let's import stories here import from stories and all stories I will simply do a uh user stories dot flatmap uh value user and I will do user. stories now the all stories is going to be simply one array of all the stories here and they will all have Ur that means that I can use all stories instead of pages to Loop Pro them it's not have a going to have a page color but it's going to have be a story so what I'm going to do is I'm not going to change send anything here maybe I'm going to change I don't know black and inside here I'm going to Simply render an image where the source is going to be URI story. URI and for style I will do with 100% and height height 100% what's wrong image should be imported from react native now that container renders the image it will have this uh border radius so we can do overflow hidden and if I go next we see that we can move through all the stories with this animation you can slow it down a bit to to see it better next next next previous previous previous just like that we have this animation uh and maybe you can even increase the width and height uh for for components but as you can see now this animated page is quite reusable it handles the logic of animated between screens but what you give what what you render inside it's really up to you so anything that you will send as children to this animated page will be animated so what you can do is you can import this one in our IG stories and you'll drra different users basically inside this component so it's really not much left to do there um and another step is going to be to integrate gesture handlers so that you when you swipe left and right you start triggering this uh animation for back and previous and that's it that was our Instagram stories we saw how to design and build the Instagram stories UI that looks like this right now it doesn't need the line Center we can move through them and also we saw how to add this um Cube 3D animation to go back and forth that is it for today guys um I have to really run uh my team is uh is waiting in the in the meeting um the exact issue index one index index plus one yeah perspective is too low try card with multiply by two perspective is too low Cataline is saying uh let's look at perspective of our wi multiplied by two so now perfect really looks nice you can even play with colors and other Shader so that when when it goes away it has like a linear gradient and looks like it's in the shadow because right now like I think yeah that that would improve it anyway guys thank you very much uh for for being here uh thank you very much for all your support uh we still have probably seven tutorials till the end of this uh series and if you enjoy them please subscribe to the channel down below and I'll will see you tomorrow
Info
Channel: notJust․dev
Views: 6,689
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, Global State Management, Zustand, Zustand Tutorial, Zustand in React Native, State Management, Persistent State, React Native Zustand, State Management Library, React Native Project, Application State Management, Efficient State Handling
Id: 8ZgSt3VJ5Mc
Channel Id: undefined
Length: 133min 27sec (8007 seconds)
Published: Tue Dec 19 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.