Template for integrating three.js with a Typescript framework like Ionic (v3).
Clone the respository, and open up a terminal/command prompt within the threeApp directory. Afterwards, run the npm & ionic commands in the terminal to install node modules and to build the ionic app. On successful build, the Ionic application should start in the OS' preferred browser.
Clone Repository
$ git clone https://github.com/mitevpi/ionic-threejs-template
$ cd threeApp
Download Packages & Start Web App
npm install
ionic serve
As seen on masteringionic.com, getting the scene to render and be visible can be a roundabout process.
Inside the main scene.ts file
import { ElementRef, ViewChild } from "@angular/core";
export class ThreeFbxLoader {
@ViewChild("domObj")
canvasEl: ElementRef;
private _ELEMENT: any;
private scene: THREE.Scene;
private camera: THREE.PerspectiveCamera;
// and so on and so forth for class set up...
// In the main void, reference the DOM element that the WebGL generated object will be assigned to.
this._ELEMENT = this.canvasEl.nativeElement;
Inside the scene.html file
<!-- somewhere outside of the header -->
<ion-content class="no-scroll">
<div #domObj></div>
</ion-content>
Inside the scene.scss file
scene-fbx-loader {
.no-scroll .scroll-content{
overflow: hidden;
}
}
Due to the generally sloppy nature of javascript development, you're going to encounter typescript errors when you try to run this template. This is because the three.js package relies on external modules, and although three.js has a corresponding @types/three npm package you can install, the external modules may or may not have corresponding @types packages.
Pay attention to typescript errors in the console, and try to go directly to the source in the node_modules/@types/three directory. For me, the error was on the VRDisplay module which is a part of Mozilla's WebVR Api, but also referenced in three.js.
There are a number of ways to get around these errors (which I'll try to document here), but the one I chose was to edit the offending .d.ts files. First, install available types by running the command:
npm i --save @types/three
If you run the application as-is, you'll likely get typescript errors without a successful build due to modules with missing types.
In the offending files, change any offending occurances (such as VRDisplay) from this:
setVRDisplay(display: VRDisplay): void;
To this:
setVRDisplay(display: any): void;
There's a good deal of three.js modules which are not part of the core library, even though intellisense will autocomplete them, and you'll find people using them on other code samples through the typical THREE namespace. There are a number of ways to inject these modules into your app.
Some of the more popular modules exist on npm for convenience.
Install via npm if available (see three-obj-loader).
OBJ Loader
npm i --save three-obj-loader
import * as THREE from "three";
import * as OBJLoader from "three-obj-loader";
// create loading manager
this.manager = new THREE.LoadingManager();
// create the obj loader object
private createObjLoader(): THREE.OBJLoader {
new OBJLoader(THREE);
var objLoader = new THREE.OBJLoader(this.manager);
return objLoader;
}
// load an obj file
public loadObj(scene: THREE.Scene): void {
this.objLoader.load("/assets/dishwasher.obj", function(object) {
scene.add(object);
object.position.y -= 60;
});
}
FBX Loader
npm i --save three-fbx-loader
import * as THREE from "three";
import * as FBXLoader from "three-fbx-loader";
// create loading manager and fbx loader
this.manager = new THREE.LoadingManager();
this.fbxLoader = new FBXLoader(this.manager);
// load a fbx scene file
private loadFbx(scene: THREE.Scene): void{
this.fbxLoader.load("/assets/chair.fbx", function (object3d) {
scene.add(object3d);
});
}
As the three.js example files show, you can reference the additonal modules directly from the .js files included in the original three.js repository.
// Script source: https://github.com/mrdoob/three.js/blob/dev/examples/js/controls/TrackballControls.js
import * as TrackballControls from "./trackball";
private controls: THREE.TrackballControls;
private createTrackballControls(camera: THREE.PerspectiveCamera): THREE.TrackballControls {
var controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [65, 83, 68];
controls.addEventListener("change", this._animate);
return controls;
}
Installed using the npm i --save
command
- three
- @types/three
- three-obj-loader
- three-fbx-loader
I've personally found this module useful in debugging and working with local content. In order to use it, it must be imported through the app.module.ts file
import { HttpModule } from "@angular/http";
@NgModule({
declarations: [
MyApp,
ThreeVanillaCube,
ThreeObjLoader,
ThreeFbxLoader
],
imports: [
BrowserModule,
HttpModule,
IonicModule.forRoot(MyApp)
],