1+ import * as THREE from "three" ;
2+ import { createRenderer } from "./renderer.js" ;
3+ import { createCamera , setupParallax , setupFocus } from "./camera.js" ;
4+ import { createScene } from "./scene.js" ;
5+
6+ const ZOOM_DIST = 5 ;
7+ const TWEEN_SPEED = 0.07 ;
8+
9+ export function main ( canvas ) {
10+
11+ // --- Initialisation ---
12+
13+ const renderer = createRenderer ( canvas ) ;
14+
15+ const { camera, basePosition } = createCamera ( canvas ) ;
16+
17+ const { scene, sun, planets } = createScene ( ) ;
18+
19+ const { targetOffset, currentOffset } = setupParallax ( canvas ) ;
20+
21+ const focus = setupFocus ( canvas , camera , planets , basePosition ) ;
22+
23+ const currentLookAt = new THREE . Vector3 ( 0 , 0 , 0 ) ;
24+ const origin = new THREE . Vector3 ( 0 , 0 , 0 ) ;
25+
26+
27+
28+ // --- Render loop ---
29+
30+ requestAnimationFrame ( render ) ;
31+
32+ function render ( ) {
33+
34+ updateScene ( ) ;
35+ updateCamera ( ) ;
36+ handleResize ( ) ;
37+
38+ renderer . render ( scene , camera ) ;
39+ requestAnimationFrame ( render ) ;
40+
41+
42+
43+ // --- Done! (the rest is defining these functions) ---
44+
45+
46+
47+ // Update the sun and planet motions, if not paused
48+ function updateScene ( ) {
49+
50+ rotateSun ( )
51+ advancePlanetOrbits ( )
52+
53+ function rotateSun ( ) {
54+ if ( ! focus . paused ) sun . rotation . y += 0.003 ;
55+ }
56+
57+ function advancePlanetOrbits ( ) {
58+ planets . forEach ( p => {
59+ if ( ! focus . paused ) p . angle += p . speed * 0.008 ;
60+
61+ p . mesh . position . set (
62+ Math . cos ( p . angle ) * p . orbitR ,
63+ Math . sin ( p . angle ) * p . tilt * p . orbitR * 0.18 ,
64+ Math . sin ( p . angle ) * p . orbitR
65+ ) ;
66+ p . mesh . rotation . y += 0.01 ;
67+ } ) ;
68+ }
69+
70+ }
71+
72+ // Update the camera by tweening if needed, otherwise (unless paused, which is part of tweeening) do the parallax thing
73+ function updateCamera ( ) {
74+
75+ updateFocusTarget ( ) ;
76+
77+ if ( focus . tweening && focus . cameraTarget && focus . lookAtTarget ) {
78+ updateCameraTween ( ) ;
79+ }
80+ else if ( ! focus . paused ) {
81+ updateCameraParallax ( ) ;
82+ }
83+
84+ function updateFocusTarget ( ) {
85+
86+ if ( ! focus . focusedPlanet ) return ;
87+
88+ const planetPosition = focus . focusedPlanet . mesh . position ;
89+ const planetDirection = planetPosition . clone ( ) . normalize ( ) ;
90+
91+ focus . cameraTarget = planetPosition . clone ( ) . add ( planetDirection . multiplyScalar ( focus . focusedPlanet . radius + ZOOM_DIST ) ) ;
92+ focus . cameraTarget . y += focus . focusedPlanet . radius * 0.8 ;
93+ focus . lookAtTarget = planetPosition . clone ( ) ;
94+
95+ }
96+
97+ function updateCameraTween ( ) {
98+
99+ camera . position . lerp ( focus . cameraTarget , TWEEN_SPEED ) ;
100+ currentLookAt . lerp ( focus . lookAtTarget , TWEEN_SPEED ) ;
101+ camera . lookAt ( currentLookAt ) ;
102+
103+ if ( camera . position . distanceTo ( focus . cameraTarget ) < 0.05 ) {
104+ focus . tweening = false ;
105+ } ;
106+
107+ }
108+
109+ function updateCameraParallax ( ) {
110+
111+ currentOffset . x += ( targetOffset . x - currentOffset . x ) * 0.13 ;
112+ currentOffset . y += ( targetOffset . y - currentOffset . y ) * 0.13 ;
113+
114+ camera . position . set (
115+ basePosition . x + currentOffset . x ,
116+ basePosition . y + currentOffset . y ,
117+ basePosition . z
118+ ) ;
119+
120+ currentLookAt . lerp ( origin , 0.1 ) ;
121+ camera . lookAt ( currentLookAt ) ;
122+
123+ }
124+ }
125+
126+ // Resize the canvas dimensions change, then update the camera so things don't get squashed
127+ function handleResize ( ) {
128+
129+ if ( resizeRendererToDisplaySize ( canvas , renderer ) ) {
130+ camera . aspect = canvas . clientWidth / canvas . clientHeight ;
131+ camera . updateProjectionMatrix ( ) ;
132+ }
133+
134+ function resizeRendererToDisplaySize ( canvas , renderer ) {
135+
136+ const width = canvas . clientWidth ;
137+ const height = canvas . clientHeight ;
138+ const needResize = canvas . width !== width || canvas . height !== height ;
139+
140+ if ( needResize ) {
141+ renderer . setSize ( width , height , false ) ;
142+ }
143+
144+ return needResize ;
145+
146+ }
147+
148+ }
149+
150+ }
151+
152+ }
0 commit comments