@@ -5,26 +5,27 @@ import {
55 ElementRef ,
66 HostListener ,
77 inject ,
8+ OnInit ,
89 ViewChild ,
910} from '@angular/core' ;
10- import { injectBeforeRender , injectNgtRef , NgtArgs , NgtCanvas , NgtState , NgtStore } from 'angular-three' ;
11+ import { injectBeforeRender , NgtArgs , NgtCanvas , NgtRenderState , NgtState , NgtStore } from 'angular-three' ;
1112import * as THREE from 'three' ;
1213
1314@Component ( {
1415 standalone : true ,
1516 template : `
1617 <ngt-group #cameras>
1718 <ngt-perspective-camera
18- [ref]="cameraPerspectiveRef"
19+ #perspectiveCamera
1920 [aspect]="store.get('viewport', 'aspect') * 0.5"
2021 [near]="150"
2122 [far]="1000"
2223 [rotation]="[0, Math.PI, 0]"
2324 />
2425 <ngt-orthographic-camera
25- [ref]="cameraOrthographicRef"
26- [left]="(0.5 * 600 * store.get('viewport', 'aspect')) / -2"
27- [right]="(0.5 * 600 * store.get('viewport', 'aspect')) / 2"
26+ #orthographicCamera
27+ [left]="(300 * store.get('viewport', 'aspect')) / -2"
28+ [right]="(300 * store.get('viewport', 'aspect')) / 2"
2829 [top]="300"
2930 [bottom]="-300"
3031 [near]="150"
@@ -38,10 +39,10 @@ import * as THREE from 'three';
3839 </ngt-mesh>
3940 </ngt-group>
4041
41- <ngt-camera-helper #perspective *args="[cameraPerspectiveRef.nativeElement ]" />
42- <ngt-camera-helper #orthographic *args="[cameraOrthographicRef.nativeElement ]" />
42+ <ngt-camera-helper #perspectiveHelper *args="[perspectiveCamera ]" />
43+ <ngt-camera-helper #orthographicHelper *args="[orthographicCamera ]" />
4344
44- <ngt-mesh #whiteMesh >
45+ <ngt-mesh #mesh >
4546 <ngt-sphere-geometry *args="[100, 16, 8]" />
4647 <ngt-mesh-basic-material [wireframe]="true" />
4748
@@ -59,128 +60,129 @@ import * as THREE from 'three';
5960 imports : [ NgtArgs ] ,
6061 schemas : [ CUSTOM_ELEMENTS_SCHEMA ] ,
6162} )
62- export class Scene implements AfterViewInit {
63+ export class Scene implements AfterViewInit , OnInit {
6364 readonly Math = Math ;
6465
65- readonly cameraPerspectiveRef = injectNgtRef < THREE . PerspectiveCamera > ( ) ;
66- readonly cameraOrthographicRef = injectNgtRef < THREE . OrthographicCamera > ( ) ;
67-
6866 readonly store = inject ( NgtStore ) ;
6967
68+ @ViewChild ( 'perspectiveCamera' , { static : true } ) perspectiveCamera ! : ElementRef < THREE . PerspectiveCamera > ;
69+ @ViewChild ( 'orthographicCamera' , { static : true } ) orthographicCamera ! : ElementRef < THREE . OrthographicCamera > ;
7070 @ViewChild ( 'cameras' , { static : true } ) cameraGroup ! : ElementRef < THREE . Group > ;
71- @ViewChild ( 'perspective' ) cameraPerspectiveHelper ?: ElementRef < THREE . CameraHelper > ;
72- @ViewChild ( 'orthographic' ) cameraOrthographicHelper ?: ElementRef < THREE . CameraHelper > ;
71+ @ViewChild ( 'mesh' , { static : true } ) mesh ! : ElementRef < THREE . Mesh > ;
7372
74- @ViewChild ( 'whiteMesh' , { static : true } ) whiteMesh ! : ElementRef < THREE . Mesh > ;
73+ @ViewChild ( 'perspectiveHelper' ) perspectiveHelper ?: ElementRef < THREE . CameraHelper > ;
74+ @ViewChild ( 'orthographicHelper' ) orthographicHelper ?: ElementRef < THREE . CameraHelper > ;
7575
7676 readonly vertices : number [ ] = [ ] ;
7777
7878 private activeCamera ?: THREE . Camera ;
7979 private activeCameraHelper ?: THREE . CameraHelper ;
8080
8181 constructor ( ) {
82+ injectBeforeRender ( this . onBeforeRender . bind ( this ) , 1 ) ;
83+ }
84+
85+ ngOnInit ( ) {
8286 for ( let i = 0 ; i < 10000 ; i ++ ) {
8387 this . vertices . push ( THREE . MathUtils . randFloatSpread ( 2000 ) ) ; // x
8488 this . vertices . push ( THREE . MathUtils . randFloatSpread ( 2000 ) ) ; // y
8589 this . vertices . push ( THREE . MathUtils . randFloatSpread ( 2000 ) ) ; // z
8690 }
87- injectBeforeRender ( ( { gl, size, scene, camera } ) => {
88- const r = Date . now ( ) * 0.0005 ;
89- const mesh = this . whiteMesh . nativeElement ;
90- const cameraGroup = this . cameraGroup . nativeElement ;
91- const cameraPerspective = this . cameraPerspectiveRef . nativeElement ;
92- const cameraPerspectiveHelper = this . cameraPerspectiveHelper ?. nativeElement ;
93- const cameraOrthographic = this . cameraOrthographicRef . nativeElement ;
94- const cameraOrthographicHelper = this . cameraOrthographicHelper ?. nativeElement ;
95-
96- mesh . position . x = 700 * Math . cos ( r ) ;
97- mesh . position . z = 700 * Math . sin ( r ) ;
98- mesh . position . y = 700 * Math . sin ( r ) ;
99-
100- mesh . children [ 0 ] . position . x = 70 * Math . cos ( 2 * r ) ;
101- mesh . children [ 0 ] . position . z = 70 * Math . sin ( r ) ;
102-
103- if ( cameraPerspective && cameraOrthographic && cameraPerspectiveHelper && cameraOrthographicHelper ) {
104- if ( this . activeCamera === cameraPerspective ) {
105- cameraPerspective . fov = 35 + 30 * Math . sin ( 0.5 * r ) ;
106- cameraPerspective . far = mesh . position . length ( ) ;
107- cameraPerspective . updateProjectionMatrix ( ) ;
108-
109- cameraPerspectiveHelper . update ( ) ;
110- cameraPerspectiveHelper . visible = true ;
111-
112- cameraOrthographicHelper . visible = false ;
113- } else {
114- cameraOrthographic . far = mesh . position . length ( ) ;
115- cameraOrthographic . updateProjectionMatrix ( ) ;
116-
117- cameraOrthographicHelper . update ( ) ;
118- cameraOrthographicHelper . visible = true ;
119-
120- cameraPerspectiveHelper . visible = false ;
121- }
122- }
91+ }
12392
124- cameraGroup . lookAt ( mesh . position ) ;
93+ ngAfterViewInit ( ) {
94+ this . activeCamera = this . perspectiveCamera . nativeElement ;
95+ this . activeCameraHelper = this . perspectiveHelper ?. nativeElement ;
96+ }
12597
126- gl . clear ( ) ;
98+ @HostListener ( 'document:keydown' , [ '$event' ] )
99+ onKeyDown ( { key } : KeyboardEvent ) {
100+ switch ( key . toLowerCase ( ) ) {
101+ case 'o' :
102+ this . activeCamera = this . orthographicCamera . nativeElement ;
103+ this . activeCameraHelper = this . orthographicHelper ?. nativeElement ;
104+ break ;
105+ case 'p' :
106+ this . activeCamera = this . perspectiveCamera . nativeElement ;
107+ this . activeCameraHelper = this . perspectiveHelper ?. nativeElement ;
108+ }
109+ }
127110
128- this . activeCameraHelper ! . visible = false ;
129- gl . setViewport ( 0 , 0 , size . width / 2 , size . height ) ;
130- gl . render ( scene , this . activeCamera ! ) ;
111+ private onBeforeRender ( { gl, size, camera, scene } : NgtRenderState ) {
112+ if ( ! this . activeCamera || ! this . activeCameraHelper ) return ;
131113
132- this . activeCameraHelper ! . visible = true ;
114+ const r = Date . now ( ) * 0.0005 ;
115+ // reassign shorthands
116+ const mesh = this . mesh . nativeElement ;
117+ const camGroup = this . cameraGroup . nativeElement ;
118+ const perspective = this . perspectiveCamera . nativeElement ;
119+ const perspectiveHelper = this . perspectiveHelper ?. nativeElement ;
120+ const orthographic = this . orthographicCamera . nativeElement ;
121+ const orthographicHelper = this . orthographicHelper ?. nativeElement ;
133122
134- gl . setViewport ( size . width / 2 , 0 , size . width / 2 , size . height ) ;
135- gl . render ( scene , camera ) ;
136- } , 1 ) ;
137- }
123+ mesh . position . x = 700 * Math . cos ( r ) ;
124+ mesh . position . z = 700 * Math . sin ( r ) ;
125+ mesh . position . y = 700 * Math . sin ( r ) ;
138126
139- ngAfterViewInit ( ) {
140- this . activeCamera = this . cameraPerspectiveRef . nativeElement ;
141- this . activeCameraHelper = this . cameraPerspectiveHelper ?. nativeElement ;
142- }
127+ mesh . children [ 0 ] . position . x = 70 * Math . cos ( 2 * r ) ;
128+ mesh . children [ 0 ] . position . z = 70 * Math . sin ( r ) ;
143129
144- @HostListener ( 'document:keydown' , [ '$event' ] )
145- onKeyDown ( event : KeyboardEvent ) {
146- if ( event . key . toLowerCase ( ) === 'o' ) {
147- this . activeCamera = this . cameraOrthographicRef . nativeElement ;
148- this . activeCameraHelper = this . cameraOrthographicHelper ?. nativeElement ;
149- } else if ( event . key . toLowerCase ( ) === 'p' ) {
150- this . activeCamera = this . cameraPerspectiveRef . nativeElement ;
151- this . activeCameraHelper = this . cameraPerspectiveHelper ?. nativeElement ;
130+ if ( perspective && orthographic && perspectiveHelper && orthographicHelper ) {
131+ if ( this . activeCamera === perspective ) {
132+ perspective . fov = 35 + 30 * Math . sin ( 0.5 * r ) ;
133+ perspective . far = mesh . position . length ( ) ;
134+ perspective . updateProjectionMatrix ( ) ;
135+
136+ perspectiveHelper . update ( ) ;
137+ perspectiveHelper . visible = true ;
138+
139+ orthographicHelper . visible = false ;
140+ } else {
141+ orthographic . far = mesh . position . length ( ) ;
142+ orthographic . updateProjectionMatrix ( ) ;
143+
144+ orthographicHelper . update ( ) ;
145+ orthographicHelper . visible = true ;
146+
147+ perspectiveHelper . visible = false ;
148+ }
152149 }
150+
151+ camGroup . lookAt ( mesh . position ) ;
152+
153+ gl . clear ( ) ;
154+
155+ this . activeCameraHelper . visible = false ;
156+ gl . setViewport ( 0 , 0 , size . width / 2 , size . height ) ;
157+ gl . render ( scene , this . activeCamera ) ;
158+
159+ this . activeCameraHelper . visible = true ;
160+
161+ gl . setViewport ( size . width / 2 , 0 , size . width / 2 , size . height ) ;
162+ gl . render ( scene , camera ) ;
153163 }
154164}
155165
156166@Component ( {
157167 standalone : true ,
158168 template : `
169+ <div class="absolute text-center text-white w-full top-0 left-0 text-xl">
170+ <a href="https://threejs.org" target="_blank" rel="noopener" class="underline"> three.js </a> -
171+ <a href="https://angular-threejs.netlify.app" target="_blank" rel="noopener" class="underline">
172+ Angular Three
173+ </a>
174+ - cameras
175+ <br />
176+ <b class="text-green-300">O</b> orthographic <b class="text-green-300">P</b> perspective
177+ </div>
159178 <div class="block h-full w-full bg-black">
160179 <ngt-canvas
161180 [sceneGraph]="SceneGraph"
162181 [gl]="{ alpha: false }"
163- [camera]="{
164- fov: 50,
165- near: 1,
166- far: 10000,
167- position: [0, 0, 2500]
168- }"
182+ [camera]="{ fov: 50, near: 1, far: 10000, position: [0, 0, 2500] }"
169183 (created)="onCreated($event)"
170184 />
171185 </div>
172- <div class="absolute text-center text-white w-full top-0 left-0 text-xl">
173- <a href="https://threejs.org" target="_blank" rel="noopener" class="underline">three.js</a> -<a
174- href="https://angular-threejs.netlify.app"
175- target="_blank"
176- rel="noopener"
177- class="underline"
178- >Angular Three</a
179- >
180- - cameras
181- <br />
182- <b class="text-green-300">O</b> orthographic <b class="text-green-300">P</b> perspective
183- </div>
184186 ` ,
185187 imports : [ NgtCanvas ] ,
186188} )
0 commit comments