Skip to content

Commit b988ce2

Browse files
Merge pull request #108 from borgbackup/calm-starfield-fadeout
index2: fade the starfield out after the cube on Stop
2 parents 5083a54 + aefaac8 commit b988ce2

1 file changed

Lines changed: 32 additions & 8 deletions

File tree

index2.html

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,8 +1298,9 @@ <h2>Trusted by sysadmins, hoarders and the merely paranoid.</h2>
12981298
}
12991299

13001300
/* --- scroll-driven state --- */
1301-
/* calm: 0 = full animation, 1 = cube gone, chunks stopped, stars only */
1302-
const state = { progress: 0, mouseX: 0, mouseY: 0, calm: 0 };
1301+
/* calm: 0 = full animation, 1 = cube gone, chunks stopped, stars only
1302+
starFade: 0 = stars at full brightness, 1 = stars gone (no animation left) */
1303+
const state = { progress: 0, mouseX: 0, mouseY: 0, calm: 0, starFade: 0 };
13031304

13041305
window.addEventListener('pointermove', (e) => {
13051306
state.mouseX = (e.clientX / window.innerWidth - 0.5) * 2;
@@ -1371,6 +1372,9 @@ <h2>Trusted by sysadmins, hoarders and the merely paranoid.</h2>
13711372
sp.needsUpdate = true;
13721373
// barely-there lateral sway; bounded so the wrap plane stays behind the camera
13731374
stars.rotation.y = Math.sin(t * 0.05) * 0.04;
1375+
// second wind-down stage: once the cube is gone, the starfield fades to nothing
1376+
stars.material.opacity = 0.7 * (1 - state.starFade);
1377+
stars.visible = state.starFade < 0.999;
13741378

13751379
// lattice: home position pushed along explode direction by scroll
13761380
if (cubeGroup.visible) {
@@ -1435,14 +1439,34 @@ <h2>Trusted by sysadmins, hoarders and the merely paranoid.</h2>
14351439
renderer.setAnimationLoop(render);
14361440
}
14371441

1438-
/* --- stop button: wind the scene down to a calm starfield --- */
1442+
/* --- stop button: wind the scene down in two stages, then to nothing ---
1443+
stop: cube + chunks recede (as before), then the starfield fades out and
1444+
the render loop is parked, leaving no animated background at all.
1445+
resume: restart the loop, fade the stars back, then bring the cube back. */
14391446
const stopBtn = document.getElementById('stopBtn');
1447+
let stopped = false;
1448+
let windTween = null;
14401449
stopBtn.addEventListener('click', () => {
1441-
const toCalm = state.calm < 0.5;
1442-
stopBtn.textContent = toCalm ? 'Resume' : 'Stop';
1443-
stopBtn.setAttribute('aria-pressed', String(toCalm));
1444-
if (reduced) { state.calm = toCalm ? 1 : 0; render(); return; }
1445-
gsap.to(state, { calm: toCalm ? 1 : 0, duration: 2.8, ease: 'power2.inOut', overwrite: 'auto' });
1450+
stopped = !stopped;
1451+
stopBtn.textContent = stopped ? 'Resume' : 'Stop';
1452+
stopBtn.setAttribute('aria-pressed', String(stopped));
1453+
if (reduced) {
1454+
state.calm = state.starFade = stopped ? 1 : 0;
1455+
render();
1456+
return;
1457+
}
1458+
if (windTween) windTween.kill();
1459+
if (stopped) {
1460+
windTween = gsap.timeline()
1461+
.to(state, { calm: 1, duration: 2.8, ease: 'power2.inOut' })
1462+
.to(state, { starFade: 1, duration: 1.6, ease: 'power2.inOut',
1463+
onComplete: () => renderer.setAnimationLoop(null) });
1464+
} else {
1465+
renderer.setAnimationLoop(render); // wake the loop before reversing
1466+
windTween = gsap.timeline()
1467+
.to(state, { starFade: 0, duration: 1.0, ease: 'power2.out' })
1468+
.to(state, { calm: 0, duration: 2.8, ease: 'power2.inOut' });
1469+
}
14461470
});
14471471

14481472
// debugging/testing handle (this page is a prototype)

0 commit comments

Comments
 (0)