Creating Smooth Scroll & Raycasting with ThreeJS

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what is up everybody today we are going to do this with 3js so as we can see we have this uh just very simple photographs here nothing all that exciting we also have this cool sort of animation that's occurring on hover um it's not as straightforward as it looks because this is all entirely achieved within 3js we have this smooth scroll we have this hover here and the way you do things like this in 3js is not like you would normally with just html css and regular javascript um so this is going to sort of set us up in the future in uh in order to do really cool stuff especially with shaders um but that's a different subject so there's a lot to to digest here um so definitely if you enjoy this make sure to subscribe and let's get started wait one second though you're about to watch me work with 3js which is a part of front-end web development now if you're not a great friend and developer you should definitely check out the front-end developer career path at scrimba.com they've recently launched their front-end development career path which is a collection of courses that cover html css javascript react and much much more as you see it's over 75 hours of awesome content there are hundreds of interactive coding challenges and it's all geared towards helping you go from beginner to someone that's hireable as a front-end developer so check out the first link in the description below to get fifty percent off all right so the very first thing i'm gonna be in a visual studio code here i'm gonna get the terminal out and control uh no not escape control tilde there we go and i'm gonna go into my code folder and we want to go to the github starter um so let me go to github.com real quickly find there it is all right so we want that that's going to be linked in the youtube description so just go there we're going to copy this url right here close that out we're going to type git clone right click and we'll call this um i i don't know i three hover there we go so we're gonna cd into three hover and we will npm i to install everything from the dependencies and then we will run uh let's see here npm run dev and this will open up a browser with this default starter right here which is just that taurus and then we will open the folder and we will go to three hover and select it alright and there we go so by the way this whole setup right here all of this that's what's necessary to create you know just this very basic scene and i if you're new to this i highly suggest checking out the description here of this video to access the playlist that's associated with this video watch the first video because i explain everything that's happening here i'm not going to waste my time doing that because i already did it so watch the first video there's a second video after this as well i would recommend watching that too and then you can get to this video where we bump things up a notch in terms of what we're doing um all right so the first thing i want to tackle uh is getting the actual photographs on to the canvas first so what i'll i'll do is um i'm going to open and i'm going to click this up in reveal explorer so right click and we're going to go into source here now i already have no we're not going to go to source we're going to go to static i already have a series of uh photographs that i want to use um so they're all right here and they're in a photographs folder so i'm just going to go ahead and copy that paste this here and these are just photographs of buildings that's all they are right here and these are from unsplash.com so go ahead and get your own images if you want no big deal um i'll see you try to remember to add this to uh github as its own project and then you can follow along with the same images if you want all right so we have those images here in photographs one two three four one two three and you'll see why that comes into play here in a second um and so what we need to do first is we need to get uh our let's just remember to get our texture loader so um texture loader we're going to get this up and running so we're going to create a constant of texture loader equals new 3 and texture loader all right so what that will allow us to do is to get these loaded up um basically uh in the next part of the code um and first let's also get rid of this eye object we don't need this object we don't even need this material you know what we we just we don't even need this all right so if we save now uh we're going to get an error because down here we're rotating a sphere that doesn't exist anymore so now if we save this let's oh it's not working let's go back to our terminal and npm run dev okay so this time it it should work it'll just be black there won't be any type of circle ctrl shift i make sure there's no errors either in your console all right so what i want to do is um we could with our texture loader just you know get all four of those images loaded up but we can do this uh in a little bit more of an efficient manner if let's just come up right here near the objects we put it in a loop of some sort so that's what i'm going to do so um what we'll do is we know we have four different pictures so what we'll say is for i uh no let i equals zero and then i is going to be less than i four here so that would give us zero one two three and then i plus plus and then inside of this what we wanna do let's come over here is create a geometry that we're going to use for each of the four images um so what we can create is conch geometry equals new three and then we're just going to do a plane buffer or a plain buffer geometry as it's called all right and so we're going to put just uh this is basically it accepts multiple parameters in fact it would be a good idea if we get this up and we go to plain buffer geometry and just you know check out the various uh based on the constructor the various properties so we have the width and the height and then the width segments and the height segments and so these we don't have to really worry about for this particular project although if we were trying to do cool things with shaders and vertex shaders like making a wave and stuff we would want to bump these up um because the default is one we want more but the width and height excuse me we do want to adjust so um by default they're just one by one uh so we're just gonna give us a square in fact yeah let's just do this for now um and then we're gonna put one in 1.3 for the height so that would give us kind of like a this type of aspect ratio more of a rectangle all right so now what we'll do we have to have a material now if you recall if you watched the other videos my other two videos um every object that you see in 3js is composed of basically two different things we have the object and then we have the material um the object is like the skeleton and the materials the skin so we already have the object here or the geometry which is the skeleton but now we need to put something on to it all right so this is how we're going to tackle this part so we're going to create a constant material equals new 3 mesh basic material all right so there's a bunch of different types of eye materials that you can use in 3gs they all do different things mesh basic material is just fine for what we need we're just trying to display an image so we're going to open this up and inside of here we're going to map and map is the property that you would use within this object i that allows you to put a texture like a picture onto the geometry so we're going to do map texture loader remember we created that up there higher uh we're going to load and inside of it we're going to use by the way these backticks because that'll allow us to also put in um a template literal i believe it's called uh basically a variable within a string and so we're going to put forward slash photographs so we don't put static it's just straight in photographs it knows already webpack already knows to look in here i've photographed forward slash this is where we put in our i all right so our the first one will be zero and then the next one will be one two and then three and then we also have to put the dot jpg because they're all jpeg files all right so at this point nothing's happening because once you have those two things the skeleton and the flesh so to speak you have to create a mesh and the mesh is just tying those things two things together and then once we create the mesh we add it to the scene so what we'll do is create uh we'll just call this const image and this is new3.mesh and it just takes two parameters which is the first geometry which is defined outside of this for loop and the reason we do it outside of this for loop is because the geometry is exactly the same for all four of them so geometry and then material right here i don't know why it added a second all right all right so um now at this point like i said we did the three things we got our geometry we got our material we have our mesh and now the last thing is to const you know oops it's the scene add the image right here all right so let's save this and to see what happens here all right so it looks kind of strange because we only see one but they're all just sitting right on top of each other so we need a way to offset this so that we can move them around uh or see them you know maybe stacked vertically or if you want to do a horizontal scroller you could do that as well um so what we can do is we can take this image oops image position and we set the x in y values here so um the first thing we'll do um let's put one here and then for the y value we're going to take our i we're going to multiply it by 1.8 so now you could see something's happening here but we can't we can't scroll we can't access the other ones which is frustrating right so what we can do real quickly is dat.d gui so we're not using this currently but we are going to in a second and this will allow us to easily debug situations and just create a a user interface thus gui um or a gui um that'll allow us just to to mess with the variables um and properties so what we can do um we want to move the camera just so we can see all four of those images um so to do that let's find um let's go down let's just put it here we have to move it uh we're gonna do it guy.add um actually let's come after wherever the camera is at where's the camera there we go we'll come down here so guy.add we're going to be putting camera dot position and then in the second parameter we put in string which is kind of strange we just put the x y or z so we'll put x here and if we save this you'll see that we have up here in this little control area the x position and of course if you move this up and down this is going to be crazy so we don't want the x really we just want the y and then also to give us an actual slider we have to put a min so we could put um let me find where i i put mine yeah it was just a negative 5 because you can go negative on the camera position so negative five and then also a max of just five i actually just do a max of ten and let's look at that so now we have this little container let me make this a little bit larger here and so now we can see all four so you'll notice if we refresh to get back to zero here um these are all going up they're going they're going the wrong way i want them to be down i like i want the first one and then the second one will come you know from there so what we can do is just take this and put minus right here so now they're all going to go down and we start here and then we just code would go down now what if we wanted some variation on the y position we can definitely do that as well so by default we have this at one if we put this back to zero you'll see um it's going straight in in the center i kind of want to have text over here um so what we're gonna do is let's do a math random all right so our math random if we just put math oops math.random this is going to go from a 0 to 1. and so naturally it's just kind of over here to the right already which is fine i'm going to put i want it to go a little bit over further so plus 0.3 and now they're a little bit over here to the further although there's not a huge difference so now every time we refresh this these will be in slightly different positions all right very cool all right um after that what we want to do is i figure out how we can make this scroll down with our mouse wheel all right um right now if we use the mouse roll we can't we can't traverse we can't go over these uh and see all these items so to do this um we're going to tie into the the wheel event which is vanilla javascript stuff nothing huge nothing you have to worry about um let's put that right here just call this mouse and we're going to window.add event listener and it's going to be on the wheel event so every time you use that wheel this is going to fire and then we'll call a um a function called on mouse wheel so we're going to create a couple properties y equals 0 let position equals 0 as well and then inside of here we're going to have our function on mouse wheel we're going to pass in the event and the event is going to give us a delta y property so if we console log delta y oh sorry event dot delta y we're going to get our console out here there we go so this is giving us a bunch of stuff here so what we want to do is we want to tie our y which is currently at default at zero which is defined above equals event dot delta y and we're going to you know what for now we're just going to leave it there we're going to make an adjustment in uh a little bit but now once we have this this y position what we'll do is we're going to come down here in our tick function now again i'm not going to go over and explain everything that's happening already did that in the first video so definitely watch that um but basically this is running rapidly uh very quickly because of this right here the request animation frame so when we do you know a lot of 3js animations and stuff or tying stuff into it the mouse we'll do it over here in this tick function um and so what we'll do is our camera and we want to adjust the camera position on the y-axis all right based on this mouse will so camera.position dot y equals let's just put in for now this is not it's going to be messed up it's not what we want um why and that's defined up above already let's see what happens here i'm not even sure what is going to happen exactly okay so it's going way too fast so once you even just touch this just barely at all it's just going away way too fast so what we want to do over here is multiply this by a a really tiny number so for us that's going to be something like times 0.0007 so now it is it's not really hardly even moving at all for some reason it's just getting stuck what we want to do is now um we're going to take our position remember we create a let position equal zero and we're going to put let's see here right above it a position eq is plus equals y so it's going to basically compound itself and keep adding to itself and then let's tie this here to the position all right so now we have something that's happening but it just keeps on going up and up and up and it won't stop so the way we get that to stop i and come to like a gradual um you know just stop essentially is we take our y and remember this is updating you know like 60 times 60 frames per second we multiply it by a number smaller than one and that's going to i sorry it's it's multiply equals so it's going to multiply itself by a factor of like let's do 0.9 um and what that will do as this is updating and this whole tick function keeps running it's going to decrease this value gradually and the position will be adding to itself a smaller number each time which will affect the camera position y so it will make it go slower so let's save that and look at that now we have that nice real smooth sort of scroll that's happening that you see a lot of these fancy 3js websites that's how you do it uh very very very very cool now you can affect the speed of things by playing with these numbers like if we try 0.5 what does that do it makes it a lot quicker so 0.9 i like it i think it's a good value you can also play with this up here as well like if you try putting in point like three right there what does that do it's really fast so you can make it a lot slower than what we had by you know lowering this number or whatever you want but i think these are good values that i like that are pretty pretty solid now there's also a way but i'm not going to do it to clamp the position y so that once it gets to like maybe this is like y five or whatever um and then maybe like minus or like zero or whatever it'll stop scrolling at a certain point but i'm not going to mess with that right now so what we'll do now is now that we have this how do we get this so that we can hover over one of these images and do something with it well that's ray casting all right so maybe you've heard of it uh in different 3d terminology or in gaming or whatever but it's called raycasting it's just basically a fancy name to detect if um something is interacting with uh an object in your scene all right that that's that's basically how you do it um this this object that's interacting with something could be the mouse it doesn't have to be the mouse it could be something else i in in the in the scene but this right here we want it to be the mouse kind of like you know an ad event listener of mouse enter in vanilla javascript we don't that that's not how you do it in a 3g yes we have to do a different way and unfortunately it's a little bit more involved but it once you get the the basic boilerplate code down and the the concept you understand it it's not a big deal so first we have to create a ray crack caster and 3js so let's go ahead and i'll just put put that right here so we're going to create a constrain caster equals new 3 dot ray caster like that um so what we want to do is we first have to get all of the uh objects in our scene which there's four of them actually technically there's six if you count the camera and the lights but we have four basically meshes and we want to get all of those um again you know if we created all these outside of a for loop and just did them you know individually one by one it would be a little bit easier but because we're we're doing things you know dynamically like within this for loop we're going to do something that's going to quickly allow us to get access to all of the objects in the scene so the way we do that is we're going to first create an array of obs obj so an empty array and then what we do is we take the scene and we traverse all right and we pass in by an object here and inside of here we're going to say if object is mesh all right mesh again remember mesh is just think of it just you know the photograph is the mesh then there's another one so there's four meshes so if it is a mesh then we say objects obgs dot push object that the object that it finds so it will fill this array with all the objects and of course you know we can console log this real quick um uh object and it should give us four different things here so you can see mesh mesh smash mesh so that's all four of them all right so that's just a quick way to find what's happening here so let's go back to that code so now we have our objects so now in our tick function we come down here and let's just do raycaster right here and we're gonna put all right first we're gonna to raycaster set from camera i we also oh i forgot another very important thing um remember i said the whatever is intersecting uh like whatever it is you want to intersect with the object you have to get that first in our case it's the mouse so we have to to do the mouse code real quick that goes in the first and then we're gonna put camera in the second parameter there so for our mouse let's create um right here all right so we already have our mouse uh right there so what we want to do is create a const of mouse equals new three vector two all right so there's a vector two and there's a vector three in our case we're just saying we want to store an x and y value that's all it is so we're going to create window at event listener and this is going to be on mouse move um and then we're going to pass in an event all right and so inside of here this is we need to get the mouse x and y and the reason for that is because we need to know we need to tell 3gs where this mouse is so that it knows whether or not we're interacting or hovering over one of the meshes that are on the scene based on that objs object so we're going to put an array rather so we're going to put in here mouse dot x equals event dot client x and we're going to divide that by the sizes dot width now the size is not width we didn't go over it i did in the first video though basically it's the width of the browser so if i do a search here real quickly yeah the size is that width equals the window inner width all right so think of it as that so we're dividing it by that and then we're multiplying it by two minus one now you're probably wondering why are you doing that this came from directly from bruno simon's course uh where i'm i'm basically getting this whole recaster code um what this does is it does a few things so for instance if we just take this real quickly let's comment this out or we don't even need to comment it out what we can do is console.log i the event dot client uh x alone so if we do this you see if we go to the very left we're at you know zero and because this is the x we're talking about the horizontal axis and the y it's all the way up here so we don't want values that are going all the way from zero to you know whatever the width of the browser is i what we're going to do is first we'll divide that by the sizes.width and what that will end up doing is that gives us a decimal a decimal point that goes from 0.0 to you know one essentially um and in order i forget what the justification was but this next bit right here will take that value and give us a negative value all the way from negative 1 to positive 1 at this end so that's what that's doing essentially i wanted to run through that so you can understand so we do the same thing with y so shift alt down just to replicate that line y right here is y and this is going to be sizes dot height and the same thing is happening here except there is one change we're going to wrap this in parentheses and we're going to put minus to invert the value because the way the y-axis works um and the values you get from javascript it's re it it's reversing um what you want for this effect to work so we just put a negative there so nothing's going to change here of course but now we have these mouse.x and dot y that we can use so remember now we're passing in the mouse right here from the raycaster so this is kind of like that boilerplate code that you just kind of need no matter what for this raycaster hoverbase thing to work and then we have to create a a consonant called intersex although you can name it whatever you want of course raycaster equals intersex objects and then we pass in the objects that we defined above so this is this value right here is gonna it's gonna let us know when the raycast or when our mouse essentially is hovering over these objects so now that we have that we can do a four const intersect of intersects all right because this is this becomes i an array so if we console log intersects let me see what happens so let's come out here oops did i intersect objects i put intersex it's intersect sorry about that all right so now if i hover over it lets us know it's kind of hard to see because you see all these other things uh you'll see that briefly it's letting us know when this uh intersects in and out all right so what we'll do is we i can put in certain things so console log intersected so let's try that so as we're hovering over it you can see it's bumping it up quite a bit and it's going to do this for all of them so it's going just it just gives you a time value essentially of how long this is hovering over and then when it stops all right so outside of here we can also create the inverse of that as well so what we can do is const i for const object of objs and we can say if intersex dot fine intersect this is a little bit verbose mean it's not verbose but it's a little bit complex um intersect dot object although this is just basic video javascript stuff equals object um we can what happens here is a console log let's see what happens here we're just going to put a test to see what exactly this does so you can see it's running continually continuously here let's refresh this all right so test so it stops when so it's basically the inverse of what was happening before and this is what's going to allow us to kind of revert back to um a an initial state so to speak so what we could do here is um we we now have access to each of these objects so what we can do is say um intersect dot object let's do position um let's just take dot x for it's moving it over um let's just set this to like three um by default it's gonna have them all pushed over to three so in order to make this work we have to put right here our object dot position dot x equals i i think it's one by default but whatever it is it's it's it's going to push it back to where it is now if we hover i thought that would work what the okay it was not working the way i thought it would um and that's because there is one error right up here this needs to be a plus all right so now if we go back we'll see we have this effect and that's because i'm hovering and it's posit it's moving the position back and forth so that's a bad example um what we could do instead let's put like uh scale dot set and then we can set the x and y um like at 1.1 1.1 and then we can do the same thing over here scale dot set oops what am i doing scale dot set uh one and one so now it should it's not gonna grow it's not gonna animate but it's gonna bounce up like that all right um another thing that i did change um i changed this right here i didn't have this recorded i put a minus here to reverse the scroll direction based on the scroll wheel so make sure you do that as well all right so if we wanted some some cool animations we can use gsap or greenstock animation platform and so what we'll do is install that and for those of you who don't know what it is i have like a ton of videos on gsap uh it's just a javascript animation library that can work with 3js so if we go to um our terminal let's create a new one we're going to mpmi gsap all right so that's ready we have to import it at the top and so that import code is let's see here import gsap from gsap we're going to come back down and so now it's inside inside of here we can say gsap and we'll use the two method um and so that's going to look like this so gsap 2 first parameter is your target um so we'll specify intersect dot object dot scale and then we put in an object in the next parameter and we're going to scale the x let's say 1.7 and the y to 1.7 and then we're going to go over here and we're going to specify g step 2 i object dot scale um oops there we go and then we're gonna put x just one and x one so when we say x one and one you're thinking well isn't that gonna change it to a square no it's just based on uh what it was originally set at if that makes sense um so if we go back now we can see something very strange happening here this isn't what i want oh that's why why am i doing x and x there we go x and y there we go all right so that's kind of cool now let's do something else let's also uh change it um in terms of the rotation so rotation this is a cool sort of thing we're just going to put the y and we're going to put value of negative 0.5 oh and let's also do that here so rotation and the y will be zero all right that's pretty cool let's also change the uh the depth of position so objective position and we'll change the z to negative 0.9 now i i played around with these values a lot and in fact it would be a good idea to use that dat.gui uh to help you figure out those values faster based on what you want so we could put position here um zero all right so now now it kind of like pushes them back and away from each other so they're not intersecting each other and that those are the values that i found worked quite well now what's really cool and what we will do in the future is you know there's so much more you can do with 3js in fact this example here is kind of silly just because this could all be done for the most part uh with just regular html css javascript um but we'll get into shaders which are an entirely different new subject i that i've never taught before so i have to become more confident before i get into shaders because we can do things like when this is hover over we could have some really cool sort of effects that occur on the image we can make it you know wave you can make flags you can make it move or just subtly change there's so much cool stuff that i'm excited but i wanted to at least cover this is already a long video i wanted to at least cover some of these basic concepts that we're going to be reusing in future tutorials um so um for the fun of it uh let's go ahead and put that um that simple headline so we'll go to index.html um and we're gonna specify a div class of content h1 and we'll say the city of excellence some random city and then we're gonna do our css and we're gonna specify you know what i like uh font family let's use playfair display i already have it installed you wouldn't need to obviously import this normally color white and i'm just going to i guess this is already a long video copy and paste these two values so this is just our content making a position absolute so it will sit on top of the webgl canvas display grid align item center which is just this h1 inside of it and then we're just you know doing something simple and there we go let me reset this to the actual size there we go very very very cool stuff all right so hopefully you enjoyed that that's really going to set us up in the future here to start getting into really cool stuff like with shaders and all that so make sure to subscribe if you haven't yet and i'll see you soon goodbye [Music] you
Info
Channel: DesignCourse
Views: 81,341
Rating: undefined out of 5
Keywords: threejs, threejs tutorial, threejs 2021, threejs smooth scroll, gary simon, designcourse, threejs raycaster, threejs raycasting
Id: U29j5NiSMVQ
Channel Id: undefined
Length: 39min 42sec (2382 seconds)
Published: Tue Mar 30 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.