Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Full Unthrottle
// Keep the tab busy with audio.
const audioCtx = new AudioContext();
const gainNode = audioCtx.createGain();
gainNode.gain.value = 0.1;
gainNode.connect(audioCtx.destination);
const oscillatorNode = audioCtx.createOscillator();
oscillatorNode.type = "square";
oscillatorNode.frequency.setValueAtTime(0.00001, audioCtx.currentTime);
oscillatorNode.connect(gainNode);
oscillatorNode.start();
// Hook rAF.
const origRequestAnimationFrame = requestAnimationFrame;
let timeoutID;
let rafID;
requestAnimationFrame = (c) => {
// If page is hidden, use a timer.
// Otherwise, use rAF.
if (document.hidden) {
timeoutID = setTimeout(c, 1);
} else {
rafID = origRequestAnimationFrame(c);
}
};
// Handle page visibility changes.
document.addEventListener("visibilitychange", handleVisibilityChange, false);
function handleVisibilityChange(e) {
// If page is hidden, cancel the rAF.
// Otherwise, cancel the timer.
if (document.hidden) {
if (rafID) {
rafID = cancelAnimationFrame(rafID);
}
animate();
} else {
if (timeoutID) {
timeoutID = clearTimeout(timeoutID);
}
animate();
}
}
// Yield to the Autoplay policy.
window.addEventListener(
"click",
() => {
audioCtx.resume();
}, {
once: true
}
);
@spite
Copy link
Author

spite commented Apr 9, 2021

animate is my function that steps, renders, and calls requestAnimationFrame:

function animate() {
  // do whatever
  requestAnimationFrame(animate);
}

YMMV

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment