3D Components with AngularJs



3D Components with AngularJs

0 1


WebUnleashed-talk

Aysegul Yonet Creating 3D Components with AngularJS talk for WebUnleashed 2015 - Toronto, Canada

On Github Yonet / WebUnleashed-talk

3D Components with AngularJs

Created by Aysegul Yonet / @AysegulYonet

Slides: bit.ly/wu-threejs-angular

AnnieCannons.com

  • Three.js
  • AngularJS
  • Three.js + AngularJS = 3D components
Creating a scene with Three.js. AngularJS fundamentals. Anatomy of a component.

Tweet Migration

Github: github.com/Yonet/TweetMigration

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

  • Scene
  • Camera
  • Renderer
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.

3D objects

  • Geometry
  • Material
  • Mesh

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.

<div ng-app="">
	<p>1 + 2 = {{ 1 + 2 }}</p>
</div>

<div ng-app="">
	<input type="text" ng-model="name"> 
	<p>Hello {{name}}</p>
</div>

jsFiddle

It is nothing but an extended version of the HTML attributes with the prefix ng added to it.

Controllers

<div ng-app="myApp">
	<div ng-controller="mainController">
		<p>The answer is,{{ meaning }}</p>
	</div>
</div>

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.

<globe info="world"></globe>
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...
			}
		}
})

//Step 0

Example Repo

Follow the steps from branch step-0 to step-5

Angular 2

@Component({selector: 'globe'})
@View({template: '<h1>Hi {{ word.name }}</h1>'})
class MyAppComponent {
	constructor() {
		this.word = {name: 'earth'};
	}
}

Resources

THE END

Slides: bit.ly/wu-threejs-angular@AysegulYonet

3D Components with AngularJs Created by Aysegul Yonet / @AysegulYonet Slides: bit.ly/wu-threejs-angular AnnieCannons.com