Search code examples
javascripthtmljquerycssaudio

Trying to play mp3 on hover to match the text in this verse javascript


Code SandBox

  1. What i am trying to do is play the mp3 file on hover or on click and to match the mp3 file with the text provided and highlight it while paying the mp3 in sync with the text is that even possible in js?

I have tried a forloop , but that ends up in the quran playing on a loop and overlapping with when the user clicks it

I have tried the getBoundClient to match the user scroll with the mp3 file still no luck . which i used in an old project here is a demo , Demo

The aim is to match the mp3 file with the text , highlight and it play like its a telltale story for example like Quran Verse Example , when you press play it does that function , However i need it to be on hover and for 1 mp3 file not multiple like in this website

My question is Is that even possible on js or jquery? Thanks for you answer in advance and a beautiful day to everyone.

Tested Logics.

  1. Added The Animation Effect from the brothers answer down below
  2. Added another logic aswell for the playing the audio on hover
    onmouseover="this.play()" onmouseout="this.pause();this.currentTime=0;"

From Answer By Emil Hovhannisyan

  1. Added extra option to play the quran on click and on hovering the sound does not work with the span elements
// function to play the quran on click works!!!
    function playandLoopThroughQuranText() {
      const playmp3quran = document.getElementById("alduha__only").play();
      //console.log(playmp3quran);
    };

and passing that to the span

 <span id="quran__verse" type="button" onclick="playandLoopThroughQuranText()">.وَٱلضُّحَىٰ[1].</span>

4 . You can add another clicker functionality on 2nd click but that would require extra code

  1. The Problem with my code provided is that it plays it and shows the animation but does not sync it with the mp3 quran file however it works on click for highlighting , and works on hover for playing the mp3 quran or clicking the mp3 of the quran

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Quran Hover on text and play it too.</title>
  </head>

  <style>
    /*General */
    html {
      padding: 0;
      margin: 0;
      width: 100%;
    }

    span {
      font-size: 2rem;
    }
    span:hover {
      background-color: #1b8b00;
      background-image: linear-gradient(314deg, #1b8b00 0%, #a2d240 74%);
      border-radius: 28px;
      cursor: pointer;
      animation-play-state: running;
    }

    audio {
      justify-content: center;
      align-items: center;
      width: 100%;
      border-radius: 28px;
      background-color: #7ed6df;
      background-image: linear-gradient(315deg, #7ed6df 0%, #000000 74%);
    }
    audio :hover {
      justify-content: center;
      align-items: center;
      width: 100%;
      border-radius: 28px;
      background-color: #7f53ac;
      background-image: linear-gradient(315deg, #7f53ac 0%, #647dee 74%);
    }

    .highlight {
      background-color: yellow;
      border-radius: 28px;
    }

    /*Typography */

    .header__text {
      text-align: center;
    }
    small {
      text-align: center;
      padding: 5rem;
    }
    .code__tested {
      text-align: left;
      background-color: #130f40;
      background-image: linear-gradient(315deg, #130f40 0%, #000000 74%);
      color: white;
      padding: 5rem 5rem 5rem 5rem;
      grid-template-columns: 1fr;
      border-radius: 18px;
      max-height: 20vh;
      width: 100%;
    }

    .divider {
      padding: 1rem;
      box-shadow: 0.3rem 0.3rem 0.3rem 0.4rem black;
      background: transparent;
      background-image: transparent;
      border-radius: 28px;
      width: 100%;
      height: 100%;
      background-color: transparent;
      padding-top: 1rem;
      top: 0;
    }

    /*Modules */

    #quran__container {
      text-align: right;
      float: right;
      padding: 1.5rem;
      width: 100%;
      word-spacing: 1rem;
      color: white;
      border-radius: 28px;
      background-color: #51713a;
      background-image: linear-gradient(314deg, #51713a 0%, #000e21 74%);
      max-height: 100vh;
      min-height: 10vh;
      height: 100%;
      left: 50%;
    }

    .quran__verse__container {
      word-spacing: 5rem;
      word-break: break-all;
    }
  </style>
  <body>
    <h1 class="header__text">
      Play Quran on hover or click or both in mp3 and highlight it
    </h1>
    <small>
      The thing i want to understand if its possible to append the mp3 file to
      the text with the duration to match the text highlighted
    </small>

    <div class="divider"></div>
    <!--- 

       pause
    play
    playing
        ondurationchange="myFunction()"
        on duration change of the video/audio exceute a javascript function whis is going to be the function where we loop over the text in the verses.

  -->

    <div
      id="quran__container"
      role="button"
      tabindex="0"
      data-word-location="0"
      onclick="playandLoopThroughQuranText();"
    >
      <!-- data-nav-is-the-attribute-that-isloopedover-with-js-
    on hover 
    --->
      <audio
        controls
        anonymous
        id="alduha__only"
        preload="auto"
        src="https://www.al-hamdoulillah.com/coran/mp3/files/abderrahman-soudais/093.mp3"
        type="sound/mp3"
        onclick="playandLoopThroughQuranText();"
        onmouseover="this.play();"
        onmouseout="this.pause();this.currentTime=0;"
      >
        Quran Audio
      </audio>

      <span
        id="quran__verse"
        type="button"
        onclick="playandLoopThroughQuranText()"
      >
        .بِسْمِ ٱللَّهِ ٱلرَّحْمَـٰنِ ٱلرَّحِيمِ
      </span>

      <span
        data-nav="verse1"
        id="quran__verse"
        type="button"
        onclick="playandLoopThroughQuranText()"
      >
        .وَٱلضُّحَىٰ[1].
      </span>
      <span type="button" onclick="playandLoopThroughQuranText()">
        وَٱلَّيْلِ .إِذَا سَجَىٰ [2]
      </span>

      <span type="button" onclick="playandLoopThroughQuranText()">
        .مَا وَدَّعَكَ رَبُّكَ وَمَا قَلَىٰ [3]
      </span>

      <span type="button" onclick="playandLoopThroughQuranText()">
        وَلَلْـَٔاخِرَةُ .خَيْرٌۭ لَّكَ مِنَ ٱلْأُولَىٰ [4]
      </span>
      <span type="button" onclick="playandLoopThroughQuranText()">
        .[5] وَلَسَوْفَ يُعْطِيكَ رَبُّكَ فَتَرْضَىٰٓ
      </span>
      <span type="button" onclick="playandLoopThroughQuranText()">
        .أَلَمْ يَجِدْكَ يَتِيمًۭا فَـَٔاوَىٰ [6]
      </span>
      <span type="button" onclick="playandLoopThroughQuranText()">
        .[7]وَوَجَدَكَ ضَآلًّۭا فَهَدَىٰ
      </span>
      <span type="button" onclick="playandLoopThroughQuranText()">
        وَوَجَدَكَ عَآئِلًۭا فَأَغْنَىٰ [8].
      </span>
      <span type="button" onclick="playandLoopThroughQuranText()">
        فَأَمَّا ٱلْيَتِيمَ فَلَا .تَقْهَرْ[9]
      </span>
      <span type="button" onclick="playandLoopThroughQuranText()">
        .وَأَمَّا ٱلسَّآئِلَ فَلَا تَنْهَرْ[10]
      </span>
      <span type="button" onclick="playandLoopThroughQuranText()">
        وَأَمَّا .[11]بِنِعْمَةِ رَبِّكَ فَحَدِّثْ
      </span>
    </div>

    <br class="divider" />
  </body>

  <script>
    const quranVerseContainer = document.getElementsByClassName(
      "quran__container"
    );
    const pagequranversecontainer = document.getElementById(
      "quran__verse__container"
    );
    const quranVerse = document.getElementById("quran__verse");
    //debug
    //console.log("button pressed"); // do an action on click span
    //console.log(quranVerse); //gets the span itself
    //console.log(quranVerseContainer); //get back the HTML Div container with the span element as an HTML Collection
    const qvc0 = quranVerseContainer.item([0]);
    //console.log(qvc0);

    // function to play the quran on click works!!!
    function playandLoopThroughQuranText() {
      const playmp3quran = document.getElementById("alduha__only").play();
      //console.log(playmp3quran);
    }
    // function to pause the quran on click doest not work!!!.

    function pauseandLoopThroughQuranText() {
      const pausemp3quran = document.getElementById("alduha__only").pause();
    }

    const timings = [
      { start: 0, stop: 500 },
      { start: 500, stop: 1000 },
      { start: 1000, stop: 1500 },
      { start: 1500, stop: 2000 },
      { start: 2500, stop: 3000 },
      { start: 3000, stop: 3500 },
      { start: 3500, stop: 4000 },
      { start: 4000, stop: 4500 },
      { start: 4500, stop: 5000 },
      { start: 5000, stop: 5500 },
      { start: 6000, stop: 6500 },
      { start: 6500, stop: 7000 },
      { start: 7000, stop: 7500 },
      { start: 7500, stop: 8000 }
    ];

    const durations = timings.map((timing) => timing.stop - timing.start);

    const qurancontainer = document.getElementById("quran__container");
    const childArray = [...qurancontainer.children]; // To use array methods

    childArray.forEach((el, i) => {
      el.onclick = () => {
        el.classList.toggle("highlight");

        const nextWord = childArray[i + 1];

        setTimeout(() => {
          el.classList.toggle("highlight");
          if (!nextWord) return; // Last word
          nextWord.click();
        }, durations[i]);
      };
    });
  </script>

  <footer>
    <small>Made by Omar abdelrahman</small>
  </footer>
</html>

<!-- References
   ```
    1. [Surat Al Duha](https://quran.com/ad-duhaa)
    2. [Surat Al Duha Mp3](https://www.al-hamdoulillah.com/en/quran/mp3/surah-93.html)
    3. [HTMLCollection.length](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection/length)
    4.[Play mp3 file with javascript onClick](https://stackoverflow.com/questions/10766538/play-mp3-file-with-javascript-onclick)
    5. [how-to-auto-animate-text-highlight-in-css](https://stackoverflow.com/questions/64197241/how-to-auto-animate-text-highlight-in-css)
    6. [event_ondurationchange](https://www.w3schools.com/jsref/event_ondurationchange.asp)
    7. [MDN - Audio - ELement](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio)
    7.1 pause   Playback has been paused.
    7.2 play    Playback has begun.
    7.3 playing     Playback is ready to start after having been paused or delayed due to lack of data. 
    8. [HTMLMediaElement: timeupdate event](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/durationchange_event)
    9. [play audio with javascript loop Code Answer’s javascript by Bored Buzzard](https://www.codegrepper.com/code-examples/javascript/play+audio+with+javascript+loop%5C)
    10. [Dynamic-Landing-Page-Project -By Omar Abdelrahman](https://github.com/omarashzeinhom/Dynamic-Landing-Page-Project)
    ```
 11/[Guffa-Answer on JS-Fiddle For Do something on button 2nd click](https://jsfiddle.net/S9wQ2/)
    -->

References

  1. Surat Al Duha
  2. Surat Al Duha Mp3
  3. HTMLCollection.length
  4. Play mp3 file with javascript onClick
  5. how-to-auto-animate-text-highlight-in-css
  6. event_ondurationchange
  7. MDN - Audio - ELement
  8. HTMLMediaElement: timeupdate event
  9. play audio with javascript loop Code Answer’s javascript by Bored Buzzard
  10. Dynamic-Landing-Page-Project -By Omar Abdelrahman 11/Guffa-Answer on JS-Fiddle For Do something on button 2nd click

Solution

  • Finally Working Please check the snippet or codesandbox!!!.

    I Added my method of code for you ( this is just one way of doing it) , that's integrated with previous answers of this question its now working but only on click , i think you can figure it out how to do it on hover.

    1. Sync the Quran with Timings manually since that you need only 1 file
    const timings = [
          { start: 0, stop: 500 },
          { start: 500, stop: 1000 },
          { start: 1000, stop: 1500 },
          { start: 1500, stop: 2000 },
          { start: 2500, stop: 3000 },
          { start: 3000, stop: 3500 },
          { start: 3500, stop: 4000 },
          { start: 4000, stop: 4500 },
          { start: 4500, stop: 5000 },
          { start: 5000, stop: 5500 },
          { start: 6000, stop: 6500 },
          { start: 6500, stop: 7000 },
          { start: 7000, stop: 7500 },
          { start: 7500, stop: 8000 }
        ];
    

    Logic Tested

    1. Added The Animation Effect from the brothers answer down below
    2. Added another logic aswell for the playing the audio on hover
        onmouseover="this.play()" onmouseout="this.pause();this.currentTime=0;"
    
    

    From Answer By Emil Hovhannisyan

    1. Added extra option to play the quran on click and on hovering the sound does not work with the span elements
    // function to play the quran on click works!!!
        function playandLoopThroughQuranText() {
          const playmp3quran = document.getElementById("alduha__only").play();
          //console.log(playmp3quran);
        };
    

    and passing that to the span

     <span id="quran__verse" type="button" onclick="playandLoopThroughQuranText()">.وَٱلضُّحَىٰ[1].</span>
    

    4 . You can add another clicker functionality on 2nd click but that would require extra code

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Quran Hover on text and play it too.</title>
      </head>
    
      <style>
        /*General */
        html {
          padding: 0;
          margin: 0;
          width: 100%;
        }
    
        span {
          font-size: 2rem;
        }
        span:hover {
          background-color: #1b8b00;
          background-image: linear-gradient(314deg, #1b8b00 0%, #a2d240 74%);
          border-radius: 28px;
          cursor: pointer;
          animation-play-state: running;
        }
    
        audio {
          justify-content: center;
          align-items: center;
          width: 100%;
          border-radius: 28px;
          background-color: #7ed6df;
          background-image: linear-gradient(315deg, #7ed6df 0%, #000000 74%);
        }
        audio :hover {
          justify-content: center;
          align-items: center;
          width: 100%;
          border-radius: 28px;
          background-color: #7f53ac;
          background-image: linear-gradient(315deg, #7f53ac 0%, #647dee 74%);
        }
    
        .highlight {
          background-color: #1b8b00;
          background-image: linear-gradient(314deg, #1b8b00 0%, #a2d240 74%);
          border-radius: 28px;
        }
    
        /*Typography */
    
        .header__text {
          text-align: center;
        }
        small {
          text-align: center;
          padding: 5rem;
        }
        .code__tested {
          text-align: left;
          background-color: #130f40;
          background-image: linear-gradient(315deg, #130f40 0%, #000000 74%);
          color: white;
          padding: 5rem 5rem 5rem 5rem;
          grid-template-columns: 1fr;
          border-radius: 18px;
          max-height: 20vh;
          width: 100%;
        }
    
        .divider {
          padding: 1rem;
          box-shadow: 0.3rem 0.3rem 0.3rem 0.4rem black;
          background: transparent;
          background-image: transparent;
          border-radius: 28px;
          width: 100%;
          height: 100%;
          background-color: transparent;
          padding-top: 1rem;
          top: 0;
        }
    
        /*Modules */
    
        #quran__container {
          text-align: right;
          float: right;
          padding: 1.5rem;
          width: 100%;
          word-spacing: 1rem;
          color: white;
          border-radius: 28px;
          background-color: #51713a;
          background-image: linear-gradient(314deg, #51713a 0%, #000e21 74%);
          max-height: 100vh;
          min-height: 10vh;
          height: 100%;
          left: 50%;
        }
    
        .quran__verse__container {
          word-spacing: 5rem;
          word-break: break-all;
        }
      </style>
      <body>
        <h1 class="header__text">
          Play Quran on hover or click or both in mp3 and highlight it
        </h1>
        <small>
          The thing i want to understand if its possible to append the mp3 file to
          the text with the duration to match the text highlighted
        </small>
    
        <div class="divider"></div>
        <!--- 
    
           pause
        play
        playing
            ondurationchange="myFunction()"
            on duration change of the video/audio exceute a javascript function whis is going to be the function where we loop over the text in the verses.
    
      -->
    
        <div
          id="quran__container"
          role="button"
          tabindex="0"
          data-word-location="0"
          onclick="playandLoopThroughQuranText();"
        >
          <!-- data-nav-is-the-attribute-that-isloopedover-with-js-
        on hover 
        --->
          <audio
            controls
            anonymous
            id="alduha__only"
            preload="auto"
            src="https://www.al-hamdoulillah.com/coran/mp3/files/abderrahman-soudais/093.mp3"
            type="sound/mp3"
            onclick="playandLoopThroughQuranText();"
            onmouseover="this.play();"
            onmouseout="this.pause();this.currentTime=0;"
          >
            Quran Audio
          </audio>
    
          <span
            id="quran__verse"
            type="button"
            onclick="playandLoopThroughQuranText()"
          >
            .بِسْمِ ٱللَّهِ ٱلرَّحْمَـٰنِ ٱلرَّحِيمِ
          </span>
    
          <span
            data-nav="verse1"
            id="quran__verse"
            type="button"
            onclick="playandLoopThroughQuranText()"
          >
            .وَٱلضُّحَىٰ[1].
          </span>
          <span type="button" onclick="playandLoopThroughQuranText()">
            وَٱلَّيْلِ .إِذَا سَجَىٰ [2]
          </span>
    
          <span type="button" onclick="playandLoopThroughQuranText()">
            .مَا وَدَّعَكَ رَبُّكَ وَمَا قَلَىٰ [3]
          </span>
    
          <span type="button" onclick="playandLoopThroughQuranText()">
            وَلَلْـَٔاخِرَةُ .خَيْرٌۭ لَّكَ مِنَ ٱلْأُولَىٰ [4]
          </span>
          <span type="button" onclick="playandLoopThroughQuranText()">
            .[5] وَلَسَوْفَ يُعْطِيكَ رَبُّكَ فَتَرْضَىٰٓ
          </span>
          <span type="button" onclick="playandLoopThroughQuranText()">
            .أَلَمْ يَجِدْكَ يَتِيمًۭا فَـَٔاوَىٰ [6]
          </span>
          <span type="button" onclick="playandLoopThroughQuranText()">
            .[7]وَوَجَدَكَ ضَآلًّۭا فَهَدَىٰ
          </span>
          <span type="button" onclick="playandLoopThroughQuranText()">
            وَوَجَدَكَ عَآئِلًۭا فَأَغْنَىٰ [8].
          </span>
          <span type="button" onclick="playandLoopThroughQuranText()">
            فَأَمَّا ٱلْيَتِيمَ فَلَا .تَقْهَرْ[9]
          </span>
          <span type="button" onclick="playandLoopThroughQuranText()">
            .وَأَمَّا ٱلسَّآئِلَ فَلَا تَنْهَرْ[10]
          </span>
          <span type="button" onclick="playandLoopThroughQuranText()">
            وَأَمَّا .[11]بِنِعْمَةِ رَبِّكَ فَحَدِّثْ
          </span>
        </div>
    
        <br class="divider" />
      </body>
    
      <script>
        const quranVerseContainer = document.getElementsByClassName(
          "quran__container"
        );
        const pagequranversecontainer = document.getElementById(
          "quran__verse__container"
        );
        const quranVerse = document.getElementById("quran__verse");
        //debug
        //console.log("button pressed"); // do an action on click span
        //console.log(quranVerse); //gets the span itself
        //console.log(quranVerseContainer); //get back the HTML Div container with the span element as an HTML Collection
        const qvc0 = quranVerseContainer.item([0]);
        //console.log(qvc0);
    
        // function to play the quran on click works!!!
        function playandLoopThroughQuranText() {
          const playmp3quran = document.getElementById("alduha__only").play();
          //console.log(playmp3quran);
        }
        // function to pause the quran on click doest not work!!!.
    
        function pauseandLoopThroughQuranText() {
          const pausemp3quran = document.getElementById("alduha__only").pause();
        }
    
        const timings = [
          { start: 0, stop: 0 }, //verse 0 bism allah  set to zero because the mp3 does not have bismallah
          { start: 0, stop: 1000 }, //verse 1
          { start: 1000, stop: 3000 }, //verse 2
          { start: 3000, stop: 4000 }, //end verse 2 start verse3
          { start: 4000, stop: 6000 }, //start verse 3 end verse4
          { start: 6000, stop: 9000 },
          { start: 9000, stop: 13000 },
          { start: 13000, stop: 17000 },
          { start: 17000, stop: 22000 },
          { start: 22000, stop: 26000 },
          { start: 26000, stop: 29000 },
          { start: 29000, stop: 37000 },
          { start: 37000, stop: 40000 }
        ];
    
        const durations = timings.map((timing) => timing.stop - timing.start);
    
        const qurancontainer = document.getElementById("quran__container");
        const childArray = [...qurancontainer.children]; // To use array methods
    
        childArray.forEach((el, i) => {
          el.onclick = () => {
            el.classList.toggle("highlight");
    
            const nextWord = childArray[i + 1];
    
            setTimeout(() => {
              el.classList.toggle("highlight");
              if (!nextWord) return; // Last word
              nextWord.click();
            }, durations[i]);
          };
        });
      </script>
    
      <footer>
        <small>Made by Omar abdelrahman</small>
      </footer>
    </html>
    
    <!-- References
       ```
        1. [Surat Al Duha](https://quran.com/ad-duhaa)
        2. [Surat Al Duha Mp3](https://www.al-hamdoulillah.com/en/quran/mp3/surah-93.html)
        3. [HTMLCollection.length](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection/length)
        4.[Play mp3 file with javascript onClick](https://stackoverflow.com/questions/10766538/play-mp3-file-with-javascript-onclick)
        5. [how-to-auto-animate-text-highlight-in-css](https://stackoverflow.com/questions/64197241/how-to-auto-animate-text-highlight-in-css)
        6. [event_ondurationchange](https://www.w3schools.com/jsref/event_ondurationchange.asp)
        7. [MDN - Audio - ELement](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio)
        7.1 pause   Playback has been paused.
        7.2 play    Playback has begun.
        7.3 playing     Playback is ready to start after having been paused or delayed due to lack of data. 
        8. [HTMLMediaElement: timeupdate event](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/durationchange_event)
        9. [play audio with javascript loop Code Answer’s javascript by Bored Buzzard](https://www.codegrepper.com/code-examples/javascript/play+audio+with+javascript+loop%5C)
        10. [Dynamic-Landing-Page-Project -By Omar Abdelrahman](https://github.com/omarashzeinhom/Dynamic-Landing-Page-Project)
        ```
     11/[Guffa-Answer on JS-Fiddle For Do something on button 2nd click](https://jsfiddle.net/S9wQ2/)
        -->

    Hope this helps and please make duaa for me and umma if it does work or not !!! Al salam alikum <3