import { PerspectiveCamera , Scene , Vector3 , WebGLRenderer } from "three" ; import { SceneColorTheme } from "../../../../classes/SceneColorTheme" ; import { lazyInject } from "../../../../inversify.config" ; import { HtmlDomService , Offset } from "../../../../services/HtmlDomService" ; import { Rectangle } from "../../domain/Rectangle" ; import { SoftVis3dShape } from "../../domain/SoftVis3dShape" ; import { Camera } from "./Camera" ; import SceneObjectCalculator from "./SceneObjectCalculator" ; import { Setup } from "./Setup" ; import { OrbitControls } from "@three-ts/orbit-controls" ; export default class SoftVis3dScene { public static CANVAS_ID = "softvis3dscene" ; public readonly scene : Scene ; public readonly camera : Camera ; @ lazyInject ( "HtmlDomService" ) private readonly htmlDomService ! : HtmlDomService ; private _width : number ; private _height : number ; private readonly renderer : WebGLRenderer ; private controls : any ; private animationId : null | number = null ; public constructor ( ) { const container = document . getElementById ( SoftVis3dScene . CANVAS_ID ) as HTMLCanvasElement ; this . _height = this . _width = 0 ; this . scene = new Scene ( ) ; this . renderer = new WebGLRenderer ( { canvas : container , antialias : true , alpha : true } ) ; Setup . initRenderer ( this . renderer , this . scene , container ) ; this . camera = new Camera ( container ) ; this . controls = new OrbitControls ( this . camera . getCamera ( ) , container ) ; this . onWindowResize ( ) ; window . addEventListener ( "resize" , ( ) => { this . onWindowResize ( ) ; } ) ; this . stopAnimation ( ) ; this . startAnimation ( ) ; } public destroy ( ) { this . stopAnimation ( ) ; } public setColorTheme ( colorTheme ) { this . renderer . setClearColor ( colorTheme . backgroundColor , 1 ) ; } public setCameraTo ( position ) { this . camera . setCameraPosition ( position . x , position . y , position . z ) ; } public getCamera ( ) { return this . camera . getCamera ( ) ; } public getCameraPosition ( ) { return this . camera . getCameraPosition ( ) ; } public getDefaultCameraPosition ( shapes ) { const platform = SceneObjectCalculator . findMaxDimension ( shapes ) ; return new Vector3 ( 0 , platform . length * 0.7 , platform . width * 0.7 ) ; } public resetControls ( ) { this . controls . reset ( ) ; } public get width ( ) { return this . _width ; } public get height ( ) { return this . _height ; } private stopAnimation ( ) { if ( this . animationId !== null ) { window . cancelAnimationFrame ( this . animationId ) ; this . animationId = null ; } } private startAnimation ( ) { if ( this . animationId === null ) { this . animate ( ) ; } } private animate ( ) { window . requestAnimationFrame ( this . animate . bind ( this ) ) ; this . renderer . render ( this . scene , this . getCamera ( ) ) ; } /**
     * Resizes the camera when document is resized.
     */ private onWindowResize ( ) { const sidebarWidth = this . htmlDomService . getWidthById ( "app-sidebar" ) ; const topbarHeight = this . htmlDomService . getHeightById ( "app-topbar" ) ; const appOffset = this . htmlDomService . getOffsetsById ( "app" ) ; const sonarFooter = document . getElementById ( "footer" ) ; const appWidth = this . htmlDomService . getWidthById ( "app" ) ; const result = SceneObjectCalculator . calculateDimensionOnResize ( sidebarWidth , topbarHeight , appOffset , sonarFooter , appWidth ) ; this . camera . setAspect ( result . width , result . length ) ; this . renderer . setSize ( result . width , result . length ) ; this . renderer . setViewport ( 0 , 0 , result . width , result . length ) ; this . _width = result . width ; this . _height = result . length ; } }