Home > Experimental, Front End Development, How to, Javascript > 3D Sphere Using jQuery

3D Sphere Using jQuery

September 22nd, 2009


Ever wanted your tag cloud to resemble a ball?  Of course you did.  This tutorial will walk you through how to create a Sphere in jQuery.

 

What We Are Building

This one can bog down a system in a hurry, but that’s the fun with experimenting with JavaScript.  We will be building a sphere that rotates depending on which way the mouse moves….exciting.

sphere

 

Getting Started

This tutorial is a continuation of a line of 3D jQuery posts.  I would recommend you having a look at the previous post so you’re up to speed.

Now that is out of the way lets get started.  For this project we’ll have 3 files. 

  • 3DEngine.js
  • Sphere.js
  • sphere.html

The 3DEngine.js is the same file that was in the previous posts so we won’t be covering that. The Sphere.js holds the Sphere class which is used by the 3D Engine.  Lastly the html file puts everything together.

 

The Sphere

With the sphere class we’ll be creating a set of 3d points (x,y,z) in an array.  To build the sphere we’re simply going to create a whole bunch of rings that start off small, get larger, then small again.  I’m not sure if this the best way of building a sphere, but it works so I’m not going to worry too much.

Here is the JavaScript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var Sphere = function (radius,sides, numOfItems){
   
    //Step through the number of rings.
    for (var j = sides ; j >= 0; j--){
       
        //Step through each point on a ring.
        for (var i = numOfItems / sides; i >= 0; i--)
        {
            //Space out each point evenly.
            var angle = i * Math.PI * 2 / (numOfItems/sides);
            var angleB = j * Math.PI * 2 / sides;
           
            //Figure out the x,y,z co-ordinates of each point.
            var x =   Math.sin(angle) * Math.sin(angleB)*radius;
            var y =  Math.cos(angle) * Math.sin(angleB)*radius;
            var z =  Math.cos(angleB)* radius;
           
            //Put the point in an array.                   
            this.pointsArray.push(this.make3DPoint(x,y,z));
        }
   
    };
};

//Need to extend class to work in 3d engine.
Sphere.prototype = new DisplayObject3D();

 

There are two loops.  One for the number of rings, the other for the points within each ring.  Inside the inner loop we first figure out where each point should lie, then figure out how that would translate into the x, y and z co-ordinates.

 

The jQuery / Html

Not much has changed in our jQuery / HTML since the 3d Plane post.  The only thing that has changed is we imported the Sphere.js and instead of adding a plane, we’re adding a sphere.

Here is the HTML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<body>
    <div id="item">
    </div>
</body>

<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script src="3DEngine.js" type="text/javascript" charset="utf-8"></script>
<script src="Sphere.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
    //<![CDATA[
   
    $(document).ready(function() {
       
        //Init Camera
        var camera = new Camera3D();
        camera.init(0,0,0,300);
       
        var container = $("#item")
       
        //Create object holder
        var item = new Object3D(container);

        //Add sphere to the object holder
        item.addChild(new Sphere(200,10,100));
       
        //Create scene
        var scene = new Scene3D();
       
        //Add object holder to the scene
        scene.addToScene(item);
       
       
        var mouseX,mouseY = 0;
        var offsetX = $("#item").offset().left;
        var offsetY = $("#item").offset().top;
        var speed = 6000;
       
        //Figure out where the mouse is when the mouse is moved.
        $().mousemove(function(e){
            mouseX = e.clientX - offsetX - (container.width() / 2);
            mouseY = e.clientY - offsetY - (container.height() / 2);
        });
       
        var animateIt = function(){
            //rotate the sphere along the y axis when the mouse
            //mouse is moved left and right
            if (mouseX != undefined){
                axisRotation.y += (mouseX) / speed
            }
           
            //rotate along the x axis when the mouse is moved
            //up and down.
            if (mouseY != undefined){
                axisRotation.x -= mouseY / speed;
            }
           
            //Render the scene.
            scene.renderCamera(camera);
           
        };
       
       
        setInterval(animateIt, 20);
       
       
        });
    //]]>
</script>

 

Disclaimer

Be careful adding points on this one.  Because the 3D engine doesn’t use html’s canvas just yet, it really can’t handle too many points. I can get away with 100 points on my machine without too much delay.  Chrome handles it the best out of all the browsers I tried.  So use it at your own discretion, you might have some angry viewers if you go too nuts.  This is just meant to be experimental…and cool.

The next step will be to optimize the 3D Engine a bit using the canvas so there won’t be this problem in the future.

 

Here is all the code together:

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var Sphere = function (radius,sides, numOfItems){

    for (var j = sides ; j >= 0; j--){
       
   
        for (var i = numOfItems / sides; i >= 0; i--)
        {
            var angle = i * Math.PI * 2 / (numOfItems/sides);
            var angleB = j * Math.PI * 2 / sides;
           
            var x =   Math.sin(angle) * Math.sin(angleB)*radius;
            var y =  Math.cos(angle) * Math.sin(angleB)*radius;
            var z =  Math.cos(angleB)* radius;
                               
            this.pointsArray.push(this.make3DPoint(x,y,z));
        }
   
    };
};

Sphere.prototype = new DisplayObject3D();

 

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<html>
    <head>
        <title>3d engine</title>
        <style type="text/css" media="screen">
            #item{
                width:100px;
                height:100px;
                margin:0 auto;
                top:300px;
                position: relative;
               
            }
            ul{
                list-style-type: none;
            }
            body{
                background-color: #111;
                color: #69c;
                font-family: Arial, "MS Trebuchet", sans-serif;
                font-weight: bold;
                font-size:2em;
            }
        </style>
    </head>
    <body>
        <div id="item">
        </div>
    </body>
   
    <script type="text/javascript" src="jquery-1.3.2.min.js"></script>
    <script src="3DEngine.js" type="text/javascript" charset="utf-8"></script>
    <script src="Sphere.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        //<![CDATA[
       
        $(document).ready(function() {

            var camera = new Camera3D();
            camera.init(0,0,0,300);
           
            var container = $("#item")
           
            var item = new Object3D(container);

            item.addChild(new Sphere(200,10,100));
           
            var scene = new Scene3D();
            scene.addToScene(item);
           
           
            var mouseX,mouseY = 0;
            var offsetX = $("#item").offset().left;
            var offsetY = $("#item").offset().top;
            var speed = 6000;
           
            $().mousemove(function(e){
                mouseX = e.clientX - offsetX - (container.width() / 2);
                mouseY = e.clientY - offsetY - (container.height() / 2);
            });
           
            var animateIt = function(){
                if (mouseX != undefined){
                    axisRotation.y += (mouseX) / speed
                }
                if (mouseY != undefined){
                    axisRotation.x -= mouseY / speed;
                }

                scene.renderCamera(camera);
               
            };
           
           
            setInterval(animateIt, 20);
           
           
            });
        //]]>
    </script>
</html>

 




Top