I am using threejs in Angular 8. When I navigate to my 3D view page, I can put data into the 3D scene, but if I levave this page and come back, a second 3D scene is below the first. Every time I do this it keeps stacking 3D scenes in a scrollable page.
My desired results is to have the same 3D scene come back after visiting other pages within my app. Is this possible. Here is the blank skeleton of my component typescript file, minus routines to put data into my scene Group:
import { Component, OnInit, ViewChild, ElementRef, HostListener } from â@angular/coreâ;
import * as THREE from âthreeâ;
import { Line } from âthreeâ;
//import { OrbitControls } from âthree/examples/jsm/controls/OrbitControlsâ;
import { TrackballControls } from âthree/examples/jsm/controls/TrackballControlsâ;
import { DataService, TrajectoryWell, WellAndPick } from ââŚ/data.serviceâ;
@Component({
selector: âapp-threed-viewâ,
templateUrl: â./threed-view.component.htmlâ,
styleUrls: [â./threed-view.component.scssâ, ââŚ/app.component.cssâ]
})
export class ThreedViewComponent {
@ViewChild(ârendererContainerâ, { static: true }) rendererContainer: ElementRef;
showLoadingIndicator = false;
renderer = null;
scene: THREE.Scene;
camera = null;
//trackBallControler: THREE.TrackballControls;
light = null;
group: THREE.Group = null;
groupWidth;
groupDepth;
trackBallController;
mslGrid: THREE.GridHelper;
xOffset = 500.0;
yOffset = 0;
numWells: string = â2000â;
vScale: number = 10;
// This is a hack but set for MB field.
//initialGridWidth = 500000.0;
initialGridWidth = 25000.0;
trajectories: TrajectoryWell[];
tops: WellAndPick[];
constructor(private dataService: DataService) {
if (this.scene == null) {
// Create new scene
this.scene = new THREE.Scene();
// this.scene.background = new THREE.Color(0x999999);
this.scene.add(new THREE.AmbientLight(0x999999));
//this.controls = new THREE.TrackballControls( camera );
this.camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, .1, this.initialGridWidth * 3);
this.camera.up.set(0, 1, 0);
this.camera.rotateOnAxis(new THREE.Vector3(1, 0, 0), this.degInRad(45));
this.scene.add(this.camera);
this.mslGrid = new THREE.GridHelper(this.initialGridWidth, 50, 0xffffff, 0x555555);
this.scene.add(this.mslGrid);
this.camera.position.set(this.initialGridWidth / 2, 5, this.initialGridWidth / 2 + 5000);
// Now the renderer
this.renderer = new THREE.WebGLRenderer({ antialias: true });
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(this.renderer.domElement);
this.trackBallController = new TrackballControls(this.camera, this.renderer.domElement);
this.trackBallController.enableDamping = false;
this.trackBallController.enableZoom = true;
this.group = new THREE.Group();
this.scene.add(this.group);
this.animate();
}
}
@HostListener(âwindow:resizeâ, [â$eventâ])
onWindowResize(event) {
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
}
animate() {
window.requestAnimationFrame(() => this.animate());
this.camera.updateProjectionMatrix();
// this.renderer.setViewport(0, 0, window.innerWidth, window.innerHeight);
this.renderer.render(this.scene, this.camera);
// this.renderer.setSize( window.innerWidth, window.innerHeight );
// this.renderer.clearDepth(); // important!
this.trackBallController.update();
}
}
My HTML Code:
Load 3D View Data
<h4>Vertical Scale: {{vScale}}</h4>
<p-slider [(ngModel)]="vScale" [style]="{'width':'14em'}" [animate]="true" [min]="0.1" [max]="100.0" [step]="0.1" (onChange)="handleChange($event)"></p-slider>
<h4>Number of Wells</h4>
<input type="text" pInputText pKeyFilter="int" [(ngModel)]="numWells">
<button pButton type="button" (click)="LoadTops()" label="Load Tops" class="ui-button-success"></button>
</p-sidebar>
<div *ngIf="showLoadingIndicator" class="spinner"></div>