Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular-CLI & ThreeJS

I have been trying to add the proper npm dependencies to add THREE to my Angular-CLI project. With CLI changing so rapidly in the past few months, I haven't been able to find working source.

Here are a few ideas...

  • Piggyback with scripts

    This was my first attempt, to simply add <script src="three.js"></script> to the index.html file. However I'm having trouble working with the javascript in the typescript interface.

  • Webpack

    This was my second attempt, but I ran into several documentation problems. Angular-cli doesn't seem to have a consistent way of using webpacks. There are four different ways of implementing webpacks. I wasn't able to get any working with THREE.

  • Bundles

    This seems like a hack, and a poor/lengthy one. It would be to add bundles to the THREE library so that it can be interpreted angular 2.

I'm still currently working on making a Angluar-CLI + THREE.js project. If I don't see progress in the next week, I may drop angular-cli. Any advice/sources would be greatly appreciated.

like image 531
KitCat Avatar asked Oct 26 '16 22:10

KitCat


People also ask

What is an Angular CLI?

The Angular CLI is a command-line interface tool that you use to initialize, develop, scaffold, and maintain Angular applications directly from a command shell.

Is Angular and Angular CLI same?

In a very simple words, Angular CLI is a command line interface for writing or easily setting/building up an angular application. Angular js - is a older version of Angular (version 1. x) which is a open-source JavaScript-based front-end web application framework.

Is Angular CLI required?

Angular CLI stands for Angular Command Line Interface. As the name implies, it is a command line tool for creating angular apps. It is recommended to use angular cli for creating angular apps as you don't need to spend time installing and configuring all the required dependencies and wiring everything together.

Does Angular CLI use node JS?

Angular CLI is essential for developing Angular JS apps. Moreover, angular JS happens to be a structural framework for developing dynamic web apps, which can be achieved if you hire Angular JS developers. While Angular CLI uses modules from node JS, HTML is utilized by Angular JS as the template language.


1 Answers

As of angular-cli 1.0.0:

  1. npm install three --save
  2. npm install @types/three --save-dev
  3. Add a div element in AppComponent.html: <div #rendererContainer></div>
  4. Import three.js in AppComponent.ts: import * as THREE from 'three';
  5. Get a handle to your div element with @ViewChild('rendererContainer') rendererContainer: ElementRef;
  6. Do the necessary setup in your constructor / lifecycle methods. Note: the ViewChild is not available until ngAfterViewInit.

Full AppComponent:

import {Component, ViewChild, ElementRef} from '@angular/core';
import * as THREE from 'three';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    @ViewChild('rendererContainer') rendererContainer: ElementRef;

    renderer = new THREE.WebGLRenderer();
    scene = null;
    camera = null;
    mesh = null;

    constructor() {
        this.scene = new THREE.Scene();

        this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
        this.camera.position.z = 1000;

        const geometry = new THREE.BoxGeometry(200, 200, 200);
        const material = new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: true});
        this.mesh = new THREE.Mesh(geometry, material);

        this.scene.add(this.mesh);
    }

    ngAfterViewInit() {
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.rendererContainer.nativeElement.appendChild(this.renderer.domElement);
        this.animate();
    }

    animate() {
        window.requestAnimationFrame(() => this.animate());
        this.mesh.rotation.x += 0.01;
        this.mesh.rotation.y += 0.02;
        this.renderer.render(this.scene, this.camera);
    }
}

Full AppComponent.html:

<div #rendererContainer></div>

If you want to use some of the additional scripts:

You may end up wanting to use some of the additional scripts, such as loaders and controls. Most of these haven't been written as modules, but instead add functionality to the THREE namespace on the window when loaded. Because of this I ended up telling the angular-cli to just load up my scripts manually by adding the following to my .angular-cli.json file:

{
  "apps": [
    {
      "scripts": [
        "../node_modules/tween.js/src/Tween.js",
        "../node_modules/three/build/three.js",
        "../node_modules/stats.js/build/stats.min.js",
        "../vendor/VRMLLoader.js",
        "../vendor/OrbitControls.js"
      ],
      ...

Note that you will also need to deal with the fact that your three.js @types file does not define any types for these additional scripts. Ideally I would like to extend the existing type definitions, but for the time being I am just foregoing type hinting for three.js to get around the errors by adding declare const THREE: any to the top of my files that use three.js. If you find a good way to instead extend the existing definitions from @types/three, please report back!

To handle resizing the window:

While I am at it I will also mention that resizing your window can cause things like raycasting (which I use to decide if an object is clicked) to not work correctly anymore. To fix this just do:

@HostListener('window:resize', ['$event'])
onWindowResize(event) {
    this.renderer.setSize(event.target.innerWidth, event.target.innerHeight)
}
like image 146
theblang Avatar answered Nov 09 '22 04:11

theblang