When the oncuechange event is triggered, it initiates a smooth fade-in/fade-out animation within the HTML P tag

Just starting out with web development and learning JavaScript. Trying to create a webpage that displays lyrics synced with an audio file inside a p tag. The subtitles are sourced from a vet file extension and I am using the "cuechange" event in JavaScript to inject the text into the p tag. Everything is working well so far, but I want to add a fade-in/fade-out animation effect for each sentence of the lyrics when the cue changes. I attempted to add a CSS animation directly to the p element, but it's not triggering with an event listener. Could someone offer guidance on this?

GitHub link: https://github.com/beatzonic/Audio-Lyrics-Subtitle

 document.getElementById('my_audio').textTracks[0].addEventListener('cuechange', function() {
    document.getElementById('lyric').innerText = this.activeCues[0].text;
    
});
body{
    
    margin: 0;
    padding: 0;
}


#lyrics_container{
    width: 100%;
    height: auto;
    padding: 30px;
    box-sizing: border-box;
}

p{
    
    font-size: 2em;
    color: red;
    font-weight: 600;

}



@keyframes fadein{
    
   0% {
        opacity:0;
    }
    100% {
        opacity:1;
    } 
    
}
    <div id="lyrics_container">

        
        <audio id="my_audio" controls>
          <source src="https://github.com/beatzonic/Audio-Lyrics-Subtitle/raw/master/in_case_you_didnt_know.mp3" type="audio/mpeg">
          <track id="sub" kind="subtitles" label="English subtitles" src="https://raw.githubusercontent.com/beatzonic/Audio-Lyrics-Subtitle/master/in_case_you_didnt_know.txt.vtt" srclang="en" default>
          Your browser does not support the audio tag.
        </audio>
        
        <p id="lyric" class="lyrics-class"></p>
        
    </div>
    

Answer №1

One possible approach is to create a function that can add a class and then remove it after a set amount of time. This code sample demonstrates how you can achieve this effect by adding a "transition" property to an element, applying the "is-animating" class, changing the content midway through the duration, and finally removing the "is-animating" class and transition property.

The function utilizes closures to ensure that any new animations requested while a previous one is still ongoing will cancel the previous animation to prevent overlapping transitions.

function createAnimation(element, duration) {
    let timeouts = [];

    return function(content) {
        if (timeouts.length > 0) {
            timeouts.forEach(timeout => clearTimeout(timeout));
            timeouts = [];
        }

        const halfDuration = duration / 2;
        element.style.transition = `opacity ${halfDuration}ms ease-in-out`;
        element.classList.add('is-animating');

        const firstTimeout = setTimeout(() => {
            element.textContent = content;
            element.classList.remove('is-animating');
        }, halfDuration);

        const secondTimeout = setTimeout(() => {
            element.style.transition = '';
        }, duration);

        timeouts.push(firstTimeout, secondTimeout);
    }
}

To use this function, call it with the desired element and total animation duration to create a specific animation effect that combines both fade in and fade out transitions.

Then, integrate this animation function into your event handling logic. When the "cuechange" event is triggered, ensure that the animateLyrics function is called with the updated text to animate the target element accordingly.

const trackElement = document.getElementById('sub');
const lyricElement = document.getElementById('lyric');
const animateLyrics = createAnimation(lyricElement, 500);

trackElement.addEventListener('cuechange', event => {
    animateLyrics(event.target.activeCues[0].text);
});

Lastly, in your CSS stylesheet, define how the browser should transition the element when the "is-animating" class is added, such as adjusting the opacity property.

#lyric.is-animating {
    opacity: 0;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the world of Typescript and Angular Filter functionalities

I am looking to utilize one of my Angular Filters in my controller as a function. I came across a solution on this page: How to use a filter in a controler The last answer provided exactly what I needed, so I implemented it in my JS code: var MyFunc ...

Discover the ins and outs of utilizing the Google+ Hangout API specifically for chatting purposes

I am currently working on a webpage and I want to include a hangout button that will allow users to connect with me and start chatting automatically when clicked. Here is the code I have so far: <script src="https://apis.google.com/js/platform.js" asy ...

Tips for successfully utilizing hyphens when passing an object property as an argument

Does anyone know how to pass an object property with a hyphen in it as an argument? I'm having trouble with this issue. Object { "section-id": 1, ... } HTML <div *ngFor="let section of sections" (trackScrollLeave)="leave(section.sectio ...

What is the process of using a For loop to output a string in reverse order?

I'm attempting to reverse the string "hello" using a For loop, aiming for the output of "olleh". However, I'm facing an issue where the last character in the string is not being removed after being added to the array. Consequently, only the last ...

Tips for setting the height of a div within a td to be 100%

I am struggling to make the orange divs in this example stretch out to match the height of the enclosing td element without explicitly setting the parent's height. I have tried using display: flex and align-items: stretch, but I can't seem to ach ...

Utilize HTML5 to enable fullscreen functionality for embedded SWF files

I have implemented a function that handles the click event of a button to toggle a DOM element into fullscreen mode. The function works well, but I am facing an issue when there is another div containing a swf inside the main div. var elem = document.getE ...

Using a <button> tag instead of a <div> inside of a <button> is not allowed, as clickable divs are typically frowned upon. What

I'm currently developing a React App that functions as a calendar, allowing users to click on specific days displayed as large squares to view information for that day. For accessibility purposes, I initially considered using <button> elements b ...

Troubleshooting the Issue of PHP Variables Not Being Assigned to Javascript Variables

I am currently struggling with an issue. I am trying to assign a PHP value to a variable in Javascript. Here is what I have attempted: <script> JSvariable = <?php echo $PHPvariable; ?>; </script> However, this approach is not yieldi ...

Send a request to the uClassify API using the Node request module

I'm currently working on integrating the uClassify API into my Node project, but I'm encountering some issues with my code. Here's what I have so far: const req = JSON.stringify('Hello, my love!'); const options = { body: ...

React Native Router Flux encountered duplicate keys in two children

Version(s) react-native-router-flux v3.31.2 react-native v15.2.1 I am encountering an issue when trying to call Actions.dialog() multiple times and receiving an error message. Despite attempting the fix mentioned in https://github.com/aksonov/react-nat ...

What is the process for creating a global variable in JavaScript?

Having trouble changing the value of "invocation_num" within a loop? I attempted to modify it as follows, but ended up with an undefined value. Any help would be greatly appreciated. $(document).on("click", '.favoret', function(){ document ...

Tips for incorporating inline images with gatsby-image

Seeking Solution In my quest to query and showcase images with a maximum width of 350px, I am hoping to have them displayed inline-block for tablets and larger screens. Ideally, each image would sit next to one another and wrap if they exceed the parent d ...

Tips on automatically changing the background image every few seconds

As a newcomer to Angular and programming in general, I am facing an issue with changing the background image of my Page using the setInterval method. The intended behavior is for it to change every second, but for some reason, it changes much faster than t ...

Tips for maintaining consistent styles in CSS for multiple websites

I am currently working on developing a customizable chatbot widget using react. The goal is to create a chatbot widget that can be easily integrated into any website, similar to the functionality of rasa-webchat. During testing on some websites, I encount ...

Is it possible to implement dependency injection within a .css document?

I have a C# .NET 6 application. Some of the web pages (Razor Pages) in the app use dependency injection to inject configuration into the Razor Pages (.cshtml files), allowing certain config elements to be displayed in the user interface. My query is, can ...

Can OR be utilized within a find operation?

I am currently developing a social media platform similar to Facebook using Express and MongoDB. One of the features I'm working on is adding friends to user profiles. When a user clicks on a button that says "Send Friend Request" on another user&apos ...

How to design a dictionary schema using Mongoose

I have been attempting to save a dictionary of objects using Mongoose. Upon realizing that the change detection for saving is lost when using the Mixed type, I am looking for a way to create a schema that does not rely on the Mixed type. While there are m ...

Resizing and uploading multiple images with accompanying descriptions

I am in need of a solution for uploading multiple images along with descriptions. Users will be uploading 1-10 large-sized images from cameras, so it would be ideal if the images could be resized before the upload. My requirements are: Compatibility wit ...

Forming triangles with outlines

Recently, I had the challenge of designing speech bubbles and found a clever technique to create the triangular tip at the end using CSS. By setting the element's width and height to 0 and playing around with borders, you can achieve diagonal shapes f ...

What is the best way to target specific text within the DOM without including text within attributes?

We are currently displaying search results from various posts on our website, and we would like to highlight the search terms in the displayed content. Currently, we are implementing this functionality on the backend using PHP. We iterate through the post ...