@@ -5,26 +5,27 @@ import {
5
5
ElementRef ,
6
6
HostListener ,
7
7
inject ,
8
+ OnInit ,
8
9
ViewChild ,
9
10
} 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' ;
11
12
import * as THREE from 'three' ;
12
13
13
14
@Component ( {
14
15
standalone : true ,
15
16
template : `
16
17
<ngt-group #cameras>
17
18
<ngt-perspective-camera
18
- [ref]="cameraPerspectiveRef"
19
+ #perspectiveCamera
19
20
[aspect]="store.get('viewport', 'aspect') * 0.5"
20
21
[near]="150"
21
22
[far]="1000"
22
23
[rotation]="[0, Math.PI, 0]"
23
24
/>
24
25
<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"
28
29
[top]="300"
29
30
[bottom]="-300"
30
31
[near]="150"
@@ -38,10 +39,10 @@ import * as THREE from 'three';
38
39
</ngt-mesh>
39
40
</ngt-group>
40
41
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 ]" />
43
44
44
- <ngt-mesh #whiteMesh >
45
+ <ngt-mesh #mesh >
45
46
<ngt-sphere-geometry *args="[100, 16, 8]" />
46
47
<ngt-mesh-basic-material [wireframe]="true" />
47
48
@@ -59,128 +60,129 @@ import * as THREE from 'three';
59
60
imports : [ NgtArgs ] ,
60
61
schemas : [ CUSTOM_ELEMENTS_SCHEMA ] ,
61
62
} )
62
- export class Scene implements AfterViewInit {
63
+ export class Scene implements AfterViewInit , OnInit {
63
64
readonly Math = Math ;
64
65
65
- readonly cameraPerspectiveRef = injectNgtRef < THREE . PerspectiveCamera > ( ) ;
66
- readonly cameraOrthographicRef = injectNgtRef < THREE . OrthographicCamera > ( ) ;
67
-
68
66
readonly store = inject ( NgtStore ) ;
69
67
68
+ @ViewChild ( 'perspectiveCamera' , { static : true } ) perspectiveCamera ! : ElementRef < THREE . PerspectiveCamera > ;
69
+ @ViewChild ( 'orthographicCamera' , { static : true } ) orthographicCamera ! : ElementRef < THREE . OrthographicCamera > ;
70
70
@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 > ;
73
72
74
- @ViewChild ( 'whiteMesh' , { static : true } ) whiteMesh ! : ElementRef < THREE . Mesh > ;
73
+ @ViewChild ( 'perspectiveHelper' ) perspectiveHelper ?: ElementRef < THREE . CameraHelper > ;
74
+ @ViewChild ( 'orthographicHelper' ) orthographicHelper ?: ElementRef < THREE . CameraHelper > ;
75
75
76
76
readonly vertices : number [ ] = [ ] ;
77
77
78
78
private activeCamera ?: THREE . Camera ;
79
79
private activeCameraHelper ?: THREE . CameraHelper ;
80
80
81
81
constructor ( ) {
82
+ injectBeforeRender ( this . onBeforeRender . bind ( this ) , 1 ) ;
83
+ }
84
+
85
+ ngOnInit ( ) {
82
86
for ( let i = 0 ; i < 10000 ; i ++ ) {
83
87
this . vertices . push ( THREE . MathUtils . randFloatSpread ( 2000 ) ) ; // x
84
88
this . vertices . push ( THREE . MathUtils . randFloatSpread ( 2000 ) ) ; // y
85
89
this . vertices . push ( THREE . MathUtils . randFloatSpread ( 2000 ) ) ; // z
86
90
}
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
+ }
123
92
124
- cameraGroup . lookAt ( mesh . position ) ;
93
+ ngAfterViewInit ( ) {
94
+ this . activeCamera = this . perspectiveCamera . nativeElement ;
95
+ this . activeCameraHelper = this . perspectiveHelper ?. nativeElement ;
96
+ }
125
97
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
+ }
127
110
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 ;
131
113
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 ;
133
122
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 ) ;
138
126
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 ) ;
143
129
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
+ }
152
149
}
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 ) ;
153
163
}
154
164
}
155
165
156
166
@Component ( {
157
167
standalone : true ,
158
168
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>
159
178
<div class="block h-full w-full bg-black">
160
179
<ngt-canvas
161
180
[sceneGraph]="SceneGraph"
162
181
[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] }"
169
183
(created)="onCreated($event)"
170
184
/>
171
185
</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>
184
186
` ,
185
187
imports : [ NgtCanvas ] ,
186
188
} )
0 commit comments