How to Make an Interactive Rotating 3d Cube with CSS and Javascript
In the ideology.press site, there's a floating 3d book that rotates and follows your mouse around the page. Using six flat images, we talk about how to turn those images into a digital interactive cube.
Transcript
(upbeat electronic music)[Rik] If you're a SuperHi student,you can actually request tutorials like this oneand this is actually one of the most popular oneswe've had quite recently, it's from ideology.press,how do you make this spinning book,that goes round in 3D space?Now they're using something called three.js,we're actually gonna build oursin just 3D CSS and Javascript together,ours is a little bit different methodology,but you know, something that we can dois get something that looks like this,as we move our cursor around the page,you see the book is spinning in space,so we'll talk about how exactlyto make this book spin in space.(upbeat electronic music)In the previous video, I talked a little bit moreabout how 3D CSS works and you can see,this is the demo of that,now, if you do wanna watch the video,I'll just put the link in the top right corner.How do I actually make our rotating cube though?So in Sketch, what I've done is set up 6 art boards,each with different sizes, as a kind of flat version,so I've got the back and the spine and the coverand then three of the sides of the bookand I've just exported them as JPEGs.Now I've set up my HTML and CSS like this,I've got a section with six of the faces in here,do I've got a div with a class of faceand the class of face-cover and face-spineand back, top, side and bottom.I've got all the images set up hereand I've got a little bit of things,a little bit of CSS set up as well,so again, some of that is in the previous video.I've got on my body, a perspective of 1500 pixels,that basically means that my camera is 1500 pixels awayfrom whenever we do any kind of rotations.In my section, I've put this in the middle of the page,so position: absolute, 50 and 50and then I've used preserve-3dand backface-visibility, hidden,so if we turn anything away from the camera,we don't see it.So how do I set up all of my faces on the page?So what I'm gonna do is start the default,now I've got 6 faces, now where are they gonna be?Well, what I'm gonna do is make them all div-faces,all six of them, have position: absoluteand it's gonna be on the top and left: 0and they're all gonna have background-size: cover.Now I haven't give them a width and height,or which image they're gonna use,'cause we'll do that individually,a few things are different sizes,so at the moment, what we'll get is somethingthat looks like this, kind of completely empty,what we'll do is we'll add the first oneand then I'll quickly add in the secondand then up to all six of them.So the first one I'm gonna do is actually the cover,so how do we get the cover onto this page?Well, the first thing we need to dois add just a class of face-cover,so again, I'm just gonna add this in,so in this one, it's gonna take all of these,'cause that's in all six, but also for the face-cover,it's gonna have a height,now the height that I've set the cover at is up here,the width is 260 and the height is 400,so we'll add that in, the width is 260and the height is 400and which image is in the background?This background-image is going to be, while we said in here,it's gonna be a book-cover and that is a JPEG,so what we'll get on our page right now is this.Now this is in the top left cornerin the middle of the page,but we want the center to be in the top left corer,now usually what we'd do is we'd add a transform to this,what we'd usually do is say this, transformand then what we'd do is we'd do a translateof minus 50 and minus 50, so we'd shift it backby 50% of its width and 50% of its height to look like that,so this center point is now in the middle of the page.I'm gonna break that up into two bits,because we're gonna deal with 3D,so this is the x direction, that goes across the pageand this is the y direction up and down the page,so I could actually write this outin a different way, this bit here,I'm gonna do translateX, with a capital Xand say minus 50%, space,translateY minus 50% as well,so that is the same thing as what I just had,so basically right now, it will look exactly the same.What I can dois move this in 3D as well,so what I'm gonna do eventually with a few of theseis rotate them in different ways,I could do rotateX by, let's just say for now, 30 degrees,so now if we look at the page,you can see the x direction is this wayand it's spun by 30 degrees this way,so think of it again on a piece of string,that goes from this corner to this cornerand we're twisting it in this direction,if we wanted to shift it this way across the page,we'd have our piece of string going down the pageand we'd twist it this way,so if you wanna twist it the other way,we change rotateX to rotateY,so we shift in this way, 30 degrees instead.Now with the cover, we don't want to twist anything at all,so I'm just gonna get rid of this for now,but what we do want is to move thisa little bit closer to the camera,how much to the camera though?Well, if we go back to my Sketch file,we want it half of the width of the bookor the depth of the book, I should sayand the depth of the book is 40 pixels,so I wanna move this cover 20 pixels closer,because the back is gonna be 20 pixels away,so the difference is 40, so what I'm gonna dois also translateZby 20 pixels,'cause we wanna move this slightly closer,now it doesn't look that much different,because 20 pixels and zero pixelsdoesn't make that much of a difference,but when we add in the other ones,it will make that difference,when we turn it around and spin it in space.So what I'm gonna do just before we go on to the next bitis add the other five faces.(upbeat electronic music)So I've just quickly added in the rest of the five faces,so for the face-side, the height is 400,but the width is 40,we've given it the image, we've moved itand shifted it and twisted it by 90 degreesand then translated it in the z direction by 130,now why 130?Well, the width of the book itself this wayis 260, we're doing half that,so basically what we're trying to dois set it up in all six directions,the spine is pretty much the same,except we're rotating it in the negative 90 degreesand then translating it at the top,again it's translated across in the x direction,so it's going upwards and then translatedby half the height of the book, which is 200and then the back is just rotated minus 180,that could be just 180 awayand then we're translating it another 20,so because we're rotating it by 180,the difference between the cover and the back is 40,because we're twisting it and then moving it away.Now if we look at it right now, it looks exactly the same,how do I make this twist in space?Now the way that I twist in space is by rotatingthe whole thing, where is the whole thing?Well, in my index.html, the whole thing is in the section,so if I go back to my style.css,what I can do is rotate this whole section nowand to do that, I'm just gonna do a transformand in the same way as what I've got in my covers,my divs below, I can rotate in the x directionby let's say, 20 degreesand I can also rotate in the y directionby let's say 30 degrees and what we see nowis we can see this moving in spaceand the more that I change this,the more they all spin around,so if I change this to, let's say 320 degrees,it's now in that kind of way,if I change this in a negative way,so maybe negative 230 degrees, quite big,we now see the back of it as well.So what we can see is this is now moving in 3D space,but what we wanna do is base it on the mouse cursor,so what we want to do is change these two things,I want to change the top and the left,because that's where it is on the page,if I move my mouse around,but I also want to change the rotation on the page,so those are the things we're gonna change.First of all, we'll move it around in spaceand then we'll change its rotation as well.Now to use this, we need to use mouse movementand to do that, we need some JavaScript.(upbeat electronic music)At the moment, there's no scripts on the page,so we can't do anything in JavaScriptand there is no JavaScript on our site,so let's first of all add in the rotate.js file,again, I've made that name up,something.js, whatever you want to call it.Now currently it's empty, 'cause we've just made it,let's add that to the page, so I'm gonna add a script tagat the bottom of this page and give it the source rotate.js,now what do I want to do in this rotate.js?Well, the first thing I want to dois when I move my mouse cursor,all I want to do is move that box,depending on where the mouse is,so that's the first thing that we'll do,how do we think about that?So when I move my mouse cursor is the first thing,so let's do that, so on the page, the document,let's add an EventListener,now what do we want to listen to?Well in this case, the mouse movement,what do we want to do, whenever we move the mouse?Well, we need to do somethingand to do something, we run a function,so comma and then function,round brackets, curly brackets,now in this round brackets, I can pass in what is happening,now I can give this a variable a name,I'm gonna call it event, it could be called ev,it could be called e, it could be called potato,whatever you want to call it that makes sense,so whenever I move my mouse, something happens,we'll call that something, event.Now in my curly brackets, I wanna just open them upto make it a little bit easier to read what's going on,now in this event, the browser passes in lots of infoand with that info, it passes in two things,an event.pageXand an event.pageY,let's hold those two things,so let's hold them in a constant called x,'cause we're not gonna change it later on,let's make that equal to in the event,there's something.pageXand with that there's a yand the event is the pageY.
Now what do we want to do?Well, we said when we moved the mouse on the page,we want to do something, what do you want to do?Well, we wanna move the box somewhere,so the first thing we need to do is get the box,how do we get the box?Well, I'm gonna set up another constant,'cause we're not gonna change it, called boxand this is gonna equal to something in the page,well, what do we wanna find?So similar to what we would do in CSS,we wanna do, what do we call it?A section, let's call it,so we wanna find, we wanna do a querySelector,it's kind of like CSS,in quotes the section.Now if we had the class in this section,we could do section.box for instance,there's only one section on our site,so that's all we need to do.Now the next thing we need to do is,well, we've got the box, we've got the x, we've got the y,let's move it around, so on the box,what do you wanna change?We want to change its style,'cause we've got our CSS,what do we wanna do first of all?Well, we wanna change the left position,now what is a new left position?Well, this is gonna equal to x, 'cause we know where it is,now it's not just x,it's x in pixels, 'cause this is in pixels as well,but in CSS, we have 150 px,so we add px to it.Now what we'll get right now is on the page,I can move my mouse up and down,but this just follows down the page with me,what I wanna do is also move that to the top as well,so in the top, it's the same kind of thing, box.style.top,this is equal to not x, but y plus the unit, px.The next thing we want to dois actually twist it around the page.(upbeat electronic music)At the moment, I'm only changing one part of my section tag,the top and left, it's actually two,but we'll count it as one,but we also wanna change the transform as well,the rotation of this, so at the momentwhat we get is this, we can move round,but what I wanna do is if I'm at the center of this page,I don't want there to be any rotationand as I move across the page and up and down the page,I want to change the rotation.So what we're gonna do is first of allfind the middle of the page,how do we even think about that?So if I go back to my code in my rotate.js,I know the top and left position of the page,so right in the top left corner,how do I find the middle?Well, I'm gonna save this again to another constant,this constant is called midx, again, I've just named that,this is gonna be equal to,well, we know the top left corner position, which is x,but let's take away the middle of the page,so it could be positive directionand negative direction as well,so where is the middle of the page?Well, window.innerwidthand we'll divide it by two,so how wide is this page?Five by two, so it's in the middle,but x positive, this way, negative.We also wanna find up and down, so we're gonna do midyand this is gonna be the window.innerheight divided by two,so we've found the middle of the page,now let's rotate this around the middle,so we're gonna start off by changing which part?Well, which part are we gonna change?If I look in my style.css is the transform,we'll change the rotateX to not 320 degrees, but zeroand the y rotation is zero as well, let's start with that.So how do we think about that?So in my box, I'm gonna change the style,but I'm gonna change the transform this time,this is gonna equal to in quotes,'cause this is gonna stay the same,rotateX brackets zero degreesand rotateY brackets zero degrees as well,now if we look at the preview in the page,we'll see as we move around, currently it's not rotating,so the middle, this shouldn't rotateand as I move this way, you can kind of see the edgedue to the perspective on the site,we wanna rotate this way and this way.
Now which way do I actually want to rotate?Now, if I'm currently in the middle of my final design,if I'm going up and down the page,which way am I rotating?Well, I'm actually rotating in the x direction,remember if I've got a piece of stringgoing from left to right of the page,that's the way it's twisting around at the moment,so it might be quite, you might be tempted to say,well, if I'm moving in the y direction, we're rotating in yand if we're moving in the x direction, we're rotating by x,it's actually the other way round,because it depends on this kind of like invisible string,that the book is kind of rotating on,so let's think about that.So instead of this being zero degreesand zero degrees here,instead, it's not gonna be zero, it's changeable,so I'm gonna get rid of zeroand put a quote plus quote,now in here, what I'm gonna put inis not the midx, but the midy,so midyand then plus that as well,so I've got something that stays the sameplus something that doesn't, it changes,plus all of the stuff, which does stay the same,so now depending on where my y position is,we're gonna rotate in the x way,so now if I go across the page,that's the x way, it doesn't change rotation,if I go up and down the page, it does twistand I can stay on that level each timeand see the back of the book.Now obviously I wanna change this way as well,so how do I do that?It's the same thing, instead of this being rotateY,I'm gonna get rid of that zero and put quote plus quote,now I wanna add in there the midx and add a plus as well,so we've got this bit that stays the same,this bit that changes, this middle bit that stays the same,this bit that changes and finallythis bit that stays the same,so I've got two things that are changing,the midy and the midx position,so now I can rotate up and down the pageand go across as well.Now if I did want to change the kind of speed of that,so maybe it's too quick going in that direction,or too slow, all I'd need to do is change this,all I'd wanna put around thereis maybe a kind of multiplier,so I put a bracket and a bracketand then times by 0.5, let's say,so it's half the speed in the rotateX way,so now it goes fine this way, this way is a lot slower.So that's all we need to doto actually add something that spins around,all I've done is added some HTML,I've got six faces in there,in my stylesheet, all I've done is said all the 3D stuffand then rotate, depending on where it should be,depending on rotateY in these twoand rotateX or fully rotateand then just changed the translationand then to move it round the page,all I've done is say whenever I move my mousearound the page, do some calculations,find the box, move it round the pageand do some rotations, depending on where it is.(upbeat electronic music)