import * as THREE from 'three' ; import { ElementRef , Injectable , NgZone , OnDestroy } from '@angular/core' ; @ Injectable ( { providedIn : 'root' } ) export class EngineService implements OnDestroy { private canvas : HTMLCanvasElement ; private renderer : THREE . WebGLRenderer ; private camera : THREE . PerspectiveCamera ; private scene : THREE . Scene ; private light : THREE . AmbientLight ; private cube : THREE . Mesh ; private frameId : number = null ; public constructor ( private ngZone ) { } public ngOnDestroy ( ) { if ( this . frameId != null ) { cancelAnimationFrame ( this . frameId ) ; } if ( this . renderer != null ) { this . renderer . dispose ( ) ; this . renderer = null ; this . canvas = null ; } } public createScene ( canvas ) { this . canvas = canvas . nativeElement ; this . renderer = new THREE . WebGLRenderer ( { canvas : this . canvas , alpha : true , antialias : true } ) ; this . renderer . setSize ( window . innerWidth , window . innerHeight ) ; this . scene = new THREE . Scene ( ) ; this . camera = new THREE . PerspectiveCamera ( 75 , window . innerWidth / window . innerHeight , 0.1 , 1000 ) ; this . camera . position . z = 5 ; this . scene . add ( this . camera ) ; this . light = new THREE . AmbientLight ( 0x404040 ) ; this . light . position . z = 10 ; this . scene . add ( this . light ) ; const geometry = new THREE . BoxGeometry ( 1 , 1 , 1 ) ; const material = new THREE . MeshBasicMaterial ( { color : 0x00ff00 } ) ; this . cube = new THREE . Mesh ( geometry , material ) ; this . scene . add ( this . cube ) ; } public animate ( ) { this . ngZone . runOutsideAngular ( ( ) => { if ( document . readyState !== 'loading' ) { this . render ( ) ; } else { window . addEventListener ( 'DOMContentLoaded' , ( ) => { this . render ( ) ; } ) ; } window . addEventListener ( 'resize' , ( ) => { this . resize ( ) ; } ) ; } ) ; } public render ( ) { this . frameId = requestAnimationFrame ( ( ) => { this . render ( ) ; } ) ; this . cube . rotation . x += 0.01 ; this . cube . rotation . y += 0.01 ; this . renderer . render ( this . scene , this . camera ) ; } public resize ( ) { const width = window . innerWidth ; const height = window . innerHeight ; this . camera . aspect = width / height ; this . camera . updateProjectionMatrix ( ) ; this . renderer . setSize ( width , height ) ; } }