Skip to content

Instantly share code, notes, and snippets.

@imgerson
Created December 22, 2018 22:07
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save imgerson/df9dc271dd1df9b2765a195ad265a53f to your computer and use it in GitHub Desktop.
Save imgerson/df9dc271dd1df9b2765a195ad265a53f to your computer and use it in GitHub Desktop.
Interactive video with HTML5 and JavaScript
<!DOCTYPE html>
<html>
<head>
<title>Basic interactive video with HTML5 and vanilla JavaScript</title>
</head>
<body>
<!-- Read my blog post on interactive videos: https://mostlydevstuff.com/2018/basic-interactive-video-with-html5-and-javascript/ -->
<style>
.hide {
display: none;
}
.initial {
display: block;
}
.videos {
position: relative;
max-width: 700px;
height: 400px;
margin: 0 auto;
}
.videos video {
max-width: 100%;
height: auto;
}
.play {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
width: 100%;
height: 98%;
padding: 0;
top: 0;
background-color: rgba(0, 0, 0, .5);
}
.play:hover .fil1 {
fill: #fff;
}
.menu {
height: 98%;
background-color: rgba(0, 0, 0, .5);
}
.menu, .menu-wrapper {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -51%);
width: 100%;
padding: 0;
text-align: center;
align-items: center;
justify-content: center;
}
.menu, .menu a {
color: #fff;
}
.menu a:hover {
cursor: pointer;
}
.menu ul li {
list-style-type: none;
}
@media only screen and (min-width: 768px) {
.menu ul li {
display: inline-block;
margin-right: 30px;
}
}
@media only screen and (max-width: 450px) {
.show-below-450 {
display: block !important;
color: red;
padding-left: 0;
padding-right: 0;
}
}
</style>
<div class="videos">
<div class="active initial closing">
<video autoplay="autoplay" loop>
<source src="/videos/video-sky.mp4" type="video/mp4">
</video>
</div>
<div class="cat hide">
<video>
<source src="/videos/video-cat.mp4" type="video/mp4">
</video>
</div>
<div class="cat hide">
<video>
<source src="/videos/video-cat-2.mp4" type="video/mp4">
</video>
</div>
<div class="dog hide">
<video>
<source src="/videos/video-dog.mp4" type="video/mp4">
</video>
</div>
<div class="dog hide">
<video>
<source src="/videos/video-dog-2.mp4" type="video/mp4">
</video>
</div>
<div class="play">
<?xml version='1.0' encoding='utf-8'?><svg xmlns="http://www.w3.org/2000/svg" width="91.44mm" height="91.44mm" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" viewBox="0 0 9144 9144"> <defs> <style type="text/css"> .fil0 {fill:#fff} .fil1 {fill:#ccc;fill-rule:nonzero} </style> </defs> <g id="Layer_x0020_1"> <metadata id="CorelCorpID_0Corel-Layer"/> <g id="_2744492901664"><g> <path class="fil1" d="M6601 4572c0,-560 -227,-1067 -594,-1435 -368,-367 -875,-594 -1435,-594 -560,0 -1067,227 -1435,594 -367,368 -594,875 -594,1435 0,560 227,1067 594,1435 368,367 875,594 1435,594 560,0 1067,-227 1435,-594 367,-368 594,-875 594,-1435zm-2513 791l1231 -791 -1231 -792 0 1583zm1442 -717l-1478 949c-14,11 -32,17 -52,17 -49,0 -88,-39 -88,-88l0 -1905 0 0c0,-16 4,-33 14,-48 26,-40 81,-52 122,-26l1480 952 2 149zm26 -122c26,41 14,96 -26,122l26 -122zm575 -1511c399,399 646,950 646,1559 0,609 -247,1160 -646,1559 -399,399 -950,646 -1559,646 -609,0 -1160,-247 -1559,-646 -399,-399 -646,-950 -646,-1559 0,-609 247,-1160 646,-1559 399,-399 950,-646 1559,-646 609,0 1160,247 1559,646z"/></g></g></g></svg>
<!-- SVG courtesy of Pixabay: https://pixabay.com/en/play-icon-player-button-outline-2935460/ -->
</div>
<div class="menu hide">
<div class="menu-wrapper">
<div class="initial hide">
<h3>Hi! I bet you like animals (just like me!).</h1>
<h4>The question is... are you a cat person or a dog person?</h2>
</div>
<div class="closing hide">
<h3>I hope you enjoyed it!</h3>
<h4>Would you like to choose a different option now?</h4>
</div>
<div class="options hide">
<ul>
<li><a id="cat-person">A cat person!</a></li>
<li><a id="dog-person">A dog person!</a></li>
<li><a href="https://twitter.com/intent/tweet?text=How to create an interactive video with %23HTML5 and %23JavaScript&via=imgersonr&url=https://mostlydevstuff.com/2018/interactive-video-with-html5-and-javascript/" target="_blank">Share demo!</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="hide show-below-450 mb15">
<p>Please, change your phone to landscape view!</p>
</div>
<script>
window.onload = function() {
var videosContainer = document.getElementsByClassName("videos")[0];
var menu = document.getElementsByClassName("menu")[0];
var menuOptions = menu.getElementsByClassName("options")[0];
var playButton = document.getElementsByClassName("play")[0];
playButton.onclick = function() {
playButton.style.display = "none";
playInitialMenu();
}
var catPersonLink = document.getElementById("cat-person");
catPersonLink.onclick = function() {
showVideos(0, videosContainer.getElementsByClassName("cat"));
}
var dogPersonLink = document.getElementById("dog-person");
dogPersonLink.onclick = function() {
showVideos(0, videosContainer.getElementsByClassName("dog"));
}
function playInitialMenu() {
playVideo(videosContainer.getElementsByClassName("initial")[0], loop=true);
setTimeout (function () {
menu.style.display = "block";
menu.getElementsByClassName("initial")[0].style.display = "block";
menuOptions.style.display = "block";
}, 1000);
};
function playClosingMenu() {
playVideo(videosContainer.getElementsByClassName("closing")[0], loop=true);
menu.getElementsByClassName("initial")[0].style.display = "none";
setTimeout (function () {
menu.style.display = "block";
menu.getElementsByClassName("closing")[0].style.display = "block";
menuOptions.style.display = "block";
}, 1000);
};
function playVideo(videoContainer, loop=false) {
var lastVideoContainer = videosContainer.getElementsByClassName("active")[0];
lastVideoContainer.classList.remove("active");
lastVideoContainer.style.display = "none";
videoContainer.style.display = "block";
videoContainer.classList.add("active");
var video = videoContainer.getElementsByTagName("video")[0];
video.preload = "auto";
video.load();
video.play();
video.loop = loop;
return video;
}
function showVideos(index, videos) {
if (index < (videos.length - 1)) {
hasNextVideo = true;
} else {
hasNextVideo = false;
}
menu.style.display = "none";
var video = playVideo(videos[index]);
video.addEventListener("timeupdate", function() {
var currentTime = (this.currentTime / this.duration) * 100;
if (hasNextVideo && currentTime > 70) {
nextVideo = videos[index + 1];
nextVideoTag = nextVideo.getElementsByTagName("video")[0];
nextVideoTag.preload = "auto";
}
})
video.onended = function() {
if (hasNextVideo) {
showVideos(index+1, videos);
} else {
playClosingMenu();
}
}
}
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment