Build a 3D Float Effect using Three.js, Framer Motion, Next.js

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today I'm remaking a classic float animation that I've seen in a lot of words Wing website my process to remake this animation was pretty straightforward first I went in blender and created a 3D scene with a bunch of shapes that I imported inside a canvas then I used the float utilit function by react 3 Dre to add a basic float effect to every single shapes and finally I used frame motion to add some asymmetry to the animation based on the position of the cursor so yeah let's see this in detail and as always you can find the live demo and the source code in the description below all all right so I have a very basic next chest application here but for this tutorial you could use any react based framework it won't change anything and so for now I just have an Mt project it looks like this in the browser and the first thing I'm going to do here is create an external component and I'm going to call it like floating shape and it's like a very basic function here and then I just import it inside of D phjs and we should have something like this and then the first thing I can do here is import a canvas from react 3 fiber and that's going to be the parent of everything inside of this animation and so I'm just going to put the canvas here and I can delete that and the the basic structure that I'm going to have here is basically I'm going to have the models and I'm going to have the environment here and so to have the models here I'm going to create another component inside of the floating shapes and I'm just going to call it model. GSX and now inside of that guy I'm going to initialize all of my shapes and to make all of my shapes I've used the blender here to create everything that I want and you can see here the perspective I've put them quite far away from each others because I want to like rotate them and I don't want to have like any collision and so that's why it looks like this but if we look at it from a forward angle we can see that it looks quite natural right it looks like they are all grouped together and it's also important to note that my material here is just like a really basic material I've just clicked like new material and CHS a color all right nothing too complicated here and it's also important to note that all the names here of the layers they're basically going to be the reference that I'm going to use to import them inside of the canvas and so once we know all of that we can go ahead here in the file and do export and I'm going to export it in gltf or glb file and now to visualize your glb file you can actually use this really useful tool for from po mandress I'm not sure if that's how you pronounce it but and so I'm just going to take my floating shapes and I'm going to drop that file inside of that website and with that I can basically see my scene here I have all of my shapes that I've made in blender and that's how they would look inside of the canvas and I can actually see the options that they put and one thing that's quite important is the environment here which I'm also going to use and this basically changes the lighting and so you could have like night and you can see the lighting is quite different you could have like Park and you see that the color and the lighting changes and then on this side we have like the code it would basically look like this of course I'm not going to copy paste this because there's a way more efficient way of doing this but it kind of gives you an idea of what it's going to look like and also I forgot one thing I need to specify here in the roots of my floating shapes component that this is a client component and so we basically tell them hey we're not client and not on the server and yeah after that I'm going to go in the public folder and create a media folder and I'm going to grab my floating shapes glb file I'm going to put it inside of the media and now I basically want to extract all the meshes from that file and so inside of the model components I'm going to have here an import and I'm going to import the used gltf from react 3 Dre and this is basically the same thing as mentioned here I'm going to grab the nodes and the materials but actually I won't need the materials here so I'm just going to grab the nodes and here I need to specify that it is inside the media folder and there's also one thing missing I'm just going to grab that line here to preload and same thing I'm going to specify Medias and that should be good and now instead of just copy pasting all of that which is like a lot of repetition I'm just going to create here an inner component and I'm going to call it a mesh and that mesh will take a node as a parameter and it's going to return here basically a mesh from 3js and now all of those information here I'm going to extract them from the node and so I'm going to have here the cast Shadow the receive Shadow scale and now instead of having like react fragments here I'm just going to create a group which is basically a group of mesh and I'm going to have a first mesh which requires a node as a parameter and I'm going to do nodes Dot and so what I can do is just check here I'm going to take like for one for example I'm going to take like the sphere maybe sphere 003 and I'm going to save that now I have a very small black sphere here I'm just going to inspect that and I can see that my canvas is like really small and so the first thing I want to do is like make that full screen and so if I go back in the roots of everything in the page.js I have the main here and so I'm just going to style the main to be in display flex and have a height of 100 G height and now if I take a look at this I have my canvas taking the full height and full width and I have my black sphere here and so that's basically it I'm going to do the same thing but for all of the meshes inside of the scene and I can use that visualizer to really see all my meshes and that's going to help me and there we go I'm done now you might ask why am I creating a mesh like one by one like this why am I not just looping the nodes and just having like a nodes. map and returning all of the meshes at once inside of a loop and the reason why is eventually I'm going to add a multiplier that's going to be a constant value that's going to be different for every single mesh and with that I'm going to be able to create a variation between all of the meshes all right that's the reason why I'm not looping the notes now if I take a look at the result I have something like this quite worrisome it looks like trash really it's like not even the right perspective it's all black like what the hell is going on here I would expect to have something that looks like this but really I have something like this but it's no problem we're going to fix it first thing we want to fix is going inside of the roots of the floating shapes and inside of the canvas here I'm going to specify a camera the first thing I want to do here is specify that I want an autographic camera and now the difference between an autographic camera and a perspective camera is I can basically show you that inside of blender here and so this is an orographic perspective it squashes the perspective there is no Distortion the closer the object is to the camera whereas a perspective camera it's going to look something like this right the cone here is really close to the camera so it appears bigger whereas like this tube shape here is further away from the camera so it appears smaller so that's the difference between a perspective and an orographic camera and personally I like this look more for this specific animation and that's why I specify an orographic camera and then I'm going to add some options here for the camera the first thing is I'm going to have a position which is a vector 3 and so on the X and on the Y I'm going to have zero and then then on the Zed I'm going to have 200 meaning the camera is going to be closer to us and it's going to look at the objects like this and now 200 on the Zed axis is quite far away so what I'm going to do is have a zoom of 10 and so it's going to be far away from the objects and then it's going to zoom in so I can save that and see the difference here and boom now you can see that I have something that looks way more like my blender scene something like this and I'm quite happy with that now of course everything looks black and that's because there is no light in the scene and if we go back in the visualizer here we can see in the environment here this is what's lighting the scene here and I kind of like this lighting it's like really simple to to create I don't have to like put a point light and choose a position I'm just going to put an environment and so I can take a look at the Dawn and like the lobby and all of that they all have different lighting and personally the one I really like is the studio lighting it's this one here so and so how do we translate that into our code going to go back in vs code here and that's basically the environment that we have here and now I'm going to import here the environment from react 3 Dre and I'm going to have an environment at the root here inside of the canvas but not inside of the model and really really easy I can just do preset is equal to Studio which is the one that I selected inside of the visualizer and if I take a look at the result I have something like this I have my shapes with some lighting but personally I'm not a fan of like the white background with this lighting specifically it just looks too bright for my own taste so easily what I'm going to do here is just add some styling to Canvas I'm going to have a background and I'm going to put a color that I specifically chose and I should have something like this which to me helps to see the contrast I prefer it that way so yeah now we're done importing the shapes and I'm going to make everything float now for the floating there is a utilit function that's really useful inside of the Dre package if you do 3D and you don't know about it you should definitely check it out there's a lot of useful tools inside of that and so I'm going to go here and I'm going to look for the float and I can take a look at their demo here they basically have like a ship and an astronaut that's floating and what they do here is basically add a float on top of their shapes and so I'm going to do the same thing here I'm going to go inside of the model and here I'm going to import float from react tree Dre and I'm just going to put the float as a parent of the group of meshes and easy like that I have a bunch of floating shapes now there's a couple of things that I don't like about this one thing is everyone can add a float and basically do the same thing that you just did all right so what I want to do here is to add some asymmetry make my animation a bit unique than just like the basic presets of a utilit function and another thing that I don't like is it's not interactive like this could be a video and I wouldn't even see the difference and so to solve those two problems I'm basically going to add some interactivity with the mouse and create some asymmetry now I'm going to use frame motion for that so since I want to use the mouse to create some interactivity first thing I want to do here is grab the position of the mouse and store it inside of a state so the first thing I'm doing here is adding a use effect hook that's going to trigger an event listener on Mouse move and that's going to call a function called manage Mouse move and then I'm creating a mouse object with an X and Y value that I initialize with the use motion value Hook from refer motion and inside of the manage Mouse move I extract the client X the client Y and I set the x and the Y with the relative position of the X and Y now for the mouse I could be using a react state but instead I'm going to use a motion value from frame motion because the frame or motion value basically has an inner State and that's actually better for performance because now every time I move my mouse I'm setting a new position for the mouse which if it is a react State it's going to reender my whole component every time which is not the best now instead I use a use motion value which has an internal State and so only the objects that are going to use the mouse will be rendered and then I'm just going to pass the mouse to the model here and now the model has access to the mouse and then I'm just going to give the mouse to the mesh here so they're going to manage their own animation something like this and now the mesh here has access to the mouse and so the first animation that I can create here is a rotation on Mouse move so first thing I want to do here is I'm going to create here a rotation X which is going to be equal to the used transform hook and that used transform is from Fair motion by the way and now the used transform function here basically is going to help me transform the position of the mouse which is a value between 0 and one and then I can choose new values from it and so I could have the current rotation X and I'm going to do minus one to the current rotation x + one and so with that we basically have a rotation X the more the mouse goes to the right the more it's going to rotate on the X and if it goes to the left it's going to rotate on the X but the other direction and then I can basically just grab the rotation X here I can do rotation X is equal to the rotation X and now this rotation x value here is a motion value it's not like number and so I need to add the motion tag here in front of the mesh for it to work and I'm going to import it here and I'm going to save that oh and here I need to specify that it is the x that I want for the mouse and I'm going to import that motion here and it's actually not from frame motion now the motion will come from frame motion 3D and I can try this see what we have I'm going to move my mouse and you can see that if I move my mouse on the x-axis it's actually moving all of the shapes here now I definitely see a couple of problems with that the one is the rotation is like directly link with the mouse there is no like easing there is no lurp and another problem is all the shapes are rotating by by the same amount and so it doesn't look natural at all and so I'm going to tackle the first problem which is making the mouse smooth adding a kneeing so it's not directly linked with the mouse and it's actually going to be real easy I'm going to go in the rout here where I initialize my mouse and I'm going to have instead a smooth Mouse which is going to be equal here on the X to the usering hook from fir motion and I'm basically going to use the mouse dox and same thing on the y- AIS but I'm going to use the mouse that I and then I'm just going to grab my smooth Mouse and instead of giving straight up the mouse I'm just going to give the smooth Mouse and let's see what I have here if I move my mouse you're going to see that I kind of have a kneeing there's like a spring animation happening like the shapes are rotating and then they're like coming back a bit which is not really the effect that I'm looking for here but that's the basic options of the US spring hook and so all I have to do is modify the options here to have the effect that I want and there's this really nice visualizer which is like firm motion visualizer versal app that allows you to basically visualize the US spring hook cuz it's it's quite complicated it has three options one is stiffness damping and mass and like it's kind of kind of hard to visualize if you don't understand what's happening behind the scenes and so this visualizer is really nice to use and those are the values that I ended up choosing for my animation and I can basically grab them and put them here as options for the smooth Mouse and I can save this and I'm going to see what I have and now you can see that this is looking much more realistic for a floating animation and now the second problem is I have no variation right all of the shapes are rotating at the same time which is not Supernatural I would like to have some variations between all of the shapes so now instead of just rotating with a constant value here I'm going to have basically a unique value for each mesh and so what I'm going to do is add a multiplier here and so I could have like a multiplier of 2.4 now I'm going to have access to a multiplier here and now instead of using a constant I'm just going to do minus the multiplier and now I need to do is have a unique multiplier for all of my shapes that I can choose personally depending on my taste and so I have something like this different multiplier for the different shapes I personally gave a smaller multiplier for the biggest shapes so that it looks like realistic with the physics and I can try this out and you're going to see that all of my shapes here are not rotating by the same amount and that's something that I really like and now I'm just doing a rotation on the x axis and I basically have the perfect structure to change any properties that I want so I'm going to do rotation y position X and position y so for the rotation y I'm just going to do the same thing but Mouse y instead rotation y here and rotation y here and then I'm going to have a position X I'm going to do the same thing Mouse X but here instead of taking the current rotation I'm going to take the current position and then same thing for the position y but now I'm taking the mouse y here is position X and here I'm going to add them in the properties I'm going to have rotation y position X so yeah something like that and now all of my shapes are moving a bit and they're also rotating depending on the position of my cursor but this animation looks quite odd it doesn't look natural at all with the interactivity and I believe it's because when I move on the x-axis I would like to rotate the shapes on the y- axis so here on the rotation X I'm going to take the rotation y value and on the rotation y I'm going to do the rotation X just reversing those two axis for the rotation and now yeah this looks a bit more natural you can see that it's actually moving according to the position of my mouse and there's another thing that I don't like I think it's rotating a bit too much and it's not moving enough so I can fix that pretty easily I'm going to have here a constant I'm going to call it a and I'm going to have it be the multiplier divided by two and I can actually use the a for the rotation instead of using the multiplier I just basically use the a which is the multiplier divided by two and so I'm going to have a bit less of a rotation and now for the position I'm going to do a multiply by two so I'm going to have more of a translating animation so I should have something like this and so it seems to make sense on the xaxis for the translation but on the y- AIS if I go up my shapes are going down and if I go down my shapes are going up so I'm just going to reverse the values here for the Translate Y I'm going to do plus here and minus here so that it's reversed and now that makes a lot more sense if I move my mouse this looks quite like a natural effect to me and so yeah that's basically the animation a really nice floating effect with some mouse Interactive I hope you learned something if you like the video leave a like subscribe and I'll see you in the next one bye
Info
Channel: Olivier Larose
Views: 4,653
Rating: undefined out of 5
Keywords:
Id: BgHv1G3oFDg
Channel Id: undefined
Length: 15min 4sec (904 seconds)
Published: Sun Oct 22 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.