Angular-CLI 和 ThreeJS

标签 angular three.js angular-cli

我一直在尝试添加适当的 npm 依赖项以将三个添加到我的 Angular-CLI 项目中。由于过去几个月 CLI 的变化如此之快,我一直无法找到可用的源代码。

这里有一些想法......

  • 搭载脚本

    这是我的第一次尝试,简单地添加 <script src="three.js"></script>到 index.html 文件。但是,我在使用 typescript 界面中的 javascript 时遇到了问题。

  • 网络包

    这是我的第二次尝试,但我遇到了几个文档问题。 Angular-cli 似乎没有一致的方式来使用 webpack。有四种不同的方式来实现 webpack。我无法与三个一起工作。

  • bundle

    这看起来像是一个 hack,而且是一个糟糕/冗长的 hack。它将向三个库添加 bundle ,以便它可以被解释为 Angular 2。

我目前仍在致力于制作 Angluar-CLI + THREE.js 项目。如果我在下周看不到进展,我可能会放弃 angular-cli。任何建议/资源将不胜感激。

最佳答案

截至 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. 在构造函数/生命周期方法中进行必要的设置。注:ViewChildngAfterViewInit 之前不可用.

完整的 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>

如果您想使用一些额外的脚本:

您可能最终想要使用一些额外的脚本,例如加载程序和控件。其中大部分并未作为模块编写,而是向 THREE 添加了功能。 window 上的命名空间加载时。因此,我最终告诉 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 的类型提示,通过添加 declare const THREE: any 来绕过错误。到我使用 three.js 的文件的顶部。如果您找到一种好方法来扩展 @types/three 中的现有定义,请反馈!

调整窗口大小:

同时我还会提到调整您的 window 的大小会导致类似 raycasting 的事情(我用它来决定一个对象是否被点击)不再正常工作。要解决此问题,请执行以下操作:

@HostListener('window:resize', ['$event'])
onWindowResize(event) {
    this.renderer.setSize(event.target.innerWidth, event.target.innerHeight)
}

关于Angular-CLI 和 ThreeJS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40273300/

相关文章:

javascript - Angular 2+多部分表单验证,如何检查单个输入的有效性

javascript - 使用 Three.js 使对象部分透明

javascript - Angular CLI 在项目创建后添加 SASS

angular - 如何在 Angular 2+ 中的元素上调用 scrollIntoView

cordova - 在 Angular 2 + Cordova 应用程序中使用 Cordova 插件

Angular 5 路由正在重新加载整个页面

three.js - Threejs工具提示

three.js - Raycast 对象以使用 Three.js 启用鼠标单击事件

angular - 无法更新 Angular CLI

Angular cli : getting it ready for production