Three.js
AngularJS
Three.js + AngularJS = 3D components
Creating a scene with Three.js. AngularJS fundamentals. Anatomy of a component.
Why Three.js?
Faster to write
Faster to learn
It is fast
Arms Globe
WebGL is the 3D API that allows access to full capabilities of GPU to create smooth 3D animations, like 2D Canvas API, it is all done through JS. Three.js is a library that provides commonly used objects and methods. 300 lines of code vs 20 lines. Intuitive, using best-practice engine techniques. Open sourced and great community.
3D scene with three.JS
To actually be able to display anything with Three.js, we need three things: A scene, a camera, and a renderer so we can render the scene with the camera.
var scene = new THREE.Scene();
A scene is a top level object that we need to add other 3D objects to. Basicly a stage.
Camera
//FoV, AR, NC, FC
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
There are a few different cameras in Three.js. Let's use a PerspectiveCamera. The first attribute is the field of view. The first attribute is the field of view.
The second one is the aspect ratio. You almost always want to use the width of the element divided by the height, or the image looks squished.
The next two attributes are the near and far clipping plane. What that means, is that objects further away from the camera than the value of far or closer than near won't be rendered.
Renderer
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
In addition to the WebGLRenderer we use here, Three.js comes with a few others, often used as fallbacks for users with older browsers or for those who don't have WebGL support for some reason.
In addition to creating the renderer instance, we also need to set the size at which we want it to render our app. It's a good idea to use the width and height of the area we want to fill with our game - in this case, the width and height of the browser window. For performance intensive games, you can also give setSize smaller values, like window.innerWidth/2 and window.innerHeight/2, for half the resolution. This does not mean that the game will only fill half the window, but rather look a bit blurry and scaled up.
Last but not least, we add the renderer element to our HTML document. This is a 'canvas' element the renderer uses to display the scene to us.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
And we have darkness. We need an object.
Geometry
//width, height, depth
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
Source Code
To create a cube, we need a BoxGeometry. This is an object that contains all the points (vertices) and fill (faces) of the cube.
For Sphere: radius, widthSegments, heightSegments.
Material
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
In addition to the geometry, we need a material to color it. Three.js comes with several materials, but we'll stick to the MeshBasicMaterial for now. All materials take an object of properties which will be applied to them. To keep things very simple, we only supply a color attribute of 0x00ff00, which is green. This works the same way that colors work in CSS or Photoshop (hex colors).
Mesh
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
The third thing we need is a Mesh. A mesh is an object that takes a geometry, and applies a material to it, which we then can insert to our scene, and move freely around.
By default, when we call scene.add(), the thing we add will be added to the coordinates (0,0,0). This would cause both the camera and the cube to be inside each other. To avoid this, we simply move the camera out a bit.
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
we're not actually rendering anything yet. For that, we need what's called a render loop.
Rendering
function render() {
requestAnimationFrame( render );
renderer.render( scene, camera );
}
render();
This will create a loop that causes the renderer to draw the scene 60 times per second. If you're new to animation, you might say "why don't we just create a setInterval? The thing is - we could, but requestAnimationFrame has a number of advantages. Perhaps the most important one is that it pauses when the user navigates to another browser tab, hence not wasting their precious processing power and battery life.
Animation
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
This will be run every frame (60 times per second), and give the cube a nice rotation animation. Basically, anything you want to move or change while the app is running has to go through the render loop.
Group
var group = new THREE.Object3D;
goup.add(cube);
group.add(sphere);
scene.add(group);
group.rotation.y += 0.1;
You can animate the group together. Child object will inherit the transformation, if they have their own transformation, transformations will be combined.
//example
What is AngularJS
Controllers
Directives
Services
Lot's of essential features like mobile gestures, animations, filtering, routing, data binding, security, internationalization, and beautiful UI components.
jsFiddle
It is nothing but an extended version of the HTML attributes with the prefix ng added to it.
Controllers
The answer is,{{ meaning }}
var app = angular.module("firstApp", []);
app.controller("MainController", function($scope){
//initial value
$scope.meaning = 42;
$scope.changeMeaning = function(){
$scope.meaning = Math.floor(Math.random() * 42);
};
})
jsFiddle
Controllers Set up the initial state of the $scope object.
Add behavior to the $scope object.
Directives
angular.module('myApp', [])
.directive('globe', function() {
return {
restrict: 'E',
template:'Name: {{customer.name}} Address: {{customer.address}}'
}
});
html, controller and a directive creates a component. Let's talk about how we create a custom component.
When you talk of directives, you will see an underlying scope alongside each directive. Data binding is an important element of directive declaration.
angular.module('myApp', [])
.controller('MainController', function($scope){
$scope.world = {name: 'earth'};
})
.directive('globe', function() {
return {
restrict: 'E',
scope: {
globe: '=info'
},
template:'Hello, {{globe.name}}'
}
})
jsFiddle
Linking function
angular.module('myApp', [])
.directive('globe', function() {
return {
restrict: 'E',
scope: {
globe: '=info'
},
templateUrl:'templates/globe.html',
link: function(element, attr, scope) {
//component functionality goes here...
}
}
})
Follow the steps from branch step-0 to step-5
Angular 2
@Component({selector: 'globe'})
@View({template: 'Hi {{ word.name }} '})
class MyAppComponent {
constructor() {
this.word = {name: 'earth'};
}
}