BeamerReveal
view release on metacpan or search on metacpan
music-ideas.org view on Meta::CPAN
const iv = setInterval(() => {
audio.volume = Math.min(1, audio.volume + delta);
if (audio.volume === 1) clearInterval(iv);
}, stepTime);
}
function fadeOut(audio, ms = 2000) {
const steps = 30;
const stepTime = ms / steps;
const delta = audio.volume / steps;
const iv = setInterval(() => {
audio.volume = Math.max(0, audio.volume - delta);
if (audio.volume === 0) {
clearInterval(iv);
audio.pause();
audio.currentTime = 0;
audio.volume = 1; // reset for next play
}
}, stepTime);
}
// Example with Reveal slide change
Reveal.on("slidechanged", () => {
if (Reveal.getCurrentSlide().id === "stop-music") {
fadeOut(audio, 2500);
}
});
</script>
// advanced fading:
<audio id="bgm" src="music.mp3" preload="auto" loop></audio>
<script type="module">
const audio = document.getElementById("bgm");
const ctx = new AudioContext();
const source = ctx.createMediaElementSource(audio);
const gain = ctx.createGain();
source.connect(gain).connect(ctx.destination);
function fadeIn(ms = 2000) {
const now = ctx.currentTime;
gain.gain.setValueAtTime(0, now);
audio.play().catch(()=>{});
gain.gain.linearRampToValueAtTime(1, now + ms/1000);
}
function fadeOut(ms = 2000) {
const now = ctx.currentTime;
gain.gain.cancelScheduledValues(now);
gain.gain.setValueAtTime(gain.gain.value, now);
gain.gain.linearRampToValueAtTime(0, now + ms / 1000);
setTimeout(() => {
audio.pause();
gain.gain.value = 1; // reset
}, ms);
}
Reveal.on("slidechanged", () => {
if (Reveal.getCurrentSlide().id === "stop-music") {
fadeOut(2500);
}
});
</script>
// fade in : simple
( run in 0.835 second using v1.01-cache-2.11-cpan-7f9471e7e0a )