使用具有角度的Three.js STL装载器

时间:2017-10-02 04:41:32

标签: angular three.js

我试图让一个简单的画布在角度项目上加载一个简单的stl文件,而且似乎无法让它工作......

我尝试过很多指南,似乎没什么用。当使用具有相同类型代码的原生javascript时,它可以很好地工作。

我的html中有一个带有viewchild:<canvas #myCanvas></canvas>的画布。

在我的.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 );

  }

}

我没有错误,但是当页面加载完毕时,我的画布中没有任何内容。 我在这里缺少什么?

2 个答案:

答案 0 :(得分:5)

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

问题是我的画布尚未初始化,当我将3d初始化移动到&#34; ngAfterViewInit&#34;它奏效了。

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

npm i --save three
npm i @types/three --save-dev 
npm i --save three-stl-loader
npm i --save three-orbit-controls
<。>在.html文件中:

<canvas #myCanvas></canvas>
<。>在.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 );

  }

}

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

拉​​兹

答案 1 :(得分:0)

ng-three-template 这个花花公子为angular + 3创建了一个模板。

使用该模板,您可以轻松地:

import {STLLoader} from 'three/examples/jsm/loaders/STLLoader';