Framer Motion Scroll-Based Animation with useScroll Hook

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this is a quick video on how to use the use scroll hook in frame motion to add scroll based animations to your project so what we want is this scroll animation which looks really slick and so what happens is as we approach this section and we scroll down they sort of grow into the view here right so both their opacity as well as their scale is animated based on scrolling and we can also very easily do this with framework motion so what we can do I'm going to make this a little bit wider we need to go to the project individual project components not the whole section and here we're going to use framer motion so frame emotion has a hook called use scroll that we can use and let's actually import that let's see if we get the suggestion here control spacebar no so I will import it manually here and actually copilot also doesn't know where it should come from well we'll say import scroll from framer motion okay okay now we need to give this hook two inputs actually just one options object but with two properties so it needs to know the target element and it needs to have the uh the actual HTML reference so we're gonna have we're gonna have to use use ref as well I'll just leave this as a string for now and then also an offset property so this offsets is going to be an array what that means is when when we actually want to start animating right so we're gonna have a Target so the the individual project is going to be a so-called Target and then we also have a container and that's actually the viewport right so the viewport is whatever you see here of the of the page and so what you have to specify here is at what point do you want to basically start the animation so here we want to start as soon as the end of the container end of the viewport reaches the top of the Target right so that's what we can specify here so here we can say uh in a string zero and then one so that means when the bottom of the viewport crosses the top of the target which is the project that's when that's when the animation should start and when should it end well it should end when the the bottom of the viewport has has has gone 33 beyond the end of the project that's what we can specify like this takes a bit to wrap your mind around this you don't really have to understand this you can always look up the documentation but that's how this offset property works okay so then we need to provide a ref here to the actual project here this section element that actually should be animated so here we're going to use the use ref hook right so here actually a polar copilot already suggests this for me we're gonna say is use ref and typically we'll start off with a value of null and let's actually import this I'm going to place my cursor here and actually we get used ref Snippets but that's something else it's from an extension so I will import it manually here use ref okay so now we um we get some issues here if we look here so this should be a client component and now it gets interesting because if we look at the overall projects section this is not really doing anything interactive this is basically just presentational markup here it's only the individual project here that now we start to use these Hooks and we really need to at least have this as a client component now what what will happen is if I make this use clients here both of these components will now be client components so even though actually technically only this project one has to be a client component and then ideally we can we can keep everything or as much as possible running on a server only right so a server component so here what we can do is instead of using use client here at the top in which case if we do that this will also become a client component which is not necessary because this is not really doing anything interactive it's just mapping over data and then using the project components which actually does need to be a client component because here we need interactivity we need a client-side functionalities here so I proposed that we actually put this in its own file so we're going to create a new file here simply called project singular and then we can just copy this right so let's just copy the entire component into that new file so and actually also the type above it right so make sure you also copy the type or the props and I'm going to paste that right here and we get a bunch of Errors because uh we need to import the proper things here so let's see if I put the the cursor here Ctrl spacebar command spacebar you should be able to import everything automatically actually because now it's already imported here so uh it should be able to deduce from that actually use wrap fair is not importing for me so I'm gonna type it myself actually we got some suggestions but I want to use ref okay you scroll I'm going to put my cursor here also we have to actually we can also just copy it here um actually we need everything except the the top three all right so we can remove this okay so now we have all the necessary Imports now remember this needs to become a client component right so the only thing we have to do is say use clients and now this is a client component um but we need to export this I'm going to make this the default export here so we're going to say export default okay so we're we're making just a default export then we can import it here and we can also remove we can also remove these Imports because we're not using that here anymore also they use ref and then we need to import the actual project and that should be easy right we can just import it automatically like that and it's a it's a default export so we don't need to use the code braces all right so now if we save here and see if that works or at least if we can get rid of the error Okay so the loading and looks like it's working right so it's still working here and so now it's a small optimization of course but if we look on the page everything in the app directory is a server component by default so here we're importing projects projects itself does not have used client so this will now also be a server component but this is importing a client component and we're using that here right and the client component will have the actual you know functionalities and client-side features right so the way to think about it is basically anything that is presentational is going to be a server component as this is more presentational just mapping over some data we have some division section and a heading just quite static now then we have this component which is more interactive right so the interactive components are going to be client components usually right and you want to put you want to use as many server you want to keep components server components if you can sometimes that means refactoring the client components to a new file and so if you look at if you imagine a react three so three of components you want to keep the client components more towards the the edges of the tree right so really at the leaves of the tree now sometimes that requires some refactoring all right so let's continue here in the project component now so it needs to know the targets right so that's why we created this ref now about the type of this graph and let's actually just add the ref so you can just go here and you can say ref is ref okay now if we hover this you can see it's trying to infer a particular type of this reference but it's not it's not really showing us that it's actually going to be this section right so here we can we can supply the type ourselves so we can use these angled brackets and we can specify this is going to be an HTML section element okay and actually that doesn't seem to be familiar to typescript so cannot find name HTML section elements okay so it looks like there is no special HTML section element type we should use the more General HTML element type so some of these HTML elements they have their own types like HTML div exist but not HTML section so they only create new types if the type needs some special behavior or special property so the section element didn't need special type typing properties so there's no special type for that but for some elements like this there actually are because they need some special stuff for some reason okay so I just Googled that actually I don't know that by the top of my head sometimes you need to Google it okay so now we can see that this ref is going to be ref objects and it knows more specific now that's going to be it's going to be an HTML element okay so this that's going to be the Target right so we have the targets here we can just provide the ref not the ref current we actually need to provide the whole ref all right so that's what we need to provide to this use a scroll hook now what do we get back from that hook what we get back is the pro scroll y progress so scroll why programs is what we get back so basically an indicator of How Far We've scrolled and that's what we can now use to animate this so we do have to make this a motion component so I'm going to make this a motion dot section component let's make sure that the closing tag is also correct yeah we need to import that let's see if it finally Works nope so we have to import this manually motion okay and then the trick is almost finished here we can use the style prop so just like CSS styling and we can just do scale for example as well as opacity let's see if no opacity should also be confirm the progress of the scrolling that's a bit of setup here but now the scale and the opacity CSS values will depend on how far we've scrolling at least that's the theory let's double check if it actually works you can already see that it seems to work right now you can see it's not so smooth but at least we're on the right track here now it's not very smooth and I actually didn't know why it's not smooth sometimes it happens with frame or motion that things don't work as smoothly as as you think they should so what I tried here is to just wrap everything in a div here and just animate that div so let's actually do that so we'll keep the section it's just going to be normal section element and we're just going to wrap everything in a div we're going to put everything in a div and that's the div that we're actually going to animate and that usually solves the issue if it's not smooth in frame or motion for me so here we need to copy the ref and the style to that div now and now is uh let's see yeah so now it's not just a general HTML element now we can change the type to HTML diff element right so make sure you change that now because we change this we also need to change this margin on the bottom right so now uh let's quickly change that as well so class name so here we added some margin on the bottom yeah so margin bottom three SM mb8 and thus last pseudo class that should now go to this div and then actually uh they have some space between them and then let's see what's going on here why is this not working ah yeah so here it doesn't work because this is still a normal jsx div element but we want to make it a motion component so we'll say motion dot div make sure that the last closing attack is also motion and now if we save here let's double check so now you can see it's very smooth right really buttery smooth for me I hope it comes across the video as well because I'm recording video here so I'm not sure if it's as smooth on the video but from my perspective here it looks very smooth now the only thing I don't like is it's a bit too much so so what I mean by that is the scaling basically starts from a very low number like zero and maybe it's a bit too much so maybe it should start already a little bit bigger so it's a bit more subtle and the same with opacity it starts off almost invisible and immediately goes to like completely one opacity so that's a very large range that it's animating basically and it's it's not really it's not as subtle as I like the animations to be so we can this scroll why progress that we get is actually a special motion value and we can change it a little bit so that the scale and opacity here that are using that are animated a little bit more subtly and actually what we also want sometimes is that the scale is is animated slightly different from the opacity right so that's we can do that immediately here as well like this so what we're going to do is there's another hook that frame motion gives us is use transform so we can transform that skill why progress that we get from you scroll and actually I already got a suggestion here so you put in the scroll why programs right so that's what we need to provide and then there's two other values so this skill the scroll y programs will go from zero to one unless that's what we're putting here and then what we actually want the transformation to be is that for the scaling here that it doesn't start at absolute zero right so it it doesn't start from an actual scale of zero but maybe let's say 0.5 and goes to one right so what this will give us let's we'll use that for the scale so we can just scale progress and we need to import this no suggestions use transform from framework motion make sure you import that and then we can use this value the the transformed value for scale so if we do that let's see if that works so now you can see that it doesn't start off so small it starts off a little bit bigger and it's a little bit smoother I think more subtle nothing it doesn't it doesn't travel such a large range during the animation now it's the same story with the opacity I don't want it to start at such a low value so we're also going to transform the opacity so let's duplicate this line I'm going to put my cursor on this line and then hold shift alt down arrow key to duplicate it and we can say opacity progress right now maybe we can even change it here we'll make this 0.6 so this should start not at zero but at let's say 0.6 and actually let's change the scale because it's still a little bit much let's actually change this to 0.8 oh well now actually we should still change this value so opacity should get opacity programs right so I change the value for scale as well to 0.8 so now it's going to start off you know significantly bigger but I think it's going to be more subtle yeah this looks better right so now it's ways to learn right so you can play around with use transform to transform that scroll y progress value that we get which is just basically a raw indicator of how much we're scroll down you sometimes want to transform that right it's a bit more advanced but uh I think we have a nice result right so really uh slick I think yeah I really like this effect I'm going to use it much more in my design now that I've learned this so uh I hope you like it as well by the way if this was helpful I'd really appreciate it if you could like And subscribe also check out my courses on CSS and JavaScript if you want to take those skills to an advanced level because in there we will build some beautiful real world projects from scratch so you can see how everything fits together and really Master CSS or JavaScript and I will also release other courses from like react and node.js so if you want to be notified then make sure you are subscribed to the email newsletter you can find the link in the description thanks for watching and I hope to see you soon
Info
Channel: ByteGrad
Views: 26,049
Rating: undefined out of 5
Keywords:
Id: m1Cm1ivOjzU
Channel Id: undefined
Length: 15min 42sec (942 seconds)
Published: Sat Jul 15 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.