Creating a Wobbling 3D Carousel
We’ve all seen a carousel in one form or another. This post will show how to create a carousel with a wobbling effect, much like an unbalanced wheel.
What We’re Building
We’ll be creating a carousel with the help of the 3d Engine we built in a previous post. The idea is we’ll create a ring by plotting points in 3d space, then we’ll rotate it so it’s almost perpendicular to the viewer. Because it’s not 100% flat, it will look like it’s wobbling up and down, giving your carousel a little more flavor.
Building the Ring
If you haven’t read up on the 3d Engine just yet I recommend you do so. Creating objects for the engine isn’t overly complicated. It’s just an array of 3d points. With the ring, we’re going to use math to plot the points for us. We’re going to be creating a circle and plot it in 3d space.
Here is the JavaScript: (Ring.js)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | var Ring = function (radius, numOfItems){ //Step through each point on ring. for (var i = numOfItems - 1; i >= 0; i--) { //Figure out where each point lies on the circle var angle = i * Math.PI * 2 / numOfItems; //Translate that point on the circle into x,y coordinates. var x = Math.sin(angle) * radius; var y = Math.cos(angle) * radius; var z = 0; //Add the point to the array. this.pointsArray.push(this.make3DPoint(x,y,z)); } }; //You need to inherit the DisplayObject3D. Ring.prototype = new DisplayObject3D(); |
The Ring class takes 2 parameters, the first is the radius of the ring, and the second is how many items are going to be on the ring.
We then proceed to step through all the points, and place them at equal distances around the ring.
The HTML
There isn’t much too the html. We’re simply going to create a <ul> with a bunch of words in it.
Here is the HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
The jQuery
There is not much changed from our previous post on how to create a 3d plane for jQuery 3D Engine. The only difference here is we’re going to give an initial value to the axisRotation x value. This will rotate the ring towards the viewer. Through trial and error I figured out the value that worked for me.
Then we’ll animate the axisRotation y value when the mouse moves left and right.
Here is the jQuery:
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 | $(document).ready(function() { //setup camera. var camera = new Camera3D(); camera.init(0,0,0,300); var container = $("#item"); //Setup 3d object holder. var item = new Object3D(container); //Add ring to 3d object holder. //The first argument for the ring is the radius. //The second argument for the ring is how many items //are on the ring. So we pass in how many items are in our list. item.addChild(new Ring(200, $("#item ul li").length)); //Create a scene. var scene = new Scene3D(); //Add 3d 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; //Capturing mouse movements. $().mousemove(function(e){ mouseX = e.clientX - offsetX - (container.width() / 2); mouseY = e.clientY - offsetY - (container.height() / 2); }); //Rotate ring so it's almost perpendicular to the viewer. axisRotation.x = 1.5; var animateIt = function(){ if (mouseX != undefined){ //When the user moves the mouse left and right, //rotate around the ring on the y axis. axisRotation.y += (mouseX) / speed; } scene.renderCamera(camera); }; setInterval(animateIt, 20); }); |
Voila!
That’s all there is too it.
Here is all the code together:
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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | <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:1em; } </style> </head> <body> <div id="item"> <ul> <li>website</li> <li>jQuery</li> <li>JavaScript</li> <li>HTML</li> <li>PHP</li> <li>3D</li> <li>Ajax</li> <li>CSS</li> <li>Design</li> <li>Flash</li> <li>Experimental</li> <li>Development</li> <li>web</li> <li>Tutorial</li> <li>ASP</li> </ul> </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="Ring.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 Ring(200, $("#item ul li").length)); 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); }); axisRotation.x = 1.5; var animateIt = function(){ if (mouseX != undefined){ axisRotation.y += (mouseX) / speed; } scene.renderCamera(camera); }; setInterval(animateIt, 20); }); //]]> </script> </html> |
Ring.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | var Ring = function (radius, numOfItems){ for (var i = numOfItems - 1; i >= 0; i--) { var angle = i * Math.PI * 2 / numOfItems; var x = Math.sin(angle) * radius; var y = Math.cos(angle) * radius; var z = 0; this.pointsArray.push(this.make3DPoint(x,y,z)); } }; Ring.prototype = new DisplayObject3D(); |
Just a small tip. If you wanted to create a carousel that doesn’t wobble, your first instinct might be to adjust the axisRotation x value until you get it. You can do it this way, it just might take a bit to get it right on the money. The easier way is to adjust the Ring.js file, and switch the y and z values. This will create a totally flat ring and you don’t have to worry about using the axisRotation x value to try and flatten it out.


