# HTML5 Experiment: A Rotating Solid Cube

Previously I shared an HTML5 experiment consisting of a rotating wireframe cube. Today, I will share a new experiment that makes a rotating solid cube. This experiment is largely based on the wireframe cube experiment.

To run this experiment you need a browser that supports the HTML5 canvas element. You should see a rotating solid cube below if your browser supports the canvas element. If not, you should consider upgrading your browser to the latest version.

## The Code

```<!DOCTYPE html>
<html>
<title>HTML5 Experiment: A Rotating Solid Cube</title>
<script type="text/javascript">

function Point3D(x,y,z) {
this.x = x;
this.y = y;
this.z = z;

this.rotateX = function(angle) {
var rad, cosa, sina, y, z
rad = angle * Math.PI / 180
y = this.y * cosa - this.z * sina
z = this.y * sina + this.z * cosa
return new Point3D(this.x, y, z)
}

this.rotateY = function(angle) {
var rad, cosa, sina, x, z
rad = angle * Math.PI / 180
z = this.z * cosa - this.x * sina
x = this.z * sina + this.x * cosa
return new Point3D(x,this.y, z)
}

this.rotateZ = function(angle) {
var rad, cosa, sina, x, y
rad = angle * Math.PI / 180
x = this.x * cosa - this.y * sina
y = this.x * sina + this.y * cosa
return new Point3D(x, y, this.z)
}

this.project = function(viewWidth, viewHeight, fov, viewDistance) {
var factor, x, y
factor = fov / (viewDistance + this.z)
x = this.x * factor + viewWidth / 2
y = this.y * factor + viewHeight / 2
return new Point3D(x, y, this.z)
}
}

var vertices = [
new Point3D(-1,1,-1),
new Point3D(1,1,-1),
new Point3D(1,-1,-1),
new Point3D(-1,-1,-1),
new Point3D(-1,1,1),
new Point3D(1,1,1),
new Point3D(1,-1,1),
new Point3D(-1,-1,1)
];

// Define the vertices that compose each of the 6 faces. These numbers are
// indices to the vertex list defined above.
var faces  = [[0,1,2,3],[1,5,6,2],[5,4,7,6],[4,0,3,7],[0,4,5,1],[3,2,6,7]];

// Define the colors for each face.
var colors = [[255,0,0],[0,255,0],[0,0,255],[255,255,0],[0,255,255],[255,0,255]];

var angle = 0;

/* Constructs a CSS RGB value from an array of 3 elements. */
function arrayToRGB(arr) {
if( arr.length == 3 ) {
return "rgb(" + arr[0] + "," + arr[1] + "," + arr[2] + ")";
}
return "rgb(0,0,0)";
}

function startDemo() {
canvas = document.getElementById("thecanvas");
if( canvas && canvas.getContext ) {
ctx = canvas.getContext("2d");
setInterval(loop,33);
}
}

function loop() {
var t = new Array();

ctx.fillStyle = "rgb(0,0,0)";
ctx.fillRect(0,0,400,250);

for( var i = 0; i < vertices.length; i++ ) {
var v = vertices[i];
var r = v.rotateX(angle).rotateY(angle);
var p = r.project(400,250,200,4);
t.push(p)
}

var avg_z = new Array();

for( var i = 0; i < faces.length; i++ ) {
var f = faces[i];
avg_z[i] = {"index":i, "z":(t[f[0]].z + t[f[1]].z + t[f[2]].z + t[f[3]].z) / 4.0};
}

avg_z.sort(function(a,b) {
return b.z - a.z;
});

for( var i = 0; i < faces.length; i++ ) {
var f = faces[avg_z[i].index]

ctx.fillStyle = arrayToRGB(colors[avg_z[i].index]);
ctx.beginPath()
ctx.moveTo(t[f[0]].x,t[f[0]].y)
ctx.lineTo(t[f[1]].x,t[f[1]].y)
ctx.lineTo(t[f[2]].x,t[f[2]].y)
ctx.lineTo(t[f[3]].x,t[f[3]].y)
ctx.closePath()
ctx.fill()
}
angle += 2
}
</script>
<body>
<canvas id="thecanvas" width="400" height="250">
</canvas>

</body>
</html>
```

If you liked this experiment, please consider leaving a comment, sharing this post using one of the buttons below, or subscribing to the blog.

1. Mira Longworth

Excellent posting

• Thank you very much.

• Hello Alida. Thank you very much.

3. Hello & thanks for that !
Is there a way to replace each faces by on HTML div or image?

• Hello GeorgioA,

I guess you want to make a texture mapped cube.
First of all, let me tell you that there are 3 approaches for doing 3D with HTML:
(1) CSS3 using 3D transforms (with or without javascript)
(2) Canvas 2D (HTML5 + JavaScript) – this is the one used in this tutorial.
(3) WebGL (HTML5 + JavaScript)

It is possible to make a textured cube with the 3 approaches. However, the first approach is the only one that supports 3D animation of DIVs.

The code in this tutorial is something like a mini 3d engine coded from scratch. To do texture mapping, we would need to implement a function to draw textured polygons, and additionally we would need to alter the Point3D class adding texture map coordinates (called UV coordinates).
I will write a texture mapped version of this code, and post a tutorial about it in a few days.

(Texture Mapping = applying an image to a 3D object)

4. Great working example, but was wondering if it is possible to map images to the faces instead of the color values. Searched for replace color, your help will be greatly apriciated.

• It is possible to map images to the cube. The process is called TEXTURE MAPPING. Today I will start a series of tutorials that aim to show how to draw a texture mapped cube. The series will be broken in 4 parts.
Thank you very much

5. I don’t want the background to be black.I want it to be transparent.What should I do?

• You can do that by replacing the the 2nd and 3rd statement in the loop() function:

ctx.fillStyle = “rgb(0,0,0)”;
ctx.fillRect(0,0,400,250);

to

ctx.clearRect(0,0,400,250); // this clears the canvas making it transparent

6. it’s awesome, but i don’t know how to give a same color to all dimentions..?

7. Shikhar Sahdev

Thank you very much lefam.
And Amir you can edit the colors from the 68th line:

var colors = [[255,0,0],[0,255,0],[0,0,255],[255,255,0],[0,255,255],[255,0,255]];

Change the colors as you want.

8. oh …! now i c

9. Its awesome example. Can you please share textured cube code. And also just wanted to know whether you can add code to stop cube movement once user takes mouse over on any surface?

• I will share code to do a textured cube as soon as I get some free time.
Regarding the code to stop movement, you mean when the mouse is inside the whole canvas, or inside any of faces/surfaces of the cube?

10. good one

• Thank you!

11. Hi, this example is cool, I like it.

So I have one question, do you have a similar example with texture mapping drawing in each face in the cube?

I don’t know if I can building, but I think is possible.

Please let me know if you have any idea

Thanks!

12. i want background to have pictures..likewise pictures rotating..

14. Thank a lot for this code, I try to make a map for create a mini-game like Prelude of the Chambered (http://s3.amazonaws.com/ld48/index.html) or Wolfenstein 3D (http://en.wikipedia.org/wiki/Wolfenstein_3D) without use raycaster but I’ve no idea how to do that. I think create a map a 2D array (because I’ve only one layout) and a camera with coordinate x, y and z but I’m lost. It’s possible with this base code ? Can you help me, please ?

(sorry for my english level, I’ve a bad school english level)

• Hello PifyZ,

Do you want to make something like what I did in the post: http://codentronix.com/2011/06/18/a-simple-3d-room-made-with-directx-and-c/ ?

• Yes, I want make something like that but I don’t want use a library (or framework) and I want make that with Javascript (Canvas) like your code (I know this language).

I know it’s stupid but I like do everything myself and I hate use library, and I like learn with source code but I know nothing at the 3D.

I don’t know if you can help me but I try.

15. This is great, but if one dimension is reduced (ie. y is in (-0.2,0.2) range), the algorithm for sorting faces by depth doesn’t work well. How could this be fixed?

16. This is great! How could I add words on each wall of the cube?

• And how can you slow the rotation of the cube?

• Carol,

To slow down the speed of rotation, try changing the number on line 84 to a higher number, or change the number on line 124 to a lower number, perhaps a fraction.

17. I want to rotate the 3d polygon(more than 3 cubes attached as single object) while on drag. please suggest
how can i do that?

18. Wonderful post, thanks for explaining it

19. Hi Lefam, Love the spinning cube and have tested it and it works and spins in all major browsers, which has been really hard to find. I need to do a texture mapped version of the cube and you said in 2011 that you would be posting a tutorial about the texture mapped cube in a few days, I haven’t been able to find it, did you post it? It is essential for me to have a texture mapped cube, preferably with text on each face as well as a picture and for each face to have a link to a website page, would this functionality be possible with this cube? Please help. Thank you so much.

I guess you want to make a texture mapped cube.
First of all, let me tell you that there are 3 approaches for doing 3D with HTML:
(1) CSS3 using 3D transforms (with or without javascript)
(2) Canvas 2D (HTML5 + JavaScript) – this is the one used in this tutorial.
(3) WebGL (HTML5 + JavaScript)
It is possible to make a textured cube with the 3 approaches. However, the first approach is the only one that supports 3D animation of DIVs.
The code in this tutorial is something like a mini 3d engine coded from scratch. To do texture mapping, we would need to implement a function to draw textured polygons, and additionally we would need to alter the Point3D class adding texture map coordinates (called UV coordinates).
I will write a texture mapped version of this code, and post a tutorial about it in a few days.
(Texture Mapping = applying an image to a 3D object)

• Hello @AnnW. Sorry for my late reply. I have been very busy.
Sorry, I did not post the tutorial. But, I will post as soon as I have some free time.

20. Amazing code. I tried making my own from scratch, matrix multiplication is too confusing. This page even works in mobile browsers like my 3Ds and iPod! By removing the code at line 120 and the last t[f[3]].z part on 105 you can create faces using 3 verts. I guess for texture mapped cubes in canvas you would have to get the image data from the UV image and skew it to the faces? Or some type of array that replaces the colors with the pixel data?

21. I’mamazed, I have to admit. Rarely do I encounter a blog that’s both equally educative and engaging, and let me tell you,
you have hit the nail on the head. The issue is something
which too few men and women are speaking intelligently about.
I am very happy that I stumbled across this during my search for something concerning this.

22. hi lefam:

I’m newbe of js cavas, I misunderstood below formula few days.
y, z value is the offset distance ? Can you explain for me.
Many thanks.
//————————————-
y = this.y * cosa – this.z * sina
z = this.y * sina + this.z * cosa
//————————————-

23. токарный станок по металлу – токарный станок с чпу, токарно винторезные станки.

24. wondering if you can imbed video into each wall of this rotating cube while still keeping it all HTML5? Also, is there a way I can email you? I might be interested in hiring you to do some cube work for my personal website

Andy

25. оформить кредитную карту пенсионеру – получить займ без справок и поручителей, кредит наличными с доставкой на работу.

26. very cool code. is it possible to create more cubes to have 2 or + cubes rotating on page?

27. Awesome stuff, Cheers!

28. Amazing info, Thanks.

29. This website certainly has all of the info I needed concerning this subject and

30. I do consider alll of the idea you’ve offered in your
post. They’re really convincing annd can certainly work.
Nonetheless, the posts are verry short for newbies.
May you please extend them a little from next time? Thank you for the post.

31. Ремонт Айфон и Айпад – Замена микрофона iPhone 5S в Екатеринбурге, Замена защитного стекла iPhone 4S (тачскрина) в Екатеринбурге.

32. However, in comparison to Tramadol, morphine does not have the ability to induce improved postoperative immuno-suppression. The
nerve root and neurologic structures are protected and carefully retracted, so that the herniated
disc can be removed. In addition, the Green Light Laser Prostate Treatment
by less risk and complications than those previously used for treatment of BPH.

33. Hi, of course this piece of writing is genuinely pleasant and I
have learned lot of things from it about blogging.
thanks.

34. Very good article. I absolutely love this website. Thanks!

Great work

i want background to have pictures..
image rotating

36. If you are interested in topic: can you make money recycling old electronics

37. Your method of describing everything within this paragraph
is genuinely nice, every one can without difficulty know it, Thanks
a whole lot.

38. Pretty greаt post. І simply stumbled uoon уour weblog and wаnted to mention that
I’ve truⅼү enjoyed browsing yⲟur blog posts. Ⅰn аny case І’ll be subscribing
іn your feed and I am hoping yyou ԝrite once mοre soon!

39. Very efficiently writtеn post. It will be supportive to
anybody who utilizes іt, including yourѕ trᥙly :
). Kеep doing whhat you ɑre doing – ϲan’r wait to reаd mоrᥱ posts.

40. Hi, I wondered what the fov meant in the project function.

this.project = function(viewWidth, viewHeight, fov, viewDistance) {
var factor, x, y
factor = fov / (viewDistance + this.z)
x = this.x * factor + viewWidth / 2
y = this.y * factor + viewHeight / 2
return new Point3D(x, y, this.z)
}

I further understand the code and learned a lot from it. Thanks!!

• Field Of View…
Never mind!!

41. Wonderful, what a weblog it is! This blog presents useful data to us, keep it up.

42. nice work

43. Hello, is anybody here interested in online job? It’s simple survey filling.
Even 10\$ per survey (ten minutes of work). If you are interested, send me e-mail to
hansorloski[@]gmail.com

44. I have checked your site and i have found some duplicate content, that’s
why you don’t rank high in google’s search results, but there is a
tool that can help you to create 100% unique content, search for;
boorfe’s tips unlimited content

45. It’s an amazing piece of writing for all the online people; they will
obtain benefit from it I am sure.

46. Hi there, of course this piece of writing is really
good and I have learned lot of things from it about
blogging. thanks.

47. Hi. I see that you don’t update your website too often. I know that writing articles is boring and time consuming.
But did you know that there is a tool that allows you to create new articles using existing
content (from article directories or other websites from your niche)?
And it does it very well. The new posts are
high quality and pass the copyscape test. You should try miftolo’s tools

48. Hi everyone, it’s my first visit at this web site, and piece of writing is in fact fruitful in support of me, keep up posting these articles.

49. Hey i made a stereoscopic version out of your mini 3d engine.
https://codepen.io/jonasanoj/pen/aXKJwK?editors=1010

Thanks and peace !