angular - ThreeJS/Angular - "scene is undefined"

标签 angular three.js

我刚刚发现 ThreeJS,并尝试使用 ThreeJS 的 OBJLoader 加载 .obj 文件。

不幸的是,我收到错误

Cannot read property 'scene' of undefined

此错误是在 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 );
  }

}

提前感谢您的帮助

最佳答案

这是因为objLoader.load回调函数中的this引用的是onload函数,而不是类实例。

解决此问题的一种方法是将 this 实例化为 createScene 函数中的变量,然后在加载函数中使用该变量而不是 this:

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' );

  }
);

希望有所帮助。

关于angular - ThreeJS/Angular - "scene is undefined",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54207186/

相关文章:

javascript - Angular 2 eventEmitter 不起作用

javascript - 父子操纵之间的共享值(value)

javascript - 三.JS FPS控制左右扫射

javascript - Collada 到 JSON

javascript - threejs限制一行的长度

css - Primeng Datatable - 在该行中单击按钮时如何向特定 tr 元素添加样式

javascript - Angular 中的 d3.js - 属性 'event' 在类型 'typeof import 上不存在

javascript - Three.js:使全景中使用箭头键旋转变得平滑

javascript - 在将网格体添加到 Three.js 中的场景之前,如何设置网格体的位置

javascript - 以 Angular 2 格式化货币输入