HTML5-lydafspiller i modalt vindue

15. januar 2023 kl. 20:29 Kode 0

Da jeg udviklede denne version af Psylicium.dk (januar 2023), fik jeg optimeret lydafspilleren, så hvor jeg før havde et skjult modalt vindue for hvert eneste musiknummer, som så åbnede dets tilsvarende vindue baseret på ID, har jeg nu kun ét modalt vindue til al afspilning. Det har lettet koden og sideindlæsningen gevaldigt, og fungerer kort og godt således:

  1. Jeg har lavet en “skabelon” af det modale vindue uden indhold, som selvfølgelig er skjult når siden indlæses. I dette vindue er pladsholdere til coverbillede, titel, kunstner og mp3-fil, og disse bliver udfyldt af jQuery vha. data-* attributter i links med CSS-klassen “.player”
  2. Når jeg hiver musiknumrene ind fra databasen, kører jeg titlen gennem str_replace, der fjerner specialtegn og mellemrum, og sætter “player-” foran, så f.eks. “Best Day (Z-Buffer Club Mix)” bliver til id=”player-bestdayzbufferclubmix”. Dette bliver til linkets unikke ID, som så får udtrukket info (titel, kunstner, cover og mp3-fil) fra data-* attributterne

Opret 3 tomme filer – modal.php (eller modal.html, hvis indholdet er statisk – jeg bruger .php i dette eksempel), modal.js samt modal.css, og indsæt indholdet herunder i de respektive filer.

modal.php: Det modale vindue med et full-screen overlay, der slører baggrunden:

modal.php
<div class="modal-overlay">
   <div class="modal-content">
      <img class="cover" src="" id="cover">
      <div class="info">
         <span id="title" class="title">This is info</span>
         <span id="performer" class="performer"></span>
      </div>
      <div class="player">
         <audio id="audio" controls autoplay preload="none" src=""></audio>
      </div>
      <span class="modal-close">×</span>
   </div>
</div>

modal.php fortsat – generering af player ID og link med af data-* attributter. I dette tilfælde er variablerne $performer, $cover_image og $filename statiske, men kan sagtens hentes fra en database. Dette eksempel vil lave en afspiller, hvor titlen er Equinoxe Part 4 (Scrubtuds 2K22 Edit), kunstneren Jarre, og filnavnet audio.mp3.

Har man flere musiknumre på samme side, skal hvert link-ID være unikt, og dette bliver automatisk genereret ud fra titlen. Specialkarakterer i $replace-arrayet bliver fjernet, og strengen laves til lowercase – dvs. Equinoxe Part 4 (Scrubtuds 2K22 Edit) bliver til ID’et equinoxepart4scrubtuds2k22edit:

modal.php
// Set variables
$performer = "Jarre";
$cover_image = "cover.jpg";
$filename = "audio.mp3";

// Generate ID for modal window based on title
$title = "Equinoxe Part 4 (Scrubtuds 2K22 Edit)";

// Characters to be stripped
$replace = array('æ', 'ø', 'å', '\'', ' ', '(', ')', '-', '?', '!', '.','&');

// Convert to lowercase. $playerid is now "equinoxepart4scrubtuds2k22edit"
$playerid = strtolower(str_replace($replace, '', $title));

// Render HTML
echo '<a id="player-'.$playerid.'" class="playerlink" data-cover="'.$cover_image.'" data-audio="'.$filename.'" data-title="'.$title.'" data-performer="'.$performer.'">";
echo $performer.' - '.$title. ' (click to open player)';
echo '</a>';

modal.js, som vha. jQuery henter informationer fra html-dokumentet og viser dem i afspillervinduet:

modal.js
$(document).ready(function(){
   // Create overlay and open player when class .playerlink is clicked
   $('.playerlink').on('click', function() {
      $('.modal-overlay').css({"visibility": "visible", "opacity": "1"});
      $('.modal-content').addClass("active");
      $(document.body).addClass('noScroll');
    	
      // assign 'data-*' to variables
      var id = $(this).attr('id');
      var title = $('#'+id).attr('data-title');
      var performer = $('#'+id).attr('data-performer');
      var cover = $('#'+id).attr('data-cover');
      var audio = $('#'+id).attr('data-audio');
    
      // Inject variables into target IDs in the player
      $('#title').text(title);
      $('#performer').text(performer);
      $('#cover').attr("src", cover); 
      $('#audio').attr("src", audio);

      // The Close Button
      $('.modal-close').on('click', function() {
         $('.modal-content').removeClass("active");
         $('.modal-overlay').css({"visibility": "hidden", "opacity": "0"});
         $(document.body).removeClass('noScroll');

         // Stop music and reset time
         $('#audio').each(function(){
            this.pause(); // Stop playing
            this.currentTime = 0; // Reset time
         })
      })
   })
});

Stylesheet til hele molevitten:

modal.css
.playerlink {
   cursor: pointer;
}

.modal-overlay {
   background-color: rgba(0,0,0,.7);
   opacity: 0;
   visibility: hidden;
   width: 100%;
   height: 100%;
   position: fixed;
   overflow-y: scroll;
   top: 0;
   left: 0;
   -webkit-backdrop-filter: blur(10px) grayscale(100%);
   backdrop-filter: blur(10px) grayscale(100%);
   z-index: 999;
   transition: all .5s;
}

.noScroll {
   overflow: hidden;
}

.modal-content {
   background-color: #fff;
   color: #333;
   position: absolute;
   text-align: center;
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
   width: 400px;
   padding: 1rem;
   border-radius: 5px;
   box-shadow: 0 0 10px rgb(0 0 0 / 50%);
   transition: all .2s;
   opacity: 0;
   transition-timing-function: ease-in-out;
}

.modal-content .cover {
   width: 300px;
}

.modal-content .info {
   margin: 1rem 0;
   padding: .5rem;
   background-color: #ccc;
}
.modal-content .info span {
   display: block;
   text-align: center;
}

.modal-content .info .title {
   font-size: 1.25rem;
   font-weight: 600;
   line-height: 1.5rem;
   margin-bottom: 0.5rem;
}

.modal-content .info .performer {
   font-size: 1.1rem;
}

.modal-content .player {
   display: block;
}

.modal-content .release {
   font-size: .8rem;
   text-align: center;
   width: 100%;
}

.modal-content.active {
   opacity: 1;
}

.modal-close {
   background-color: var(–modal-close-bg);
   color: var(–modal-close-cross);
   position: absolute;
   top: .5rem;
   right: .5rem;
   cursor: pointer;
   font-size: 1.5em;
   line-height: 20px;
   padding: 0 4px 3px;
   margin: 0;
   border-radius: 50%;
}

Inkludér modal.css, modal.js samt jQuery (https://releases.jquery.com/) i headeren som vist herunder. Dette er et helt simpelt HTML-eksempel med 2 links – #player-audio1 og #player-audio2.

demo.html
<!DOCTYPE html>
<html>
   <head>
      <link rel="stylesheet" href="modal.css" type="text/css" media="screen" />
      <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
      <script src="modal.js"></script>
   </head>
   <body>
      <div class="modal-overlay">
         <div class="modal-content">
            <img class="cover" src="" id="cover">
            <div class="info">
               <span id="title" class="title">This is info</span>
               <span id="performer" class="performer"></span>
            </div>
            <div class="player">
               <audio id="audio" controls autoplay preload="none" src=""></audio>
            </div>
            <span class="modal-close">×</span>
         </div>
      </div>

      <a id="player-audio1" class="playerlink" data-cover="cover_bug.jpg" data-audio="audio1.mp3" data-title="Dette er Titel 1" data-performer="Dette er kunstner 1">Kunstner 1 – Titel 1 (Klik for at åbne afspiller)</a><br /><br />
      <a id="player-audio2" class="playerlink" data-cover="cover_templeofdoom.jpg" data-audio="audio2.mp3" data-title="Dette er Titel 2" data-performer="Dette er kunstner 2">Kunstner 2 – Titel 2 (Klik for at åbne afspiller)</a>

   </body>
</html>

LIVE DEMO

Ingen kommentarer til “HTML5-lydafspiller i modalt vindue”

Skriv en kommentar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *

This site uses Akismet to reduce spam. Learn how your comment data is processed.