Buildtide
Author: Hussain Mir Ali

I am interested in web and mobile technologies.

If you have any questions or feedback then message me at devtips@Buildtide.com.

3D Objects with JavaScript

In this post I have discussed the use of  ThreeJS which is a WebGL library for modelling 3D objects in the browser. This is great because it allows developers to build useful applications while utilizing the power of GPU.

I will be building a comical representation of  an atom. The nucleus will be a sphere object and there will be three electrons orbiting around the atom. Some thing like in the picture below. But there will be color differences.



Step 1: Setting up files.

In the project folder create app.js file. This will serve the index.html file.


var util = require('util');
var fs = require('fs');
var engines = require('consolidate');
var url = require('url');
var express = require('express');
var app = express();
var path = require('path');
var name, email, message;
var port = process.env.PORT || 8081;

app.use(bodyParser.json());
app.engine('html', engines.mustache);
app.set('view engine', 'html');
app.use(express.static(path.join(__dirname,'')));

app.get('*',function(req,res){
res.render('index.html');
});

app.listen(port);
console.log("Express server listening on Port: "+port);

Create scripts folder under the project directory. In the assets folder create three.min.js and TrackballControls.js. Copy these files from the following link https://github.com/husenxce/comicAtom/tree/master/assets .

In the project directory create index.html file.


<html>
<body>
<script src="scripts/three.min.js"></script>
<script src="scripts/TrackballControls.js"></script>
</body>
</html>

Step2: Setup main.js file. This file contains the logic for the atom and the motion of electrons.

Create the animate and render function. These are responsible for tracking the mouse and 
updating the scene.


 var camera, controls, scene, renderer;

init();
animate();

function animate(){
requestAnimationFrame( animate );
controls.update();
}
function render(){
renderer.render( scene, camera );
}

Create the init() function. This function contains the logic for setting up the geometry, lighting, material, mouse control and perspective of the application.


            function init(){
var i = 0;


//Code for Camera perspective.
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.x = 100;
camera.position.y = 100;
camera.position.z = 700;

//Control for mouse change and tracking.
controls = new THREE.TrackballControls( camera );
controls.addEventListener('change', render);

//Initializing scene.
scene = new THREE.Scene();

//Adding Sphere for the atom nucleus.
var geometry = new THREE.SphereGeometry(50,50,50);
var material = new THREE.MeshLambertMaterial();
var mesh1 = new THREE.Mesh( geometry, material);
mesh1.position.x = 0;
mesh1.position.y = 0;
mesh1.position.z = 0;
mesh1.material.color = new THREE.Color( 0xff0000 );
scene.add(mesh1);

//Adding Spheres for electrons.
var geometry = new THREE.SphereGeometry(10,10,10);
var material = new THREE.MeshLambertMaterial();
var mesh2 = new THREE.Mesh( geometry, material);
mesh2.position.x = ( 150);
mesh2.position.y = ( 250);
mesh2.position.z = 0;
mesh2.material.color = new THREE.Color( 0x4900FD );
var refx2 = mesh2.position.x;
var refy2 = mesh2.position.y;
scene.add(mesh2);
var mesh3 = new THREE.Mesh( geometry, material);
mesh3.position.x = ( 200);
mesh3.position.y = 0;
mesh3.position.z = ( 200);
mesh3.material.color = new THREE.Color( 0x4900FD );
var refx3 = mesh3.position.x;
var refz3 = mesh3.position.z;
scene.add(mesh3);
var mesh4 = new THREE.Mesh( geometry, material);
mesh4.position.x = 0;
mesh4.position.y = ( 150);
mesh4.position.z = ( 225);
mesh4.material.color = new THREE.Color( 0x4900FD );
var refy4 = mesh4.position.y;
var refz4 = mesh4.position.z;
scene.add(mesh4);


//Adding ligting for the scene.
var directionalLight1 = new THREE.DirectionalLight( 0xffffff, 0.8 );
directionalLight1.position.set( 100000, 1000, 0 );
scene.add( directionalLight1 );

//Initializing renderer.
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);

//Appending to body.
document.body.appendChild(renderer.domElement);

//Starting animation.
animateMotion(mesh3,mesh2,mesh4,refx2,refx3,refz3,refz4,refy4,refy2);
}

Now create the animateMotion function. This function is responsible for the motion of electrons around the nucleus of the atom.


function animateMotion (mesh3,mesh2,mesh4,refx2,refx3,refz3,refz4,refy4,refy2) {
var i =0;
setInterval(function(){
if(i===360)i=0;
mesh3.position.x = refx3*Math.cos(i);
mesh3.position.z = refz3*Math.sin(i);
mesh2.position.x = refx2*Math.cos(i);
mesh2.position.y = refy2*Math.sin(i);
mesh4.position.y = refy4*Math.sin(i);
mesh4.position.z = refz4*Math.cos(i);
i=i+0.04;
render();
},5);
}

Each electron moves in a circular motion on separate x-y, x-z and y-z axis. The motion is achieved by updating the variables by setting them to cosine and sine of values from 0 to 360 in a loop.  

Add main.js file to index.html.


<html>
<body>
<script src="scripts/three.min.js"></script>
<script src="scripts/TrackballControls.js"></script>
        <script src="scripts/main.js"></script>
</body></html>


Step3: Run.



$ node app.js



  Working Demo:  http://comicatom.herokuapp.com/