Springy Animated Modals // Framer Motion & React Tutorial for Beginners

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
animation is one of the most satisfying things for a developer because it can turn a boring cookie cutter feature into something really special in today's video we'll build a modal window and react from scratch but on top of that we'll also bring in a library called framer motion to implement a bunch of crazy animations for the modal in this beginner-friendly tutorial you'll learn how to style a modal with css then how to manage its open and closed state with javascript and most importantly how to implement declarative animations with framer motion and react and i'll even show you how to drag and move a modal around the screen and explain the physics behind motion like this and we'll look at a bunch of other cool tricks and best practices along the way if you're new here like and subscribe and if you like this tutorial upgrade to a pro membership on fireship io to get access to the sequel where we build a notification system with framer before we jump into the code let's take a closer look at what we're building today and by the way there's also a live demo where you can play around with this project before you build it we have a button that when clicked will add a backdrop to the entire screen and then animate a window on top of it then to close it we can either click the close button or click outside of it on the backdrop which will automatically trigger the outro animation modals are a very useful ui feature when you need to focus the user's attention and or you don't want to navigate them to an entirely different route you can also do complex things inside of them for example the entire login feature for fireship io is handled inside of a modal what you don't want to do is pop one of these things up after a few seconds asking someone to subscribe to your newsletter or even worse asking them to accept cookies let's go ahead and jump into the code to get started we'll first need to generate a react project and for that i'm using create react app once created i'll go ahead and open it up in vs code and install our only dependency which is framer motion framer by the way is maintained by the team behind the framer design tool and is a very well maintained and polished library for implementing animations it's not the only way to animate and react but in my opinion it's the most intuitive approach for a feature like this now to run the app run npm start from the command line and that should bring up the default react app on localhost 3000. next we'll go into the app.js file and delete all the boilerplate code from there i'll go into the index.css file and delete that code as well and import normalize css this is a cool little trick with create react app that will just give us a blank slate to work with when it comes to css then from there i'm going to paste in all the css for this project which you can get on github by the way we'll come back here to explain the important styles as we move along at this point you should see an empty black background and now we're ready to implement our first animation which is a button that gets bigger when we hover over it and gets smaller when we press it first we can import the motion component from framer motion then in the jsx add a regular button that has a class name of save button and currently when clicked doesn't do anything now to animate it we can simply swap out the regular button for a motion button motion actually wraps all of the html elements for you and provides additional props to configure an animation like while hover will make the button bigger when you hover over it and then while tap will make it smaller to give it the impression of being pushed in and just like that we've already created our first animation but you might be wondering why would i want to use framer motion over just regular css animations well for one it's just easier and results in more simplified code but on top of that framework can do a lot of things that css can't like listen to different browser events and integrate with the actual state of your react application it's just more developer friendly to work with and that'll become apparent as we build out our next feature the modal to build it we have two moving parts here which we will organize in the components directory first we have the backdrop which is just an overlay that sits across the entire screen and makes everything else look dark then the modal window sits on top of it and that's where the user's attention will be focused when working on a larger react project it's generally a good practice to write one component per file in this demo i have a directory for each main component with an index.jsx file inside of it a little trick in vs code is to hit the button for a new file and then write out the entire file path with a slash and it will automatically create the directory for you let's start by building the backdrop we'll first import the motion component then define our own custom component called backdrop and export it as the default from this file the component itself will take two props the first one is children which allows us to embed additional components in between the tags for the backdrop and the second one is on click which allows us to pass a custom event handler into the component to update the global state when the backdrop is clicked that allows us to think of this as a dump component that doesn't have its own internal state to manage in the jsx we set up a motion div and define the on click handler as the function that gets passed in as a prop and then the children will go in between the motion div tags it has a class name of backdrop and let's go ahead and take a look at the css before we start animating remember it's an overlay so we give it a position of absolute and set it in the top left corner with a height and width of 100 then we'll give it a black background but we still want to see the elements that are underneath it and an easy way to do that is to simply use a hex color but then add an additional two characters for the opacity and finally we want to center the children both horizontally and vertically which we can do with display flex now with our style set we can go back to our component and define the various animation states to make the backdrop fade in and fade out the initial state should be invisible which we can set with an opacity of zero then when it's active we want to animate it to an opacity of one and then when the animation is finished we want to go back to an opacity of zero which we can set with the exit property and that's all there is to it but it's not very useful without some content inside of it let's now go ahead and implement the modal component at the top we'll import motion again as well as the backdrop component that we just built then we'll define and export a component called modal that has two props one is a function to close the modal and the other is the text that we want to display inside of the window in the jsx we declare the backdrop component because that will always sit behind the window itself and when the backdrop is clicked it will automatically close the window now because we're using the children prop in the backdrop we can add elements inside of it like the motion div here which will represent the window now the first thing i want to do here is set up the click handler and call event stop propagation normally when you click on something it bubbles up the dom to find the first event handler to take care of it that default browser behavior would cause the modal to automatically close anytime the content inside of it was clicked which is not something we would want in this case the next thing we'll do is add a modal class to it and let's quickly take a look at the css to make the width and height responsive i'm using the clamp and min functions from css clamp in this case will attempt to set the width to 700 pixels but if the screen is too small then it will go up to 90 if needed or if the screen is too big it will go to a maximum of 50 percent of the screen width this is a really cool trick to know in css because otherwise to make the modal responsive we'd have to set up media queries and things like that which would take a lot more code okay now back to our component we have a property called variance that references an object called drop in this object allows you to define multiple custom animation states that's really cool because you can use it to create a complex sequence of animations based on different ways the user might interact with your app in this animation we have three states hidden visible and exit when the window is hidden we'll translate it along the y-axis by negative 100 of the view height when it exits it will drop beneath the viewport to positive 100 of the view height when it is visible though we'll put it on its natural position of zero on the y axis the end result is an animation that drops in from the top and lands in the middle then when it leaves it drops even further to the bottom now one additional cool thing we can do here is tweak the transition settings when it becomes visible i'm going to set the duration to point one second and give it a spring type animation to make it look kind of bouncy and that provides a very easy way to make your animations look special i don't want to get into the physics of it but damping is a decrease in the amplitude of an oscillation as a result of energy being drained from the system to overcome frictional or other resistive forces if you turn it down really low the spring will never stop bouncing but if you turn it up too high then the spring won't have much of a balance at all with stiffness if you turn it down really low then it'll make the spring react very slowly and vice versa if you turn it up very high if you want to dive deeper into spring animations i'll link to a brilliant blog post that actually visualizes the relationship between damping and stiffness in a framer motion component the final thing we'll want to do in this component is go back down to the motion div and add props for the different states like initial animate and exit and now the final question becomes how do we actually trigger this animation in the react app for that we'll head back into our root app component and inside of it import the use state hook from react as well as the modal we just built in order to open and close it we need some state on this component that will tell us whether or not it's currently opened or closed and we can easily set that up with the use state hook it'll have a default value of false and then just to make our code a little more readable here i'm going to set up functions for close and open that will toggle the value between true and false now with our state setup we can go down to the launch model button that we created at the beginning and define its on click event handler to run the close function if the modal is open otherwise run the open function that allows us to toggle the state from the button but we also need to toggle the state from the modal itself like when the user clicks on the backdrop or from the close button within the window itself so if modal open is true then we'll render the modal component and it will take the props of modal open as well as handle close to make it aware of the data or state in the parent app component if we check it out in the browser we should now have a working modal window but there's one problem here notice how that it animates in perfectly but when we click the close button it just disappears instead of animating out the reason this happens is because the modal is completely removed from the dom when the state changes luckily though framer motion has a mechanism to rescue us from this predicament we can import the animate presence component and put our modal inside of it to keep it visible temporarily even after it's been removed from the dom there are two important props here first one is initial which will be set to false to disable any initial animations and the second one is exit before enter setting it to true will ensure that all nodes have finished animating before they're actually removed and we can also do more advanced things here like listen to life cycle events if we go ahead and try it again we now get the full sequence of animations from enter to exit congratulations you just built an animated modal window with react and framer motion oh and i almost forgot i told you i would make the modal window draggable to accomplish that all we have to do is add the drag prop to the motion dim and now you're free to drag it around the screen i'm going to go ahead and wrap things up there but if you want to learn some more advanced concepts like how to build a notification feed and work with drag and drop gestures in framer consider upgrading to fireship pro to get access to the sequel thanks for watching and i will see you in the next one
Info
Channel: Fireship
Views: 115,637
Rating: undefined out of 5
Keywords: webdev, app development, lesson, tutorial
Id: SuqU904ZHA4
Channel Id: undefined
Length: 11min 2sec (662 seconds)
Published: Tue Sep 14 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.