Building with React and Three.js using React Three Fiber

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Laughter] okay so the first thing you want to do is you want to head over to the github repository that's in the description and what you could do is you can go ahead and select this code button which will give you a url to clone the repository uh you could clone the master branch or you could kind of specify what branch you want to clone i do have two branches one being the master one being the starter so it's really up to you i do recommend cloning the master branch that way you can have both master and starter and then once you have the master branch cloned just go ahead and switch the starter branch through get checkout starter if we go over to this url here i'll have in the description this is the final project that we are going to build which is hosted on netlify at the moment and then if i head over to localhost 3000 i do have the starter wrench up and ready before jumping into the code i do want to talk about these models that i was able to download from a website called sketchfab so i did not make these i will have the creditor in the description but what sketchfab allows us to do is simply look for different 3d models that we could that we could download gtlf files and pretty much just add them to our project so if i were to look for the project we worked on which was an armchair i will select downloadable um i'm going to disable show restricted because they do have uh models with like nudity stuff so we don't want that i think it was called richie armchair yes so this is the one i got exactly the yellow the green and the gray if we go ahead and select it you can see that you could play around with the 3d model here you can also head over where it says download 3d model and then you will select the auto converted format of the gltf file select download and then this will go ahead and download the file for you it's going to give you two files as well as a texture folder the textures are related to the model's look so it's going to be image formats and then it's going to give you a dot bin and a dot gltf file now you don't need to worry about downloading these models i already have them in the starter branch if we head over to the code i have added them to the public folder so you can see textures gray compressed text is green compressed texture is yellow compressed and then we have the armchair gray green and yellow bin and dot gltf files so if you wanted to add your own um which was like a different model than what i currently have just download them and then drag them to your public and then make sure that they look like so where you have the textures which are just images and then you do have the bin and the glti file i did change the naming convention of these so make sure if you ever change the naming convention you must look for where it says this images array and then you need to make sure you update the paths as well as for the buffers for the uri make sure it matches the dot bin path or the dot bin name okay so that's enough here so again if you wanted to add your own just go ahead and drag them into the public and then you can reference them within your app.js but for now let's go ahead and jump into the project where we're going to start adding our canvas and then building out the rest of the site so actually before we start using the canvas from react3 fiber i do want to talk about this components folder i do have already created components that we don't waste too much time recreating them the header which is the simple header that we have at the top nothing special here and then we do have a section.js now this can get a little complex so i recommend just going in and just kind of playing around it but really what section is going to represent is the different blocks or sections we have uh now i did not write this myself this was uh grabbed from a code pin from the creator of uh react3 fiber which is paul henschel uh what you can do here is simply just look into how this works exactly but this is kind of referring to adding that smooth scroll to each section so as we're scrolling through it's going to pass a certain properties to kind of update how each section moves up and down the scrolling rig so we aren't using the default browser scroll or the scrolling element in the browser we are going to build our own scrolling area or scrolling rig which allows us to have a much smoother effect as we're scrolling if you scroll down here to the use section there's this custom there's this custom hook that comes with a lot of different things that we can reference we don't reference them here at all on this project but they are very helpful he gives us the option to you know find the viewport with the viewport height the canvas width canvas height this mobile uh returns a boolean depending on the width of the viewport if it is under 700 or not so these are different properties that you could play with uh again we don't really use it but it is an option i changed the name to section but it's typically called block and a lot of the examples that paul henshaw provides so we're going to be referencing this to add our model and that html within this section so that we can have that smooth scrolling effect i just didn't want to spend so much time redoing this entire section so you don't you don't need to worry about it too much and then we have state state is going to allow us to define the width or sorry the height of our entire project for the scrolling rig with the amount of pages we want pages does return uh sort of a a max height of a hundred viewport height so we have three sections for three pages then the sections elements this is kind of just more or less related to you know just updating the different uh you know sections or areas that we are located on within the page so i would just leave the state how it is with this sort of configuration you can update it if you want but this does match the fact that we can create three sections and rather smoothly using this section.js file so it all it all kind of is a bit confusing uh this is definitely a little bit more advanced when playing around with the react three fiber uh reconcile with the library so definitely just hold off on this for now we're going to focus just learning uh you know very basic things but still creating a very powerful site so that does it for the breakdown for the components and then we have the sas file which is just simple styles that you know you don't need to spend too much time looking here it's all very simple stuff so first thing we're going to do is get rid of this container that gets rid of the starter wrench we're going to go ahead and bring in a canvas and i do have auto import on so this is going to go ahead and auto import canvas for us from react 3 fiber it's already have canvas set up for us what we can do is pass in certain properties that we kind of need to kind of help with our canvas so we have color management which adjusts the colors corresponding to whatever we assign so it gives us a better look and then we also have camera and for our camera what we're going to do is set the position first so this does go by i believe x y and z so we're going to set it 0 0 and then 120 and then a fov which is the field of view the default is 50 but we're going to give it a field of view of 70. now we have our canvas already set up and if you had watched my previous react 350 tutorial i do go into more detail of what the canvas provides but it just gives us a uh the canvas that wraps around this scene as well as the camera so it's very easy to use in comparison to just 3js without react i'm not going to spend too much time describing a lot of the things that i'm going to talk about i will have a left panel that will go into more detail but be sure to watch my previous episode that one has you know more detail regarding basics now one thing i do want to mention is i am using dry and now what dry is is it allows us to kind of have these recipes or these custom components that can help us you know speed up the process of building you know a certain app so i already have dry installed and what i can do is i can import let's actually pull up the dock so i could show you so i am on the dry github repository and again it's just a collection of useful helpers and abstractions for reactor fiber so if we scroll down and look at sort of the index it allows us to right here for example for shapes instead of us using meshes and uh mesh materials and things like that we can just kind of actually we'll still be using the material but instead of having to define the different shapes we can just use these components for example if we wanted a box all we do is just bring in box or like round box plane and then we could do a sphere the plan would represent i guess the floor but we could do a sphere and all we do is pass in the material so it's just like a helper of allowing us to write 3js code or reactive fiber code much faster let's go ahead and start using it the very first thing that we're going to use from dry is actually the html so you cannot use html in the canvas it doesn't it doesn't register it right it doesn't pick it up so to use html we just need to use it from dry and then pass this in within the canvas so i'll just say dry and then the very first thing that we're going to do which is going to be very simple is just write html here and i'm going to provide it a property that will say full screen that will take up the entire screen and then in here i can start writing html so i'm going to pass a container and inside the container i'll pass an h1 called title and from here i'll just say hello so if i go out to our app i think we need to actually run it let's bring this up here yeah so just go ahead and run yarn start and now we have hello now to test out dry even further what we could do is just bring in a rounded box so i'm going to comment this out and then we'll do is rounded box and instead of writing it ourselves we can just copy it from here so i will copy this go back to our app and then we can paste it inside the canvas we can comment out this mesh props and then let's go ahead and change the z so if we look now it's going to be very small if we change the z index to like 20 this will zoom us in further so here's our little box if i get rid of wireframe it will just be a cube and so this is just given us more you know or not give us more but it's allowing us to write you know 3.js code faster using pre-built components with dry so i can get rid of this and just go back to what we were doing so i will set this back to 120 i'll uncomment the html and then we're back here perfect so we'll actually do now is i want to take out this html and create its own component so i am going to control x or command x and then from the top i'll create a function called or component called html content and now inside html content what i'm going to do is just page paste in the html that we just had and then i'm going to render out html content here so everything should still look the exact same right however now we want to build upon this html content to provide it the model as well as you know add the content that we need to actually add now what i'll do is i'm going to go ahead and wrap this entire jsx here with a section so right section like so but it's going to be capitalized because we're going to be importing the section component from our section js so at the very top here let's go ahead and import section from components and section like so we did get an error because the component does not contain a default export that's fine let's go ahead and add the curly brackets because section isn't a default export it's it has the use section hook and then the section so we'll go ahead and write these uh brackets just to bring in section uh section is going to take in two props a factor prop which will set it to 1.5 as well as an offset prop and this is related to uh the offset and sort of the the inertia and um kind of the amount of force you want as you're scrolling so the section moves it's not going to make much sense here because our scrolling rig is not yet built but it'll make a lot more sense here as we continue on through the project i will play with these so that we can have different scrolling effects or different scrolling power for the different sections let's go ahead and command x or ctrl x getting rid of everything that's in here and copying it because we still need to add a few more things i am going to add a group and now the position of my group is going to be set to the following it's going to be 0 250 and then 0. and again when dealing with position it's going to be x y and z so inside the group now we will paste in the html and if we take a look everything still looks the same if i play with this position set it to 200 it should be pushed down so we are going to be kind of multiplying by 250 for each section so this will be 250 then 0 and then negative 250 for the bottom and that's going to be changed in the position so what we could do next is start adding our model which is located in the public folder to add the model what we're going to do is create its own component now i'll call this component a model and what we're going to use is use the use gltf loader hook from dry so i'll go ahead and do a const gl tf and this will be set to use gltf loader and it will auto import from dry and then in here we're going to pass the url or the path so the path that we're passing in is the following so it's going to be forward slash so that we can access the public directory and then armchair yellow dot gl tf go ahead and add a comma and then we could pass true so that we could use draco i believe that's what it's called draco which if we look here let's look for loaders draco use gltf loader that doesn't take me okay use gltf loader well it's a convenience hook that uses used loader gltf and draco um use binary so if we wanted to use a binary we pass true and draco gltf although i don't know if we are using yeah use draco binaries for a custom path okay i'll leave it as true however i do need to do more research here in geology okay yeah we can use binaries okay cool so yeah past truths that we can use binaries but now we want to return the model we'll do the following we'll do return and then we'll use a primitive and inside the primitive we'll pass an object prop which this is going to receive the gl tf and then we need to access an object further in gltf which is scene so we're going to access the actual scene and then we'll pass in dispose and set that to null save that now let's go ahead and render this out and see if it does actually work so i have this group here within this html content and what i'm going to do in here is create a mesh now you don't need to create a mesh but i do want to play with the position of this model so i will pass a mesh and inside the mesh we'll just pass in the model and then for the mesh we will have a position and now we'll set the position position to the following it's going to be zero and then the y is going to be 35 and the znx is going to be zero okay let's save that and take a look so we did get an error and the error is related to model suspended while rendering but no fallback ui was specified at a suspense fallback component higher in the tree to provide a loading indicator or a placeholder to display okay so what this means is that we need to use a suspense so that we can have a fallback as the model is loading what we'll do is we'll grab suspense we'll scroll down and then inside canvas we're going to pass in suspense like so and then inside suspends past html content and then as a fallback property in suspense we're going to just set fall back to null for now but we will create a loading indicator um towards the end so let's leave it like so and take a look now perfect so hello did load and then the chair did load as well but it's completely black and that's because we don't have light if you don't have lights then there is no color which is pretty obvious but now i do want to say that i also want to start creating the scrolling rig uh what i s what i want to do next position so 35 it's pushed up let's push it down so i think negative 35 so now we can have it centered so now we're looking directly at the chair but i do want to add lights so i think we should add the lights we should add the effect behind the chair of its spinning and then add the scrolling rig and honestly we're pretty much almost done after that so we've got our model loaded everything's good to go i'm going to create a new function called lights not a function of a new component called lights and this is going to return the different lights that we want so the very first light that we do want to return is an ambient light and ambient light like that with the intensity of 0.3 and again as i am adding all these elements i am going to have descriptions on the right uh so that i don't leave you a bit confused so lights is not assigned let's go ahead and add lights we'll add it underneath the canvas like so we'll just render that boom so we have lights or we have the ambient light which gives it color but we don't have the other lights that we need so ambient light allows us to project light off of the objects all right i need to return more lights so let's do that we have ambient light at the top and we need to use react fragments because we need to add additional lights so go ahead and add those tags there we're going to add a directional light and the directional light will have a position set to the following so x will be 10 y is 10 z is 5 and then we do have intensity which is going to be set to 1. all right so let's see how it looks now okay so it gives it a bit more color which is nicer let's close out of that and then i'm going to copy and paste this again because we have another directional light but then the position and the intensity is different so the x will be 0 y is 10 and the z is going to be 0 and then the intensity is going to be bumped up just a bit to 1.5 okay so it's much brighter towards the top part here and then finally we're going to add a spotlight which i wanted to kind of just be flashing at it from a very far distance uh so we'll do that now spotlight and the intensity will be to set to one and then a position set to the following uh what am i doing okay we will set the x to zero y to one thousand and then the z to zero so let's see how that looks okay i wonder if we set the x to zero and the y to one thousand okay so that is hitting it direct on which i do like it rather than being at the very top because we already have enough fly at the top let's see one more time yes it's really bright at the top rather have it on the x which is hitting directly towards it so now let's make this baby spin uh to make it spin um it reminded me of the whole zbinala meme if anybody watches f1 let me know in the description but what we're going to do is make it spin so we're going to go down to the html content and we're going to yeah make the mesh or the group spin so to make this thing spin we need to add a ref so cause ref is set to a use ref and then we're going to get an error because user f is not being imported and then we're going to provide the mesh a uh i use the used ref so we're specifically targeting the mesh here or the model only and now i want to add a used frame now this is different than a use effect or anything in react this is coming from react3 fiber but what i want to do with the used frame is i want to grab ref.current which will grab this mesh ref will just bring in the object and then ref.current will grab the element and then i'm going to do dot rotation dot y is plus equal to 0.01 let's go ahead and save this and it auto imported use ref from react3 fiber so now if we take a look you can see that this is now spinning in kind of just in a circle really right so it's just rotating as if we're just kind of showing off the chair which is pretty cool so use frame um it's pretty much just a callback that's going to run or add point zero one to the rotation every single time it is rotated so it's going to continue rotating in a circle if i wanted to go the other way i'll just add minus or equal point zero one and it'll go the opposite direction perfect so that's allowing us uh to have this spin that's going to allow us to add the model with the lights so we're making very good progress so far what i want to do next is i want to add another html content here and i want to add it to the bottom but now this is going to be asking to you know we're going to ask it to be unique and render different content in a different chair and put it in a different position so let's do that and then add the scrolling rig so the different properties i do want to pass in here to make these unique are the following so i'm going to grab the properties before defining them which is fine i'm going to have children i'm going to add bg color or we could wait on the bg color for now i'm going to add model path and position so these three are going to be unique for now which children will represent the content the html content model path would represent the path we pass in to render the chair and then position is the position where we're going to set the kind of uh the group right so what we need to do is define those props in html content down below first thing we have is the model path now the model path is going to be the following so i'm going to grab this right here armchair gltf and i'm going to pass it here like that and then position i'm going to pass in 250 for the first one and then for children we don't pass anything in all we need to do is not make it self-closing they'll add html content like that so like so and then inside this html column i'll get rid of the second one inside this html content we're going to render this div so i'll take that i'll paste it in here like that and then inside of this html content components i'll get rid of this and just return children and then let's start plugging in the model path and the position position is going to be for the group so we'll get rid of this y and we'll pass in position maybe i should make this a bit more defined so i'll say position y rather than position and then make sure we pass in position y like so and then our model path is going to be passed into the model component so model path will be model path and then make sure you go to our model component and instead of this hard coded path we're just going to add model path make sure you use destructuring to bring in model path so let's go ahead and save that and take a look everything should be the exact same however now we want to load uh more unique content so what i'm going to do is copy and comment this out and then paste it in here and i'm going to change a few things the first thing i'll change is just this yellow to green so that we could render the green chair and then the content i will say buy i'll leave the position y for 250 for now so now we have buy and we have now we have a green chair so it's becoming a bit more you know dynamic in a way if you want to say that what we actually want to do though is provide better content and then we want to change the position so this position is going to be set to position y which means it's going to be pushed down but you can't see it because we don't have a scrolling rig made just yet but we're going to do that here in a second so i'm going to add or sorry uncomment the yellow which will just bring us back to hello and you know you can leave the content how you want but let's make the content you know i don't know i know in the final one i do have you know hey you know we have online chairs a new way to see online chairs we have different colors we have monochrome i'm not going to do that here i'm just going to give it the name or the name of the color of the chair which yellow is going to be yellow chair green will be green chair you know i don't need to copy everything i do in the final project so next what we can take a look at is doing the scrolling rig so the scroll area is going to be outside of the canvas so if we look for canvas here we're going to build the scroll area so i'll do dot scroll area like so and inside the scroll area we have two divs so the first div that we have is going to be related to the dom content or the content we render so the html content will be rendered in here and then we'll have another div and i actually don't need class names for these so i'll get rid of these but we'll have another div which will return the the height of our pages so what i'll do here is first define uh the kind of the dom content area so at the very top what we're going to do is add style and the domicon that's going to have a position of sticky and a top set to zero it's also going to have a ref attribute which the ref attribute will be called dom content so any of the html will actually go in here which we defined you know in the containers and i'll show you how to do that here in a second next the second div that we have will be related to the page height so what we'll do is do height and this is equal to the stage pages that or the state pages that we have so we did define those in the state and all we need to do is bring that in is just state dot pages and we'll multiply this by 100 viewport height so state is undefined as well as dom content but what we'll do is fix the dom constant first so const dom content is equal to use ref like so and then if we scroll to the bottom state is not defined which we just need to bring in state so page state import state from and this is coming from components state which we defined here so it's just a kind of configuration related to our height of the the application as well as scrolling behavior in a way so go ahead and save that and everything seems to be working well um what we need to do now is actually get content inside this dom content so if we look now and open up the console go to elements we'll see that we have this position relative here which is going to be our entire canvas and then we have this scroll area which has nothing inside but what we want to do is add the yellow html tags inside this position sticky so i think that there might be an actual better way to do this but this is a way you can i don't necessarily like this method all that much because it isn't dynamic to the page height we kind of need to pre-define what our height looks like and then build around that i think there's a better way to do it which um i'm still looking into but i think there's a code pin by paul henschel where he creates a a custom hook that is called every single time the page hide changes and it updates depending on the height of the canvas i will look into that maybe in a future video but definitely check that out i'll have that linked in the description below but for now we're going to use this method where we define our fixed height and then work around that so we have our height set everything is good to go we need to add the ref content in or we need to add the content in the dom content so what this means is uh let's first go to where we have this html content and we're going to pass in dom content so we'll do dom content is equal to dom content and we need to do the same exact thing for the first html content these two right here so let's scroll to the top and then we'll bring in dom content and then this html here will receive a portal set to dom content so now if we look at our scroll area we now have inside this position sticky this div of the yellow if we open it up here container title yellow and then we also have the one on the bottom so we can scroll now but it doesn't actually move that fixed area or it doesn't have like a function of the scroll area and that's because we haven't created that on scroll function which we'll do right now so in the app what we're going to do is the following we'll create a ref for scroll area and then we'll create an onscroll function so const on scroll and we'll pass in an event and what we'll do is return the following we'll say state which we already defined state dot top dot current and top dot current is coming from this create ref that we create and so we're just grabbing the element now is set to e dot current or sorry e dot target which is e.target will receive the scroll area this one here which we'll define in a second so e.target.scrolltop now we need to create a use effect which will run the onscroll function so we're going to return void on scroll and the reason we're returning void is because we want to define it as undefined initially and then we'll say target target is going to be set to the scroll area dot current and then just pass in an empty array perfect now this is getting an error because we haven't defined use effect so scroll the top and bring in use effect and then let's actually scroll to the bottom here with the scroll area and then for the scroll area we're going to provided a ref set to scroll area and then on scroll function is going to be on scroll like so let's save that and take a look now we have yellow in the yellow chair and as we start scrolling we get to the green chair now this model brings in its own kind of shadow but if you don't want that you can just delete the shadow texture and then create your own shadow with the plane if we scroll down even further you can see that it adds there's a lot more room left to scroll down and this is primarily related to the state pages uh multiplied by 100 which state pages is three so it's given us three sections and looking at this now it looks like i did make a mistake um which it's not really a mistake but it's just kind of i messed up the naming convention so what we'll do here is state.pages will just kind of be state.sections and if we set these to 2 it would only multiply the height by 100 viewport height now that is you know up to you on how you want to name these i'm going to leave it as sections here oops let's cancel that i'm going to leave it as sections because it does make more sense because pages refers to you know entire pages but then sections refers to how many sections you have in a page it's going to be the exact same thing but it's just sake for you know cleaning it up now we do have one more chair that we need to render at the bottom here so let's actually do that all that's going to and tell us to do is just copy html content again and then change armchair green to armchair gray and then change the title to say gray and now all we do is refresh and then now as we start scrolling it is kind of a bit laggy you can see that now they're rendering on top of each other and that's because i didn't update the position y so position y is going to be negative 250 which will push it down even further so now we have yellow we go down to green we go back up to yellow we go to green and we go even further to gray so now if i scroll all the way down and we get to gray and get to green so green right here is in the center of the entire canvas which is set to position zero if we go up to 50 we go to this yellow and if we go negative 250 we go to this gray so that's how that sort of math works behind the scrolling it's a bit confusing but it makes sense once you start playing with it perfect now what i want to do is i want to take a look at changing the background color and for us to change the background color what we're going to use is an intersection observer if we go to package.json though you can see that i have react intersection observer which allows us to use a using view hook to return a billion every time we are in the section um you know will return true saying we we can actually view this section or or not so let's do that real quick at the very top let's create a comment for intersection observer and this intersection observer what we're going to do is import use in view which is a custom hook and we're importing it from react dash intersection observer now i'm going to scroll down to the html content component here and what we're going to do is const ref item and then we're going to pass in in view it's set to use in view and then we're going to pass uh some properties or actually one property which is the sirens are going off let's hope they're okay okay so the sirens are gone now um what we'll do is yeah i pass in a threshold of zero which just means that kind of gives us like margin ish right if we don't want to i'll add the description i forgot to okay so the threshold i think what it means is that there is no offset or there is no kind of additional margin that we need to view right setting it to zero just leaves it like so but what we'll do is this ref item is going to be passed in and i just realized i don't have a development in this html component but what i will do is i'll create a div and i'll call it um what should i call this i don't know we'll just call this view and i'll provide this ref the ref item and i actually don't even need a class name just add a div around the children just so that we can have a ref so now i'll add a use effect right and what we'll do in here is i will say in view and end which is going to say true run this right if it's false we're not going to run it at all but we're going to grab the document dot body dot style dot background and we're going to set this to bg color now bg color will be dynamic dependent on the section and i'll show you how to do that here in a sec but as a dependency we're going to pass in in view make sure that we grab this bg color now and bring it in as the structuring this means we do need to pass bg color as a prop so let's pass bg color as a prop for the first one and for the first one we're going to say bg color represents the following hex code so it's going to be that orangish color f15946 i'm going to copy this scroll down to the second html content and in here i'll pass a purplish color which is going to be five seven one e c one and then on the last one i'm going to have bg color of the following it's going to be grayish right so six three six five six seven like so perfect so let's take a look now if i refresh we have the yellow messed up and i think this is messed up mainly because of this div right here so to fix that end center it again what i'll do is i'll pass in the class name of container and that will fix it but then it's kind of redundant the fact that we're passing container in the container again so get rid of the container that's inside the cha the children or representing children inside html content because we don't need to render container twice so now we're back and it's set to yellow now if i scroll down the background color turns purple if i scroll down the background color turns gray and then purple and then back to orange and then back to purple so these entire sections are at a height of 100 viewport height once i scroll into the next 100 viewport height it will turn to the corresponding color of that specific section yellow is orange green is purple and gray is gray okay so that's gonna do it for me if you didn't enjoy it please leave a like don't forget to subscribe and lots more content coming soon i've just been really busy thanks for staying patient with me guys stay safe out there and have a wonderful day
Info
Channel: Wrong Akram
Views: 106,396
Rating: undefined out of 5
Keywords: javascript, react.js, react, github, code, css, jsx, ui, ux, awwwards, javascript animations, three.js, 3d, javascript 3d, react-three-fiber, react-spring, webgl, react 3d, gltf, sketchfab
Id: Qs9A3XIjbg4
Channel Id: undefined
Length: 42min 45sec (2565 seconds)
Published: Wed Sep 23 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.