我只是发现ThreeJS,正在尝试使用ThreeJS的OBJLoader加载.obj文件。
不幸的是,我遇到一个错误
无法读取未定义的属性“场景”
此错误在行this.scene.add( object );
这是我的全部内容:
import { Component, OnInit } from '@angular/core';
import * as THREE from 'three';
import * as OBJLoader from 'three-obj-loader';
OBJLoader(THREE);
@Component({
selector: 'app-items-catalog',
templateUrl: './items-catalog.component.html',
styleUrls: ['./items-catalog.component.css']
})
export class ItemsCatalogComponent implements OnInit {
constructor() {
}
private canEleId = 'renderCanvas';
ngOnInit() {
this.createScene(this.canEleId);
this.animate();
}
canvas: HTMLCanvasElement;
private renderer: THREE.WebGLRenderer;
private camera: THREE.PerspectiveCamera;
private scene: THREE.Scene = new THREE.Scene();
private light: THREE.AmbientLight;
private cube: THREE.Mesh;
createScene(elementId: string): void {
//var scene = new THREE.Scene();
// The first step is to get the reference of the canvas element from our HTML document
this.canvas = <HTMLCanvasElement>document.getElementById(elementId);
this.renderer = new THREE.WebGLRenderer({
canvas: this.canvas,
alpha: true, // transparent background
antialias: true // smooth edges
});
this.renderer.setSize(window.innerWidth, window.innerHeight);
// create the scene
this.camera = new THREE.PerspectiveCamera(
75, window.innerWidth / window.innerHeight, 0.1, 1000
);
this.camera.position.z = 5;
this.scene.add(this.camera);
// soft white light
this.light = new THREE.AmbientLight( 0x404040 );
this.light.position.z = 10;
this.scene.add(this.light);
let geometry = new THREE.BoxGeometry(1, 1, 1);
let material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
this.cube = new THREE.Mesh( geometry, material );
//this.scene.add(this.cube);
/* HERE IS THE PART WHERE THE PROBLEM IS */
-----------------------------------------------------------------
const objLoader = new THREE.OBJLoader();
objLoader.setPath('../../assets/icon/threed/')
// objLoader
// var loader = new THREE.OBJLoader();
objLoader.load(
// resource URL
'helicopter.obj',
// called when resource is loaded
function ( object ) {
console.log(object);
object.position.y -= 60;
this.scene.add( object );
},
// called when loading is in progresses
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
function ( error ) {
console.log( 'An error happened' );
}
);
---------------------------------------------------------------
}
animate(): void {
window.addEventListener('DOMContentLoaded', () => {
this.render();
});
window.addEventListener('resize', () => {
this.resize();
});
}
render() {
requestAnimationFrame(() => {
this.render();
});
this.cube.rotation.x += 0.01;
this.cube.rotation.y += 0.01;
this.renderer.render(this.scene, this.camera);
}
resize() {
let width = window.innerWidth;
let height = window.innerHeight;
this.camera.aspect = width / height;
this.camera.updateProjectionMatrix();
this.renderer.setSize( width, height );
}
}
感谢您的帮助
答案 0 :(得分:0)
这是因为this
的回调函数中的objLoader.load
是指函数onload而不是类实例。
售卖此商品的一种方法是将this
实例化为createScene
函数中的变量,然后在加载函数中使用该变量代替它:
createScene(elementId: string): void {
let me = this;
...
objLoader.load(
// resource URL
'helicopter.obj',
// called when resource is loaded
function ( object ) {
console.log(object);
object.position.y -= 60;
me.scene.add( object );
},
...
);
}
另一种方法是使用箭头功能,其中this
将引用ItemsCatalogComponent
类:
objLoader.load(
// resource URL
'helicopter.obj',
// called when resource is loaded
( object ) => {
console.log(object);
object.position.y -= 60;
this.scene.add( object );
},
// called when loading is in progresses
( xhr ) => {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
( error ) => {
console.log( 'An error happened' );
}
);
希望有帮助。