ThreeJS / Angular-“场景未定义”

时间:2019-01-15 21:35:37

标签: angular three.js

我只是发现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 );
  }

}

感谢您的帮助

1 个答案:

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

  }
);

希望有帮助。