我试图让一个简单的画布在角度项目上加载一个简单的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 );
}
}
我没有错误,但是当页面加载完毕时,我的画布中没有任何内容。 我在这里缺少什么?
答案 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';