Rebuild an Awwwards Side Menu with Framer Motion and Nextjs

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's going on guys welcome back I came across a super nice menu by an agency called Aon Cartier and honestly I looked at it and I had no idea how to make that so I had to remake that menu so I separated this video in multiple sections and I'm going to take a look at all the inner components of that menu and I'll use nexj and for motion to remake it and as always you can find the live demo and the source code in the description below all right so I have a very basic nexj application here and we should have something like this A blank page to start this tutorial and now the first thing I want to start with is the button component there's two animations inside of it there's a perspective animation on the text and there's a sliding kind of effect with an overflow hidden so let's see how we can make this the first thing I want to do here is go inside of the layout and that's where I'll put the header in the real world application you want to put it inside of the layout most of the time because that way the header will persist across multiple Pages all right so here what I'm doing is creating a components folder and inside of it I'm putting a header and a button and then I'm just initializing those components and importing them inside of the layout and so we should have something like this we have the header here inside of the layout and then I have a header components which looks like this and inside of it I have a button component which looks like this and so I'm going to start with the simple styling for the header I'm just going to add like a button paragraph here just to see what we're doing and then I'll go in the styling of the header and I'll start adding some styling and the first thing I want to do here is put it in position fixed so that when I scroll it stays at the same place and then I can do like a right 50 pixel and a top 50 pixel and that way the header is like sticking to the right side of the screen where I I want the menu to be and that's basically going to be it for the header and now we can start working on the button so I'm just going to delete the paragraph here we won't need that and I'm going to add a little styling here I'm going to call this the button and I'll import the stylesheet here the first thing I'll do here is set a certain height and I can put like a background color just to see how it looks okay so I'm just going to reverse those values here and I'm also going to add a border radius of 25 pixels so the corners are rounded and we should have something like this and I'm just going to do a cursor pointer as well just so we have like the cursor indicating that we can click on that and and then if I look at the demo here we can see that the animation when I click on the button there's like two parts of it there's one that's written menu and there's like another button underneath that's written closed so I'm going to do that right now so I know I have two buttons so I'm just going to create two div and I have one where there's a menu and another one where it's written close and then I can add a class to those and it looks something like this and so I'm just going to go into styling here and I'm going to specify that the elements all of them should have of 100% and the width of 100% so it takes the full width and height of the buttton and then I know that one needs to be underneath the other and so what I'm going to do is Target the second one and I'm going to put it in position absolute with a top of 100% And it looks something like this and I'm just going to add a background color so we can see clearly What's Happening Here red for the first one and I'm going to do like orange for the second one and now we can see this and now to have the text in the middle what I'm going to do is the magic display Flex align item Center and just defy content Center and now everything is centered here and then all I have to do is add an overflow hidden and now to actually hide the element that's in position absolute for the Overflow hidden to work I need to also put it in position relative and now we can see that we don't see the second one that's at the bottom and now all I have to do is find a way to translate it when I click on the button I'm going to remove the Overflow hidden so we can clearly see what's happening and I'm going to put the right colors so I'll remove the red here I don't need that remove the red here too and I'm going to put the color that I want and then the second one is black and the color inside of it is white and also I want the text to be in all caps so I'm going to do text transform uppercase and we have something like this now all I have to do is find a way to translate those divisions up and down when I click on them so I'm going to go in the root of the header here and I'm going to create a state that's going to track if the menu is open or not so I'm going to have here an isactive and a set isactive which is going to be equal to the use state from react and I'm going to initialize it at false and then I'm just going to specify here that I am on the client because I'm using hooks which are client side functions and then the button here I'm just going to pass the isactive is equal to the isactive from the state and same thing thing I'm going to give it the responsibility of setting the menu open or not that's going to be the set isactive function and now inside of the button here it has access to the isactive property and the is active function and I can add on the button and un click event and do set isactive to the reverse of the active property so if it's open it's going to close it if it's closed it's going to open it and after that I need to create a division that's going to move up and down and so I'm just going to wrap those two elements inside another div that I'm going to call the slider and this guy will basically move up and down so I'm going to take those two elements and put them inside of the slider and now to animate the slider I'm going to use fir motion so I can go ahead here and import motion from frame motion now I'm going to add the motion tag in front of the slider and then all I have to do is specify an animation and I can change the top property of the slider is the menu active if it is I want you to be translating by minus 100% so it's going to slide up and if it's not active then I just want you to have a top of zero and now for the top property to be working all I need to do is go into the styling here now I'm going to specify here that the slider needs to be in position relative and now the element is inside the slider and I can save that and we can see this and now I'm going to click on the menu and boom it's sliding up and then I'm just going to reactivate the Overflow hidden and it's looking like this if I click it slides up and down but now obviously there's a weird effect here and I believe I simply need to specify that the slider should have a height and width of 100% so it takes the full dimension of the button so I'm going to save that and if I click on on it now that makes a lot of sense so this looks pretty clean to me I have the first animation of the button and to make this animation a bit more nice I'm going to add a kneeing and a duration just so that it looks good so I can come here and specify a transition and I can do a duration I'm going to do like5 second and I can specify an easing and here I have the easing that I customized for this animation now obviously it's a bit hard to visualize what that value is so one thing I like to do is go on e.net and here you can see like all the different eings and then you can choose one like easing out Quint and then you can grab that qbic baser value here and copy paste that to have like your own easing so I'm going to save that and we should have something like this very clean animation and as you can see it's a bit nicer than when I don't specify a transition it makes everything a bit more polished so now I can work on the second animation of the button which is the perspective animation and if I look at the demo here I can see when I hover I have like basically the text is like doubled and it kind of like slides away in like a square motion kind of so I'm going to do that right now I'm just returning a paragraph inside of each element but instead of returning a paragraph I'm going to return another component which I'm going to call like perspective text and this guy will return a div that I'm going to call perspective text and inside of it I'm going to return two paragraphs and here is just going to take a label as a parameter and I'm going to put the label so the text will be doubled and then I can simply take that internal component and I'm going to replace it and put one inside each element and I'm going to specify here the label should be menu and then same thing here for for the other elements but I'm going to change it and I'm going to do close and now it looks like this it kind of broke everything we have the menu we can see we have two menu and we have like two clothes so now it looks like trash but I'm going to fix that using CSS and I'm going to make the animation as well in full CSS so I'm going to go into styling here and I'll specify here the perspective text first of all it should have a width of 100% and a height of 100% and another thing I know is inside of it I have a paragraph and I have a copy of it which is the second paragraph and I know that the second paragraph I want it to be in position absolute so that it stacked on top of the other one so I'm going to put it in position absolute and see what we have and now we have something like this so now I want the menu to be centered here so I'm just going to take the display Flex Allen items and justify content Center and I'm going to paste it inside of the perspective text so everything is centered and that looks like this and you can see that the text now kind of looks weird and that's because there's like two of them stacked on top of each others and that's why it kind of looks more thick and then just so that it's a bit more clean I'm going to delete this inside of the element because the perspective text is taking the full width than the full height anyways so I don't need to Center things inside of the element so I'm going to save this and we should have the same result just so that it's a bit more clean and now the logic of this animation by the way I've done one in the past exclusively on this topic of like the prospective text so you can check it out it's a bit of an old video but if you're interested you can check it out so what we need to do is create a transform and I'm going to do a rotate on the x- axis and I'm going to do minus 90° and now we don't see anything but we can see that the text is not as thick and that's because the second paragraph is now like instead of being flat like this towards you where you can read it it's now like like this so you don't actually see it and actually I'm going to just do like 45° so you can see and you're going to see that it's kind of like rotating on the xaxis right so I'm going to do like 75 like maybe 85 and you're going to see you see like a small line that's basically what we want so I'm going to do 90° and then I want to do a hover CSS animation when I hover on the button I want to trigger the animation so here inside of the element I'm going to add a hover and then what I'm going to going to change is the perspective text and then what I'll do is basically I'll Transform the parent and I'll move it back to a rotation that's like in Reverse of what I did for the second paragraph and now to see what's going on I'm just going to add a transition so here I have the transition that I created before and I Target the transform value and so it's going to work for that rotation here so I'm going to save that I'm going to hover and you can see that the menu is kind of rotating like this and so that looks a bit weird because I have a second paragraph here that's supposed to be seen because it's in rotation minus 90° and then I'm rotating by 90° the parent and so we should be seeing the second paragraph but here I'm not seeing it and the reason is I need to specify here a transform style to the parent and I'm going to do preserve 3D and that way I can create like a proper perspective animation I'm going to save that and you'll see the difference and now when I hover I can see that I have my second paragraph appearing while the first one is disappearing now it looks a bit weird now but we can fix that pretty easily by basically trans translating the first paragraph as it's disappearing so what I'm going to do here is I'm going to un hover again I'm going to Target the paragraph and I'm going to Target here the first one and here I'm going to do a transform but I'll do a Translate Y minus 100% And then I'll also add a transition to the paragraphs here same thing and now that's kind of making sense you can see that the first paragraph is like flipping over the second one and the second one is also appearing from the bottom right that looks pretty good now obviously it's a bit busy cuz they are overlapping on top of each other so I'm going to animate the opacity here the second paragraph initially is going to have an opacity of zero and then when I hover I want to set the opacity of the first paragraph to zero and the opacity of the second paragraph to one so I'm going to do it like this and here the transition I'm going to apply it to all so not only the transform but also on the opacity and here you can see it looks pretty good I have the first paragraph that's being like yanked on top and the second one that's appearing but if I look closely the second paragraph is like centered in the middle and it's just flipping over over like this and I want it to be like at the bottom and come on top like this so there's another thing that we can change here the transform origin of the second one so I'm going to do transform origin and I'll do a bottom center and that way I want it to appear from the bottom instead of being centered like this and now it looks like this which makes more sense but it's also like translating now for some reason so I'm going to fix that by adding here a translation of 9 pixels I'm going to do n not minus 9 but 9 and now it looks like this a pretty sweet perspective animation and now I'm going to move on to the animation of the windows menu I'm going to use frame motion to expand the window and close it so I'm going to be honest with you this is going to be much simpler than the button okay I'm going to have here a div which is basically going to be the menu and then I'm going to go into styling here inside of the header I'm going to have the menu and I'm going to give it a certain height and a certain width so those are the values that I found for the menu to be nice and then I'll give also a background color and I'm just going to take the same color that I had in the button here which was like like this yellow here I'm going to save it and we should have something like this I'm also going to add a border radius of 25 pixels and we have something like this and now my button here is kind of getting yeated so here instead of being relative the button will be in position absolute and then I'll specify a top zero and a left zero and now it's here I'm going to do top zero right zero instead and now it's back where it's supposed to be and I'm just going to click here and we can see that it's like flush which is exactly what we want right it's like perfectly inside of the box so same thing for the button I'm going to use frame motion so import framer from frame motion but now instead I'm going to create a variance and that variance will have two State one is open and one is closed now when it's open I basically want to have a width and height that I specified here so I'm going to do like this and then when it's closed I basically want that window to be the same Dimension as the button so that it's kind of like closing inside of the button so if I remember correctly it's 100 of width and the height is 40 and then I'm just going to grab grab the motion added to the div here and then I'll specify variance that I want to use is the variance that I just described and then I can specify when should it be animated and I'm going to do is the menu active if it is then I want you to take the open description of the variance and if it's not active I want you to take the closed description of the variant and I can also specify that initially I want you to be closed so I'm just going to specify that I want you to take definition of the closed State here so I'm going to save that and and so we don't see the window anymore I'm going to click and then boom it's opening and it's closing like this and I can try to break it and it's not breaking so that's really good now there's another thing that I don't like when it's open I would like to have kind of a margin here uh because I don't want the button to be like precisely closed like that I would like to have like a little Gap a little margin so I'm going to add extra values here when it's open I want the top to be minus 25 and then the left I want a minus 25 as well and then when it's closed I want to reset to zero and yeah for that to work I'm just going to specify that it should be in pixels and also here instead of doing left -25 and say it should be right minus 25 because the menu is on the right side and then lastly since I'm doing top and right property I need to put the menu here in position relative so that is actually going to work now I'm going to try this out if I click on the menu boom it's opening there's like a small margin of 25 pixels which is exactly what I want and if I close it goes like this really nice and lastly I want to add a transition to this animation so that it looks polished so I'm going to basically take the same transition as the button here this right here and I'm going to specify here in transition like this same thing for the closed and I'll save this let's see what we have and now we have the menu now it's going a bit fast for my taste so I'm just going to slow it down to 75 seconds and we should have something like this a very nice animated Windows menu and now I'll be working on the nav which is all the text which are being animated with a prospective animation as well so the first thing I'm doing here is creating a nav component and I'm just initializing a very simple react component and then inside of the header I import the nav and if we take a look at this we have the nav and here I'm going to open and close it and now it kind of looks weird but we're going to fix all that so if I look at the demo here I can see that I have a bunch of titles inside of the knv and now instead of just hardcoding all of those knaves I'm going to create an array I'm just going to map that array to return all of those Tex so what I'm going to do here is inside of the nav I'm just going to create a data.js file and here I'm just going to export A const Links which is going to be an array and inside of that array it's going to have a bunch of different objects with a title and for example the first one here is going to be projects and then it's going to have an HF and I'm going to do like back slash for now cuz this app doesn't have multiple pages but eventually you would like to have like maybe your projects page like this so I'm just going to do the same thing for all of them so I have my array of links here and I'm just going to import it inside of the nav and here I can add some styling to the nav I can do nav here and inside of it there's going to be two things one is the body and one is the footer now we're working on the body for now and inside of the body that's basically where I want to mop the links so I'm just going to have links and I'm going to do mop and here I have access to the link object and the index and I'm just going to return here a div that I eventually will be animating and now that div needs a key and I can just basically do like the index and inside of that div I'm going to have an anchor and inside of that anchor I have the title of the link and the hre of the anchor and now it's giving me an error for the Styles so I'm just going to do import Styles here from the sty sheet and it kind of looks like this when the menu is closed and when I open it it looks like this so now I'm going to make all of this look good using CSS so here I have the nav and also have the body and let's start with the nav here it's going to have a height of 100% And I'm going to add some padding to a lot at the top and then a bit on the right a bit more on the bottom and then the same thing on the left and now since I'm doing height 100% And I'm adding some padding it's going to destroy the layout and for it to like stay tight inside of the parent I need to specify a box sizing and I'm going to do border box and with that the padding won't like overflow outside of the height 100% that's like a small small trick and we should have something like this so that looks pretty good for the nav I'm going to go on the body now and for each anchor inside of the body I'm going to do color black text decoration non and I'm going to do font size 46 pixels and we should have something like this now I'd like to have a bit more gap between the words so I'm going to put the body in display Flex with a gap of like 10 pixel and the direction should be in color and now that looks pretty good I'm quite satisfied with the look of this so now I'm ready to animate everything now obviously if I open and close kind of looks like a complete mess but it's fine I'm going to go in the nav here and same thing I'm going to import the motion from fir motion and here to help with the structure I'm just going to add some parentheses and by adding some parentheses I can actually put this on a line and that looks a bit better for my eyes and then I'm just going to add some motion and here I'm going to specify a variance and I'm going to call it like perspective so now this perspective animation I'll be creating it in an external folder again and then I'll create this variance here so I'm going to have the perspective and that animation is going to be quite complex it's going to have three states one being the initial the enter and the exit and I'm going to start simple with the opacity so initially it's going to have an opacity of zero and that way it doesn't like look weird like this I'm going to have it being invisible at first and when it enters I'm going to put the opacity to one and on exit I'm going to do opacity zero and now I can go back here in my motion div and I can specify that the animate here should be the enter animation and the exit should be the exit animation and the initial should be the initial description that's all here so I'm going to save that and let's see if this actually works I'm going to refresh my page and then you can see that the animation is getting triggered as soon as the component mounts because that's actually an enter animation triggers as soon as the component mounts and so what I'm going to do which is a bit different than like the body of the header which was an animation based on like a state here so here in my nav instead of always have it be present in the browser I'm going to have it be conditional to the is active state so I'm going to only return the knob if the state is active I'm going to save and here we can see that I don't see the nav and I'm going to open it and boom I see it appearing so the first thing that's throwing me off is the opacity is getting triggered like too early I would like the menu to be open a bit before triggering the animation of those titles so I'm going to add a delay so here in the enter I'm going to have a transition and I'm going to just specify a delay of like 0.5 and that makes a bit more sense to me but now I would like for the titles to be animated one by one and not at the same time and so kind of like a staggering animation so to do that I'm just going to pass here a custom value to the animation and I'm going to do custom here it's going to be equal to the index and so the first one will be 0 1 2 3 4 and here in the enter I now have access to that index here and I can do plus the index and I can do multiply by like 0.1 I'm going to try this out here boom and now they are all appearing one after the other which is good and the next problem now is when I close it it just disappears right away it basically does not trigger the exit animation and that's because here the is active when it is false when it gets turned off the nav just disappears from the browser and so I basically want to tell it hey before unmounting trigger your exit animation I can do that with the animate presence from fir motion and I'll try this out and on close boom you can see that I have my exit animation working but now I kind of see it moving as the window close which is not something I like I'm going to basically add a delay on the window here so basically the the closed animation of the menu I'm going to go here inside of the transition and I'm just going to add a delay of maybe 0 .35 and that makes a lot of sense it's kind of giving time to the titles to disappear before closing so with that we basically have the base and now we only need to make the animation of the titles a bit more fancy cuz right now it looks really dry really normal it looks still good but we can make this much better so I'm going back inside of the nav here and I'm going to be tweaking the perspective animation here instead of just changing the opacity I'm going to be changing a bunch of other properties the first thing I want to do is very similar to the button animation I'm going to change the rotate X so I'm going to do that initially I want to have a rotate X of 90 and then on enter I want you to reset the rotate X to Zero so let's see how that looks and we have something like this it's kind of like a panel that's getting like open like this but honestly this animation is quite boring it's not really what I want and to make it really nice I need to add perspective to this since it's a rotation on the x value if I add a perspective it's going to be affecting it and it's going to look much better so what I'm going to do here it's going to get a bit more complicated I'm going to add another div which is going to be a parent here and on the parent I can actually add some perspective I'm going to call it here the link container and then I'll move the key to the parent and we should have something like this we now have a link container that's the parent of all of our titles now I'm going to take that link container and I'm going to start adding some styling to it basically what I want to try to do is add a perspective so I'm just going to add a perspective of 12 pixel see what we have with that and now it looks like this you can see that it's quite different than when I didn't have have a perspective and to me this looks a bit better but now obviously the transition is like really weird so I'm just going to change that so here in the transition I'm just going to start adding some properties and I'm going to do like 0.65 and one thing that's really nice too is I can specify a duration for like the opacity and for the opacity I'm going to have a duration of 0.35 and that way the opacity animation is faster than the rotation and finally I'm just adding a kneeing here and I'm going to try this and honestly this looks quite cool one thing that we can tweak is the perspective here we can play around with it and do like perspective origin and we could do like perspective origin top for example and here you can see that it's quite changing the animation and if I do bottom you can see that it's also changing and to me this looks quite good it's almost what we want and let's say if I do like left you can see that again it's different it's kind of a cool effect too honestly all of them looks really nice it depends on your taste you can tweak around with the perspective origin it's quite a nice property but for now I'm just going to leave it at bottom so this is really nice I like it I'm going to add some spice to this I'm quite satisfied with the rotation but I want to like kind of have a sliding effect as the title appears and I want it to come from the left side and then up so what I'm going to do is have an initial Translate Y of maybe 80 pixel and I'm also going to have a translate X of minus 20 and I'm going to reset them back to zero and let's see how it looks freaking nice right this looks amazing I'm really satisfied with that and all of that is because we're using the perspective all right if I take off the perspective you're going to see that the result is much different so this is how it looks without perspective kind of dry right and then you could change like the perspective and put like perspective origin right and you could play around with that and honestly that's really fun you can see like a bunch of different effects like this is quite funky but for now I'm going to leave it at bottom and lastly here all I'm going to do is add a bit of transition for the exit animation duration of 0.5 and the same easing as the button I'm going to save that and this is just a small tweak to have like a nice easing on the opacity animation here and that's basically it for the nav animation and lastly I'm going to work on the footer component so here inside of the nav I had a body with the titles now I'm just going to create another div here which I'm going to call the footer and I'm going to have the same logic I'm going to go in the data here and I'll just export a const footer links this time it's going to have a bunch of objects very similar to The Links so it should look something like this I'm going to take that full links import it with the main links and I'm going to do the same thing as the links here I'm going to map the footer links have the link index I'm going to return div and here the div needs a key I'm going to have a string I'm going to do F and the index so that it's different from the key here and very simply I'm just going to have an anchor and then same thing link the title and here I'm going to animate the anchor and here I'm going to take the same thing but I'm going to have a different variance I'm going to call it like slide in and I'm also going to have a custom value so there's like a delay between each elements and here I'm going to create the sliding animation cons slide in so I'm just going to copy paste this but I'm going to modify it actually I just want the opacity and here on enter I also just want the opacity now for the transition here I'm just going to do 0.5 this won't matter and for the delay I'm just going to increase it a bit and then I'm just going to add another property which is going to be a y of 20 so it's going to be lower at the beginning and it's going to slide up as it appears so here I'm just going to reset the Y and that kind of makes sense I'm going to save that see what we have now obviously the footer is not styled so it might look a bit weird we're going to see what we have okay we can see that we have the footer here and it's appearing working fine but obviously The Styling is off so going to go inside of the knv here and now we have the body and I'll have the footer and the footer is going to be very simple display flex and I'm just going to have a flex wrap and all anchor will have a width of 50% copy paste this so it should look like this now it's a bit tight so what I'm going to do is inside of the knv I'm also going to put it in display Flex but Flex Direction column and I'm going to do a justify content space between and that way they're going to be both at the opposite of each other and that makes quite sense and I actually just realized I don't need to have a parent on top of the motion here I'm just going to delete that and move this and I'm just going to add the key directly to the anchor and we should have something like this that makes quite a lot of sense and we can see with the animation and to me that looks really good so yeah that was the menu so yeah that was so yeah that was the recreation of so yeah that was Recreation of this Awards winning menu I hope you learned something I learned a lot while doing it it was a ton of fun the perspective text is quite fun to work with and to experiment so hope you learned something if you did leave a like subscribe and I'll see you in the next one bye
Info
Channel: Olivier Larose
Views: 6,230
Rating: undefined out of 5
Keywords:
Id: MsdR8iAscNs
Channel Id: undefined
Length: 26min 41sec (1601 seconds)
Published: Mon Nov 06 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.