the room tone tries to start on load (plays where the browser allows, otherwise on the first tap) — the seed page is never silent for want of a gesture
shots / shots (push) Successful in 2m22s
shots / shots (push) Successful in 2m22s
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K6897PWcUEwHiqZMcVnNF6
This commit is contained in:
1 parent
131f3b255b
commit
8fc613ed20
1 file changed
+5
-2
+5
-2
@@ -647,13 +647,14 @@ function makeCrackle() {
|
||||
/* the bed: crackle whenever no music is playing. Decided from state, called whenever state changes. */
|
||||
function bed() {
|
||||
clearTimeout(crackle.timer);
|
||||
crackle.timer = setTimeout(() => { const want = state.primed && !state.playing && !state.holding && state.audio.paused; if (want) crackleOn(); else crackleOff(); }, 300);
|
||||
crackle.timer = setTimeout(() => { const want = !state.playing && !state.holding && state.audio.paused; if (want) crackleOn(); else crackleOff(); }, 300);
|
||||
}
|
||||
function crackleOn() {
|
||||
if (crackle.on || state.holding) return;
|
||||
crackle.el ||= makeCrackle(); crackle.on = true;
|
||||
const base = crackle.base ?? crackle.el.volume, t0 = performance.now();
|
||||
crackle.el.volume = 0; crackle.el.currentTime = 0; crackle.el.play().catch(() => {});
|
||||
crackle.el.volume = 0; crackle.el.currentTime = 0;
|
||||
crackle.el.play().catch(() => { crackle.on = false; clearInterval(crackle.ramp); }); // refused without a gesture: the first tap calls again
|
||||
clearInterval(crackle.ramp);
|
||||
crackle.ramp = setInterval(() => { const k = Math.min(1, (performance.now() - t0) / 600); if (!crackle.on) { clearInterval(crackle.ramp); return; } crackle.el.volume = base * k; if (k >= 1) clearInterval(crackle.ramp); }, 40);
|
||||
}
|
||||
@@ -675,11 +676,13 @@ function prime() {
|
||||
state.audio.play().then(() => { state.playing = true; state.primed = true; crackleOff(); setPlayIcon(); vizStart(); }).catch(() => { state.needTap = true; $("#cover").classList.add("tap"); });
|
||||
return;
|
||||
}
|
||||
if (!crackle.on) bed();
|
||||
if (state.primed || state.current || (state.audio.src && !state.audio.paused)) return;
|
||||
try { state.audio.src = SILENCE; const p = state.audio.play(); if (p && p.then) p.then(() => { state.primed = true; bed(); }).catch(() => {}); } catch {}
|
||||
try { crackle.el ||= makeCrackle(); if (!crackle.on) crackleOn(); } catch {}
|
||||
}
|
||||
for (const ev of ["pointerdown", "touchend", "keydown"]) document.addEventListener(ev, prime, { capture: true, passive: true });
|
||||
setTimeout(bed, 400); // the room tone, from the start where the browser lets it
|
||||
/* iOS routes sound through Web Audio the moment the element is wired to an analyser, and suspends Web Audio when
|
||||
the screen locks (and obeys the mute switch). So on iOS the cover pulses to the beat from the sheet instead,
|
||||
and the music stays a plain <audio> element that keeps playing in the background. */
|
||||
|
||||
Reference in new issue
Block a user