Angular-CLI和ThreeJS

12
我一直在尝试添加正确的npm依赖项以将THREE添加到我的Angular-CLI项目中。由于CLI在过去几个月内变化如此迅速,我无法找到有效的源代码。
以下是一些想法...
1. 与脚本捆绑 这是我的第一次尝试,只需在index.html文件中添加即可。但是我无法使用typescript接口中的javascript。
2. Webpack 这是我的第二次尝试,但我遇到了几个文档问题。Angular-cli似乎没有一致的使用webpacks的方法。有四种不同的实现webpacks的方式。我无法使任何一个与THREE一起工作。
3. Bundles 这看起来像是一个hack,而且很差/冗长。它是将bundle添加到THREE库中,以便可以解释angular 2。
我仍在努力制作一个Angluar-CLI + THREE.js项目。如果在下周内没有进展,我可能会放弃angular-cli。非常感谢您提供的任何建议/来源。
1个回答

44
截至angular-cli 1.0.0:
  1. npm install three --save
  2. npm install @types/three --save-dev
  3. 在AppComponent.html中添加一个div元素:<div #rendererContainer></div>
  4. 在AppComponent.ts中导入three.js:import * as THREE from 'three';
  5. 使用@ViewChild('rendererContainer') rendererContainer: ElementRef;获取对div元素的引用。
  6. 在构造函数/生命周期方法中进行必要的设置。注意:直到ngAfterViewInit之后,ViewChild才可用。
完整的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);
    }
}

完整的 AppComponent.html:

<div #rendererContainer></div>

如果您想使用一些额外的脚本:
您可能最终想要使用一些额外的脚本,例如加载器和控件。这些大多数都没有被编写为模块,而是在加载时将功能添加到window上的THREE命名空间中。因此,我最终告诉angular-cli通过将以下内容添加到我的.angular-cli.json文件来手动加载我的脚本:
{
  "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"
      ],
      ...

请注意,您还需要处理的事实是,您的three.js @types文件没有为这些附加脚本定义任何类型。理想情况下,我希望扩展现有的类型定义,但暂时我只是放弃了对three.js的类型提示,通过在使用three.js的文件顶部添加declare const THREE: any来解决错误。如果您找到了一种好的方法来扩展来自@types/three的现有定义,请回报!
为了处理窗口大小调整:
顺便提一下,调整您的window大小可能会导致像raycasting(我用它来判断对象是否被点击)等问题不再正确工作。要解决此问题,只需执行以下操作:
@HostListener('window:resize', ['$event'])
onWindowResize(event) {
    this.renderer.setSize(event.target.innerWidth, event.target.innerHeight)
}

2
@EricScandora,关于额外脚本(如加载器和控件)的使用说明已经添加。如果有任何问题或需要进一步解答,请告知! - theblang
不幸的是,我无法使用three.js,它无法加载three:错误:(SystemJS)XHR错误(404未找到)加载http://localhost:3000/three - sancelot
@sancelot 我无法提供太多帮助,因为这个答案中的所有信息都与使用 angular-cli 有关,它使用 Webpack(而不是您似乎正在使用的 SystemJS)。 - theblang
这个很好用。我已经使用Angular4将其启动和运行了。难道没有通过Angular的Renderer2传递任何渲染的要求吗? - Wayne Riesterer
1
可能想在@types安装上加上--save-dev。 - Devin McQueeney
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接