截至angular-cli 1.0.0:
npm install three --save
npm install @types/three --save-dev
- 在AppComponent.html中添加一个div元素:
<div #rendererContainer></div>
- 在AppComponent.ts中导入three.js:
import * as THREE from 'three';
- 使用
@ViewChild('rendererContainer') rendererContainer: ElementRef;
获取对div元素的引用。
- 在构造函数/生命周期方法中进行必要的设置。注意:直到
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)
}
Webpack
(而不是您似乎正在使用的SystemJS
)。 - theblang