Created
December 22, 2018 22:07
-
-
Save imgerson/df9dc271dd1df9b2765a195ad265a53f to your computer and use it in GitHub Desktop.
Interactive video with HTML5 and JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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