Angular-CLI &三JS [英] Angular-CLI & ThreeJS

查看:30
本文介绍了Angular-CLI &三JS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试添加适当的 npm 依赖项,以将三个添加到我的 Angular-CLI 项目中.过去几个月 CLI 变化如此之快,我一直找不到工作源.

这里有一些想法...

  • 附带脚本

    这是我的第一次尝试,只是将 添加到 index.html 文件中.但是,我在打字稿界面中使用 javascript 时遇到问题.

  • 网络包

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

  • 捆绑包

    这似乎是一个 hack,而且是一个糟糕的/冗长的.将捆绑添加到三个库中,以便可以解释角度 2.

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

解决方案

As of angular-cli 1.0.0:

  1. npm install 三 --save
  2. npm install @types/three --save-dev
  3. 在AppComponent.html中添加一个div元素:

  4. 在AppComponent.ts中导入three.js:import * as THREE from 'three';
  5. 使用 @ViewChild('rendererContainer') rendererContainer: ElementRef;
  6. 获取 div 元素的句柄
  7. 在构造函数/生命周期方法中进行必要的设置.注意:ViewChildngAfterViewInit 之前不可用.

完整的应用组件:

import {Component, ViewChild, ElementRef} from '@angular/core';从三"导入 * 为三;@成分({选择器:'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css']})导出类 AppComponent {@ViewChild('rendererContainer') rendererContainer: ElementRef;renderer = new THREE.WebGLRenderer();场景 = 空;相机 = 空;网格 = 空;构造函数(){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();}动画(){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:

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

您最终可能想要使用一些额外的脚本,例如加载器和控件.其中大部分还没有编写为模块,而是在加载时向 window 上的 THREE 命名空间添加功能.因此,我最终告诉 angular-cli 通过将以下内容添加到我的 .angular-cli.json 文件中来手动加载我的脚本:

<代码>{应用程序":[{脚本":[../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 文件没有为这些附加脚本定义任何类型.理想情况下,我想扩展现有的类型定义,但目前我只是通过将 declare const THREE: any 添加到我的顶部来避免对three.js 进行类型提示以解决错误使用three.js的文件.如果您找到了一种好方法来扩展 @types/three 中的现有定义,请反馈!

调整窗口大小:

在此期间,我还会提到调整 window 的大小可能会导致 光线投射(我用它来决定是否单击对象)不再正常工作.要解决此问题,只需执行以下操作:

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

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.

解决方案

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)
}

这篇关于Angular-CLI &amp;三JS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆