Melanjutkan dari artikel membuat interactive movie bagian ke-1, kali ini saya akan membahas bagaimana membuat tombol atau area hotspot pada video agar dapat muncul pada waktu tertentu dan pengguna dapat berinteraksi dengan mengkliknya.

Pertama, kita perlu men-download video untuk dijadikan sebagai contoh yaitu video dari Sintel © oleh Blender Foundation pada tautan berikut https://mdn.github.io/learning-area/javascript/apis/video-audio/finished/video/sintel-short.mp4, simpan file video dan beri nama movie.mp4 pada folder videos.

Kedua, kita perlu menambahkan style dengan tipe class hotspot ke dalam CSS kita. Style class hotspot berarti setiap elemen yang menggunakan style class ini akan memiliki format tampilan yang sama.

#overlay-v, #video-container{ 
  position:absolute; 
  left:50%; 
  top:50%; 
  transform: translate(-50%, -50%); 
  width: 100%; 
  height: 100%; 
  object-fit: contain; 
} 
html, body { 
  height: 100%; 
  margin:0; 
  background: #000; 
}
.hotspot {
  position: absolute;
  background-color:rgba(0,0,128, 0.5);
  display: none;
  text-align:center;
  cursor: pointer;
  padding: 20px;
  color: #fff;
  left: 0;
  top: 0;
  width: 100px;
  height: 100px;
}

Class CSS hotspot ini akan disembunyikan terlebih dahulu (display:none) dan akan ditampilkan pada saat waktu yang telah ditentukan melalui javascript.

Bukalah dokumen index.html dan tambahkan ke dalam tag overlay-v beberapa tag baru untuk kita jadikan hotspot seperti ditunjukkan pada code di bawah:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Judul Interactive Movie</title>
  <meta name="description" content="Interactive movie.">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  <link rel="stylesheet" href="css/app.css">
  <script src="js/app.js"></script>  

</head>
<body onload="init();" >
  <div>
    <video id="video-container" type="video/mp4" src="videos/movie.mp4" playsinline></video>
    <div id="overlay-v">

       <div class="hotspot" data-show-time="3.5" onclick="seekTo(84)" style="width: 30%; height: 15%; left: 35%; top: 60%" >Skip to Dragon Scene</div>

       <div class="hotspot" data-show-time="97" style="top: 20%; width: 50%; left: 25%; height: 5%">What will she do?</div>
      <div class="hotspot" data-show-time="97" onclick="seekTo(97.1)" style="background: green; top: 70%; width: 20%; height: 5%; left: 20%">Safe</div>
      <div class="hotspot" data-show-time="97" onclick="seekTo(61)" style="background: red; top: 70%; width: 20%; height: 5%; left: 60%">Leave</div>

    </div>
  </div>
</body>
</html>

Pada setiap elemen div dengan class hotspot kita dapat memberikan perubahan style khususnya pada width, height, posisi left, dan right. Selain itu yang sangat penting adalah atribut data-show-time yang akan berisi nilai kapan waktu hotspot ini muncul dan onclick yang akan berisi fungsi javascript yang akan dilakukan ketika hotspot ini diklik oleh pengguna.  Terdapat 1 hotspot yang hanya berisi informasi dan 3 hotspot yang diklik dan memindahkan detik video ke detik 84, 97.1, dan 61.

Berikutnya adalah memodifikasi code pada dokumen app.js, sisipkan code berikut pada awal baris sebelum fungsi init():

var media; // video player element
var cuePoints = []; 
var overlay;
var prevTime = 0;
var activeHotspots = [];

Berikut adalah penjelasan dari variabel-variabel yang didefinisikan:

  • Variabel media berguna untuk menampung video player yang akan kita gunakan untuk melakukan manipulasi pada elemen video seperti play, pause, stop, dan lompat (seek) ke waktu tertentu pada video.
  • Variabel cuePoints merupakan sebuah himpunan (array) yang akan menampung seluruh elemen hotspot dan waktu mulai dari hotspot tersebut.
  • Variabel overlay merupakan div dengan ID #overlay-v yang berfungsi untuk mulai memainkan video ketika diklik oleh pengguna.
  • Variabel prevTime berguna untuk menyimpan posisi waktu detik terakhir dari video saat dimainkan, ini akan bermanfaat ketika akan mengecek waktu untuk menampilkan hotspot.
  • Variabel activeHotspots merupakan sebuah himpunan (array) yang akan menampung hotspot-hotspot yang sedang muncul (aktif) pada layar. Ketika kita akan menyembunyikan/menghilangkan seluruh hotspot dari tampilan, kita hanya perlu menyembunyikan seluruh hotspot yang ada di dalam himpunan activeHotspots.

Modifikasi fungsi init() dengan code berikut:

function init() {
  media = document.querySelector('#video-container');
  media.addEventListener('timeupdate', mediaTimeUpdate);       
  
  overlay = document.querySelector('#overlay-v');    
  overlay.addEventListener('click', startVideo);   

  var hotspots = document.querySelectorAll('.hotspot');
  for (var i=0; i<hotspots.length; i++) {
    var hotspot = hotspots[i];
    var showTime = parseFloat(hotspot.getAttribute('data-show-time'));
    if (isNaN(showTime) == false) {
      cuePoints.push({
        hotspot: hotspot,
        showTime: showTime
      });
    }
  }
}

Fungsi init ini melakukan 3 fungsi, yaitu:

  1. Memberikan isi variabel media menjadi elemen video player dengan ID #video-container pada HTML, kemudian memberikan event listener timeupdate, yang berarti setiap kali video berjalan maka akan otomatis memanggil fungsi mediaTimeUpdate (yang akan dibuat selanjutnya).
  2. Memberikan isi variabel overlay menjadi elemen div dengan ID #overlay-v pada HTML, kemudian memberikan event listener click, yang berarti bila pengguna mengklik elemen ini, maka akan memanggil fungsi startVideo (yang akan dibuat selanjutnya).
  3. Menghimpun seluruh elemen div dengan class hotspot pada HTML dan memasukkannya ke variabel himpunan cuePoints.

Masih pada app.js, tambahkan fungsi startVideo seperti pada code berikut setelah fungsi init:

function startVideo() {
  media.play();
  overlay.removeEventListener('click', startVideo);
}

Fungsi ini melakukan 2 tugas yaitu:

  1. Memainkan video
  2. Menghilangkan kemampuan pengguna untuk mengklik pada elemen #overlay-v agar selanjutnya kita dapat mengklik hotspot-hotspot.

Kemudian tambahkan fungsi mediaTimeUpdate seperti pada code berikut:

function mediaTimeUpdate() {
  for (var i=0; i<cuePoints.length; i++) {
    var cuePoint = cuePoints[i];
    if (cuePoint.showTime >= prevTime && cuePoint.showTime < media.currentTime) {
      showHotspot(cuePoint.hotspot);
    }
  }
  prevTime = media.currentTime;
}

Fungsi ini akan melakukan pengecekan waktu untuk muncul (showTime) terhadap seluruh hotspot yang ada dalam himpunan cuePoints apakah sudah +/- sama dengan waktu video berjalan saat ini. Bila ya, maka tampilkan hotspot dengan memanggil fungsi showHotspot dengan code sebagai berikut:

function showHotspot(hotspot) {
  hotspot.style.display = 'block';
  activeHotspots.push(hotspot);
  media.pause();
}

Fungsi showHotspot ini melakukan 3 hal yaitu:

  1. Menampilkan elemen div hotspot dengan mengeset style CSS pada hotspot menjadi ‘block’.
  2. Menambahkan hotspot ke dalam himpunan activeHotspot
  3. Menghentikan sementara (pause) video yang sedang main, agar pengguna dapat melakukan interaksi terhadap hotspot.

Kembali ke dokumen index.html, beberapa elemen hotspot memiliki atribut onclick, tujuannya adalah ketika elemen ini diklik oleh pengguna, maka akan memanggil fungsi yang didefinisikan pada onclick. Pada contoh ini, onclick akan memanggil fungsi seekTo yang akan dibuat untuk memindahkan video ke detik tertentu.

Tambahkan fungsi seekTo dan hideHotspot pada app.js dengan code berikut:

function seekTo(second) {
  media.currentTime = second;
  media.play();
  hideHotspot();
}
function hideHotspot() {
  for (var i=0; i<activeHotspots.length; i++) {
    var hotspot = activeHotspots[i];
    hotspot.style.display = 'none';
  }
}

Pada bagian akhir fungsi seekTo, kita akan memanggil fungsi hideHotspot untuk menyembunyikan seluruh hotspot yang muncul pada layar.

Bila semuanya sudah dibuat, silakan dicoba dengan membuka dokumen index.html pada web browser dan klik pada video, tunggu sampai detik ke 3.5 untuk melihat hotspot muncul dan coba klik hotspot tersebut untuk melompat ke detik 84 dari video.

Demikian dasar pembuat movie interactive dengan menggunakan HTML5 dan Javascript. Semoga artikel ini membantu anda dan silakan berkreasi, lakukan modifikasi pada code sesuai dengan kebutuhan anda.

Referensi:

Mozilla Developer Network: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs