使用Three.js STL加载器与angular

Raz*_*ger 1 three.js angular

我正在尝试获取一个简单的画布以在一个有角度的项目上加载一个简单的stl文件,并且似乎无法使其工作...

我尝试了许多指南,但似乎没有任何效果。在将本机javascript与相同类型的代码一起使用时,效果很好。

<canvas #myCanvas></canvas>在HTML中有一个带有viewchild的画布:

在我的.ts文件中:

import {Component, ViewChild, AfterViewInit} from '@angular/core';
import * as THREE from 'three';
var OrbitControls = require('three-orbit-controls')(THREE)
var STLLoader = require('three-stl-loader')(THREE)
var loader = new STLLoader()
import Scene = THREE.Scene;
import Mesh = THREE.Mesh;
import PerspectiveCamera = THREE.PerspectiveCamera;
import WebGLRenderer = THREE.WebGLRenderer;
import TrackballControls = THREE.TrackballControls;
import {log} from "util";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit{
  ngAfterViewInit(): void {
    this.myCanvas.nativeElement.style.background = "grey";
    this.myCanvas.nativeElement.style.width="1000px"
    this.myCanvas.nativeElement.style.height="500px"
  }

  @ViewChild("myCanvas") myCanvas;
  private scene: Scene;
  private camera: PerspectiveCamera;
  private renderer: WebGLRenderer;
  private controls: TrackballControls;
  title = 'app works!';
  constructor(){
    this.init3D();
  }
  init3D(){
    log("init3D")
    // renderer
    this.renderer = new THREE.WebGLRenderer({alpha: true, canvas: this.myCanvas});
    log(""+window.innerWidth+" "+ window.innerHeight )
    this.renderer.setSize( window.innerWidth, window.innerHeight );

    // scene
    this.scene = new THREE.Scene();
    this.scene.background = new THREE.Color( 0xFFFFFF );

    // camera
    this.camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 0.01, 10000 );

    this.camera.position.set( 113, 111, 113 );
    this.scene.add( new THREE.AmbientLight( 0x222222 ) );

    this.scene.add( this.camera ); // required, because we are adding a light as a child of the camera

    // controls
    this.controls = OrbitControls;

    // lights

    var light = new THREE.PointLight( 0xffffff, 0.8 );
    this.camera.add( light );

    loader.load('./assets/plate.stl', geometry => {
      var material = new THREE.MeshNormalMaterial()
      var mesh = new THREE.Mesh(geometry, material)
      log(this.scene.toJSON())
      this.scene.add(mesh)
    })

    this.animate();

    window.addEventListener( 'resize', this.onWindowResize, false );
  }

  animate() {

    window.requestAnimationFrame(_ => this.animate());

    this.camera.lookAt( this.scene.position );

    this.renderer.render(this.scene, this.camera);

  }

  onWindowResize() {

    this.camera.aspect = window.innerWidth / window.innerHeight;

    this.camera.updateProjectionMatrix();

    this.renderer.setSize( window.innerWidth, window.innerHeight );

  }

}
Run Code Online (Sandbox Code Playgroud)

页面加载完成后,我没有收到任何错误,但画布中没有任何内容。我在这里想念什么?

Raz*_*ger 5

我可以运行它,如果将来有人需要它,我会发布一个有效的代码。

问题是我的画布尚未初始化,当我将3d初始化移动到“ ngAfterViewInit”时,它起作用了。

要使用您必须运行此安装的代码:

npm i --save three
npm i @types/three --save-dev 
npm i --save three-stl-loader
npm i --save three-orbit-controls
Run Code Online (Sandbox Code Playgroud)

在.html文件中:

<canvas #myCanvas></canvas>
Run Code Online (Sandbox Code Playgroud)

在.ts文件中:

import {Component, ViewChild, AfterViewInit, OnInit, Renderer2, Input} from '@angular/core';
import * as THREE from 'three';
var OrbitControls = require('three-orbit-controls')(THREE)
var STLLoader = require('three-stl-loader')(THREE)
var loader = new STLLoader()
import Scene = THREE.Scene;
import Mesh = THREE.Mesh;
import PerspectiveCamera = THREE.PerspectiveCamera;
import WebGLRenderer = THREE.WebGLRenderer;
import TrackballControls = THREE.TrackballControls;

@Component({
  selector: 'app-stl-loader',
  templateUrl: './stl-loader.component.html',
  styleUrls: ['./stl-loader.component.css']
})
export class StlLoaderComponent implements OnInit {

  @ViewChild("myCanvas") myCanvas:any;
  @Input()
  private path:string;
  private scene: Scene;
  private camera: PerspectiveCamera;
  private renderer: WebGLRenderer;
  private controls: any;

  ngOnInit(): void {
    //add listener for the resize of the window - will resize the renderer to fit the window
    let global = this.render.listen('window', 'resize', (evt) => {
      this.onWindowResize();
    })
  }

  ngAfterViewInit(): void {
    this.init3D();
  }
  constructor(private render: Renderer2){

  }
  init3D(){
    // renderer
    this.renderer = new THREE.WebGLRenderer({alpha: true, canvas:  this.myCanvas.nativeElement});
    this.renderer.setSize( window.innerWidth, window.innerHeight );

    // scene
    this.scene = new THREE.Scene();
    this.scene.background = new THREE.Color( 0xFFFFFF );

    // camera
    this.camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 0.01, 10000 );
    this.camera.position.set( 113, 111, 113 );
    this.camera.aspect = window.innerWidth / window.innerHeight;
    this.scene.add( new THREE.AmbientLight( 0x222222 ) );
    this.scene.add( this.camera ); // required, because we are adding a light as a child of the camera

    // controls
    this.controls = new OrbitControls(this.camera,this.renderer.domElement);

    // lights
    var light = new THREE.PointLight( 0xffffff, 0.8 );
    this.camera.add( light );

    loader.load(this.path, geometry => {
      var material = new THREE.MeshPhongMaterial( { color: 0xBEBEBE } );

      var mesh = new THREE.Mesh( geometry, material );
      this.scene.add(mesh)
    })

    //request animation
    this.animate();

  }

  /**
   * render the scene and request the window animation frame
   */
  animate() {

    this.camera.lookAt( this.scene.position );

    this.renderer.render(this.scene, this.camera);

    window.requestAnimationFrame(_ => this.animate());

  }

  /**
   * will resize the renderer and the camera to the right size of the window
   */
  onWindowResize() {

    this.camera.aspect = window.innerWidth / window.innerHeight;

    this.camera.updateProjectionMatrix();

    this.renderer.setSize( window.innerWidth, window.innerHeight );

  }

}
Run Code Online (Sandbox Code Playgroud)

STL文件的路径作为组件的输入给出。

拉兹