Animating with audio playback
Today I wanted to try animating text based on the time elapsed within an audio element. I was wondering if animating a transcript for a podcast could be an entertaining way to provide a more visual presentation for readers of a podcast's transcripts. Making animation an option and not a default would be how I would approach it. Adding in some animations could help add the podcasters' personalities to the transcripts. Now I just need to figure out how to load in a transcript to help with the animation process. What I did today was far too tedious and not ideal for a 30-plus minute podcast.
The words below should animate as the audio plays.
This is a test of the HTML audio element.
View the code:
HTML and JS
<section class="code-block">
<h5>The words below should animate as the audio plays.</h5>
<p id="audioTime" class="hide"> </p>
<audio id="audioPlayer" controls preload="auto">
<source src="https://jeremycaudle.com/ast/testaudio.mp3" type="audio/mpeg">
Your browser does not appear to support the <code>audio</code> element. I'm sorry. :(
</audio>
<p id="audio-transcript"><span id="wordThis">This</span> <span id="wordIs">is</span> <span id="wordA">a</span> <span id="wordTest">test</span> <span id="wordOf">of</span> <span id="wordThe">the</span> <span id="wordHTML">HTML</span> <span id="wordAudio">audio</span> <span id="wordElement">element</span>.</p>
</section>
<script>
/* Variables */
const audio = document.getElementById('audioPlayer');
let audioTime = document.getElementById('audioTime');
const wordThis = document.getElementById('wordThis');
const wordIs = document.getElementById('wordIs');
const wordA = document.getElementById('wordA');
const wordTest = document.getElementById('wordTest');
const wordOf = document.getElementById('wordOf');
const wordThe = document.getElementById('wordThe');
const wordHTML = document.getElementById('wordHTML');
const wordAudio = document.getElementById('wordAudio');
const wordElement = document.getElementById('wordElement');
let time = audio.currentTime;
/* Functions */
function clearWordStyles(object) {
wordThis.style.fontWeight = 300;
wordIs.style.fontWeight = 300;
wordA.style.fontWeight = 300;
wordTest.style.fontWeight = 300;
wordOf.style.fontWeight = 300;
wordThe.style.fontWeight = 300;
wordHTML.style.fontWeight = 300;
wordAudio.style.fontWeight = 300;
wordElement.style.fontWeight = 300;
}
/* Events */
audio.addEventListener('playing', (e) => {
audioTime.setAttribute('class', 'show');
audioTime.textContent=`Audio playback currently at: ${Number.parseFloat(time).toFixed(2)}`;
});
audio.addEventListener('play', (e) => {
console.log('Playback has started.')
});
audio.addEventListener('pause', (e) => {
console.log('Playback has paused.')
});
audio.addEventListener('timeupdate', (e) => {
time = audio.currentTime;
audioTime.textContent=`Audio playback currently at: ${Number.parseFloat(time).toFixed(2)}`;
if (time < 1.48) {
clearWordStyles();
} else if (time > 1.48 && time < 2.02){
clearWordStyles();
wordThis.style.fontWeight = 900;
} else if (time > 2.02 && time < 2.24){
clearWordStyles();
wordIs.style.fontWeight = 900;
} else if (time > 2.24 && time < 2.34){
clearWordStyles();
wordA.style.fontWeight = 900;
} else if (time > 2.34 && time < 3.01){
clearWordStyles();
wordTest.style.fontWeight = 900;
} else if (time > 3.01 && time < 3.25){
clearWordStyles();
wordOf.style.fontWeight = 900;
} else if (time > 3.25 && time < 3.5){
clearWordStyles();
wordThe.style.fontWeight = 900;
} else if (time > 3.5 && time < 4.53){
clearWordStyles();
wordHTML.style.fontWeight = 900;
} else if (time > 4.53 && time < 5.05){
clearWordStyles();
wordAudio.style.fontWeight = 900;
} else if (time > 5.05 && time < 6.2){
clearWordStyles();
wordElement.style.fontWeight = 900;
} else if (time > 6.2){
clearWordStyles();
}
});
</script>
CSS
section.code-block {
max-width: 30em;
margin: 1rem auto;
font-family: Helvetica, Arial, sans-serif;
padding: 1rem;
background-color: rgb(168, 230, 214);
border-radius: 1rem;
}
.code-block p, .code-block h5 {
text-align: center;
}
#audioTime {
color: red;
transition: opacity .5s ease-out, font-weight .125s ease-out;
z-index: 4;
}
audio {
width: 100%;
max-width: 30em;
margin-bottom: 1rem;
}
.hide {
opacity: 0;
}
.show {
opacity: 1;
}