Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Integrating Angular js & three.js

5,462 views

Published on

Presentation outlining two different code patterns to integrate three.js and AngularJS.

Published in: Software
  • Be the first to comment

Integrating Angular js & three.js

  1. 1. Josh Staples @cubicleDowns blog.tempt3d.com github.com/cubicleDowns/ng-three-viewer
  2. 2. WHO? Software Engineer @ napofearth.com “Explore Music Visually” PRIVATE BETA (#ngmeetup)
  3. 3. TODAY 1. (v1) Angular & Three.js 3D Model Viewer 2. (v2) “Controller as” & prototypal Angular components 3. Grunt & Closure compilation approaches 4. (v3*) Scoped scene graph
  4. 4. WHY? Great pattern(s) with low barrier of entry & high productivity All web devs can easily be 3D web devs Isolate THREE code from Angular UI/UX code!
  5. 5. THREE WHAT? threejs.org three features ● Renderers ● Scene Graph ● Cameras ● Animation ● Lights ● Materials ● Shaders ● Objects ● Geometry ● Loaders ● Utilities ● Export/Import ● Support ● Examples ● WebVR ● DIYVR Started by Mr. Doob on April 23, 2010
  6. 6. ANGULAR WHO?
  7. 7. Demo v1 http://localhost:8000/v1/dist/
  8. 8. CONTROLLER AppController CONTROLLER FileLoaderController UI Elements and Controllers DIRECTIVE INCLUDE file-loader.html DIRECTIVE INCLUDE about.html DIRECTIVE INCLUDE chrome.html DIRECTIVE INCLUDE toolbar.html
  9. 9. CONTROLLER FileLoaderController Dependency Injections Across Angular Components CONTROLLER AppController DIRECTIVE select SERVICE StorageService SERVICE MessageBus FACTORY Viewer
  10. 10. Viewer.factory('ViewerFactory', … ) { init() home = new Viewer.Scene() animate () render () makeSelection () loadOBJMTL () loadGLTF () loadOBJ () loadJSON () scale () rotate () /** Translate the model along an axis * @param {number} x * @param {number} y * @param {number} z */ translate (x,y,z) home.wrangler.currentModel.position.set(x, y, z); CONTROLLER AppController ● init () ● rotate () ● scale () ● translate () SERVICE MessageBus DIRECTIVE select ● makeSelection () CONTROLLER FileLoaderController ● loadOBJMTL () ● loadGLTF () ● loadOBJ () ● loadJSON () Viewer Factory Interface
  11. 11. Viewer Factory Architecture Viewer Factory Singleton function init(params) { home = new Viewer.Scene(params); animate(); } Viewer.Scene() this.scene THREE.Scene() this.renderer THREE.WebGLRenderer() this.wrangler Viewer.Wrangler() function animate () { requestAnimationFrame(animate); render(); } this.setup Viewer.Setup() this.cameras Viewer.Cameras() this.controls THREE.OrbitControls() this.raycaster THREE.Raycaster()
  12. 12. USE CASE - User Click, Intersect 3D Model, Return Model Information Angular Directive, <canvas select> elem.on(tap, function(e) x = e.gesture.center.x; y = e.gesture.center.y; // creating NDC coordinates for ray intersection. mouseDown.x = (x / width) * 2 - 1; mouseDown.y = -(y / height) * 2 + 1; ViewerFactory.makeSelection(mouseDown); Viewer Factory, makeSelection makeSelection(mouse): Angular Controller/Factory $scope.$on(‘objectSelected’, function () { // Do Something. }); var vector = new THREE.Vector3( mouse.x, mouse.y, 1).unproject(home.cameras.liveCam); home.raycaster.set(home.cameras.liveCam.position, vector.sub(home.cameras.liveCam.position).normalize()); var intersected = home.raycaster.intersectObjects(home.wrangler.currentModel, true); MessageBus.trigger('objectSelected', intersected[0])
  13. 13. MOST PROFITABLE MOVIE?
  14. 14. MOST PROFITABLE MOVIE? THE SEQUEL!
  15. 15. STARRING “Controller as” & as ctrl Annotations as SNAFU
  16. 16. Sequel (v2) http://localhost:8000/v2/dist/
  17. 17. Controller as <div id="file-loader" ng-controller="FileLoaderController as loader" ng-show=”loader.visible”> <input type="text" ng-model="loader.data.obj" placeholder="obj file url"> <input type="text" ng-model="loader.data.name" placeholder="unique name"> <button ng-click="otherLoader.loadOBJMTL()">Load OBJ/MTL</button> <button ng-click="loader.loadSampleOBJMTL()">SAMPLE OBJ-MTL</button> Controller level scope :) <div id="file-loader" ng-controller="FileLoaderController" ng-show=”visible”> - - - <input type="text" ng-model="data.obj" placeholder="obj file url"> <input type="text" ng-model="data.mtl" placeholder="mtl file url"> <button ng-click="loadOBJMTL()">Load OBJ/MTL</button> <button ng-click="loadSampleOBJMTL()">SAMPLE OBJ-MTL</button> nearest scope :(
  18. 18. Service, !Factory Viewer.ViewerService .prototype init listeners animate render makeSelection loadOBJMTL loadOBJ loadGLTF loadJSON rotate translate scale ● No More Factories ○ closure pattern ● Instead, prototypal Service ○ ‘new’ and this ○ .bind() for callbacks ● Saves Memory, Time, Searches (sorry) ● Single Pattern For Everything! ● IMHO, the best way to code JS
  19. 19. /** @ngInject */ Viewer.ViewerService = function($timeout, MessageBus){ this.timeout = $timeout; this.MessageBus = MessageBus; }; Viewer.ViewerService.prototype.init = function (params){ this.home = new Viewer.Scene(params); this.MessageBus.trigger(‘app-ready’); animate(); }; Viewer.factory('ViewerFactory', ['MessageBus', function (MessageBus) function init () {} function makeSelection() {} return { init: init, makeSelection: makeSelection } closure style, ng-annotate : prototypal :) Prototypal Angular
  20. 20. CAonnntorotallteior nass /** Service which initiates the THREE.js scene and * provides methods to interact with that scene * * @param {angular.$timeout} $timeout * @param {!Viewer.MessageBus} MessageBus * @constructor * @ngInject */ Viewer.ViewerService = function($timeout, MessageBus){ this.timeout = $timeout; this.MessageBus = MessageBus; }; /** * Translate the model along an axis * @param {number} x * @param {number} y * @param {number} z */ Viewer.ViewerService.prototype.translate = function(x, y, z){ this.home.wrangler.currentModel.position.set(x, y, z) }; /** * @param {number} s */ Viewer.ViewerService.prototype.scale = function(s) { this.home.wrangler.currentModel.scale.set(s, s, s); }; The Closure Compiler can use data type information about JavaScript variables to provide enhanced optimization and warnings.
  21. 21. APP INIT (app.js) angular.module('ThreeViewer', ['ngHammer', 'ngRoute', 'LocalStorageModule']) .config(['localStorageServiceProvider',function(localStorageServiceProvider){ …. .config(['$locationProvider', function($locationProvider) { …. $locationProvider.html5Mode(true); .config(['$routeProvider', function($routeProvider){ angular.module('ThreeViewer', ['ngRoute', 'LocalStorageModule']) .config(ThreeViewer.ConfigLocation) …. .directive('select', ['ViewerService', ThreeViewer.SelectDirective.factory]) …. .filter('forceInt', ThreeViewer.ForceInt.factory) …. .service('ViewerService', [MessageBus', ThreeViewer.ViewerService]) …. .controller('AppController', ['$scope', 'ViewerService', ThreeViewer.AppController]); v2 :) v1 :
  22. 22. uglify: { ng3: { options: { compress: { drop_console: true }, sourceMap: true, }, files: { 'dist/app.min.js': ['<%= concat.ng3.dest %>'] } } }, command: 'java -jar closure/compiler.jar ' + '--compilation_level SIMPLE_OPTIMIZATIONS' + '--language_in ECMASCRIPT5_STRICT ' + '--angular_pass ' + '--externs closure/externs/angular-1.3.js ' + '--externs closure/externs/three.js ' + '--generate_exports ' + '--manage_closure_dependencies ' + '--js closure/library/base.js ' + '--js <%= app %> ' + '--js <%= ng %> ' + '--js <%= three %> ' + '--js_output_file dist/app.min.js' Minify or Closure Compilation? Closure Compiler ● type checking ● ngInject ● goog.provide / require Grunt ng-annotate ● uglify ● ng-annotate
  23. 23. NOGN Eto A TPHPR, ETEWO PATTERNS V1 ● Most Common Angular Pattern ● Grunt uglify / minify ● Factories ● Services ● Filters ● Directives ● Init controllers from DOM V2 ● Prototypal Pattern for Everything! ● Bridge to Angular 2.0 ● Controller as (local scope) ● Closure Compilation ○ type checking ○ -- angular_pass ○ dependency chains ○ minification ● App.js Initialization ● No closure pattern (factories)
  24. 24. JNOGIN t oU TSH! REE Mobile Developer - Backend Guru napofearth.com/jobs UI/UX Designer - QA #ngmeetup

×