Full screen pop up window for multiple embedded videos - javascript

I'm new to js and I found a codepen that does exactly what I want to do except it currently only works for one embedded video.
What i am trying to achieve is the same but with 6 videos.
(function ($) {
'use strict';
$.fn.fitVids = function (options) {
var settings = {
customSelector: null,
ignore: null
};
if (!document.getElementById('fit-vids-style')) {
// appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js
var head = document.head || document.getElementsByTagName('head')[0];
var css = '.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}';
var div = document.createElement("div");
div.innerHTML = '<p>x</p><style id="fit-vids-style">' + css + '</style>';
head.appendChild(div.childNodes[1]);
}
if (options) {
$.extend(settings, options);
}
return this.each(function () {
var selectors = [
'iframe[src*="player.vimeo.com"]',
'iframe[src*="youtube.com"]',
'iframe[src*="youtube-nocookie.com"]',
'iframe[src*="kickstarter.com"][src*="video.html"]',
'object',
'embed'
];
if (settings.customSelector) {
selectors.push(settings.customSelector);
}
var ignoreList = '.fitvidsignore';
if (settings.ignore) {
ignoreList = ignoreList + ', ' + settings.ignore;
}
var $allVideos = $(this).find(selectors.join(','));
$allVideos = $allVideos.not('object object'); // SwfObj conflict patch
$allVideos = $allVideos.not(ignoreList); // Disable FitVids on this video.
$allVideos.each(function (count) {
var $this = $(this);
if ($this.parents(ignoreList).length > 0) {
return; // Disable FitVids on this video.
}
if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) {
return;
}
if ((!$this.css('height') && !$this.css('width')) && (isNaN($this.attr('height')) || isNaN($this.attr('width')))) {
$this.attr('height', 9);
$this.attr('width', 16);
}
var height = (this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10)))) ? parseInt($this.attr('height'), 10) : $this.height(),
width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),
aspectRatio = height / width;
if (!$this.attr('id')) {
var videoID = 'fitvid' + count;
$this.attr('id', videoID);
}
$this.wrap('<div class="fluid-width-video-wrapper"></div>').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100) + '%');
$this.removeAttr('height').removeAttr('width');
});
});
};
// Works with either jQuery or Zepto
})(window.jQuery || window.Zepto);
// Init style shamelessly stolen from jQuery http://jquery.com
var Froogaloop = (function () {
// Define a local copy of Froogaloop
function Froogaloop(iframe) {
// The Froogaloop object is actually just the init constructor
return new Froogaloop.fn.init(iframe);
}
var eventCallbacks = {},
hasWindowEvent = false,
isReady = false,
slice = Array.prototype.slice,
playerDomain = '';
Froogaloop.fn = Froogaloop.prototype = {
element: null,
init: function (iframe) {
if (typeof iframe === "string") {
iframe = document.getElementById(iframe);
}
this.element = iframe;
// Register message event listeners
playerDomain = getDomainFromUrl(this.element.getAttribute('src'));
return this;
},
/*
* Calls a function to act upon the player.
*
* #param {string} method The name of the Javascript API method to call. Eg: 'play'.
* #param {Array|Function} valueOrCallback params Array of parameters to pass when calling an API method
* or callback function when the method returns a value.
*/
api: function (method, valueOrCallback) {
if (!this.element || !method) {
return false;
}
var self = this,
element = self.element,
target_id = element.id !== '' ? element.id : null,
params = !isFunction(valueOrCallback) ? valueOrCallback : null,
callback = isFunction(valueOrCallback) ? valueOrCallback : null;
// Store the callback for get functions
if (callback) {
storeCallback(method, callback, target_id);
}
postMessage(method, params, element);
return self;
},
/*
* Registers an event listener and a callback function that gets called when the event fires.
*
* #param eventName (String): Name of the event to listen for.
* #param callback (Function): Function that should be called when the event fires.
*/
addEvent: function (eventName, callback) {
if (!this.element) {
return false;
}
var self = this,
element = self.element,
target_id = element.id !== '' ? element.id : null;
storeCallback(eventName, callback, target_id);
// The ready event is not registered via postMessage. It fires regardless.
if (eventName != 'ready') {
postMessage('addEventListener', eventName, element);
} else if (eventName == 'ready' && isReady) {
callback.call(null, target_id);
}
return self;
},
/*
* Unregisters an event listener that gets called when the event fires.
*
* #param eventName (String): Name of the event to stop listening for.
*/
removeEvent: function (eventName) {
if (!this.element) {
return false;
}
var self = this,
element = self.element,
target_id = element.id !== '' ? element.id : null,
removed = removeCallback(eventName, target_id);
// The ready event is not registered
if (eventName != 'ready' && removed) {
postMessage('removeEventListener', eventName, element);
}
}
};
/**
* Handles posting a message to the parent window.
*
* #param method (String): name of the method to call inside the player. For api calls
* this is the name of the api method (api_play or api_pause) while for events this method
* is api_addEventListener.
* #param params (Object or Array): List of parameters to submit to the method. Can be either
* a single param or an array list of parameters.
* #param target (HTMLElement): Target iframe to post the message to.
*/
function postMessage(method, params, target) {
if (!target.contentWindow.postMessage) {
return false;
}
var url = target.getAttribute('src').split('?')[0],
data = JSON.stringify({
method: method,
value: params
});
if (url.substr(0, 2) === '//') {
url = window.location.protocol + url;
}
target.contentWindow.postMessage(data, url);
}
/**
* Event that fires whenever the window receives a message from its parent
* via window.postMessage.
*/
function onMessageReceived(event) {
var data, method;
try {
data = JSON.parse(event.data);
method = data.event || data.method;
} catch (e) {
//fail silently... like a ninja!
}
if (method == 'ready' && !isReady) {
isReady = true;
}
// Handles messages from moogaloop only
if (event.origin != playerDomain) {
return false;
}
var value = data.value,
eventData = data.data,
target_id = target_id === '' ? null : data.player_id,
callback = getCallback(method, target_id),
params = [];
if (!callback) {
return false;
}
if (value !== undefined) {
params.push(value);
}
if (eventData) {
params.push(eventData);
}
if (target_id) {
params.push(target_id);
}
return params.length > 0 ? callback.apply(null, params) : callback.call();
}
/**
* Stores submitted callbacks for each iframe being tracked and each
* event for that iframe.
*
* #param eventName (String): Name of the event. Eg. api_onPlay
* #param callback (Function): Function that should get executed when the
* event is fired.
* #param target_id (String) [Optional]: If handling more than one iframe then
* it stores the different callbacks for different iframes based on the iframe's
* id.
*/
function storeCallback(eventName, callback, target_id) {
if (target_id) {
if (!eventCallbacks[target_id]) {
eventCallbacks[target_id] = {};
}
eventCallbacks[target_id][eventName] = callback;
} else {
eventCallbacks[eventName] = callback;
}
}
/**
* Retrieves stored callbacks.
*/
function getCallback(eventName, target_id) {
if (target_id) {
return eventCallbacks[target_id][eventName];
} else {
return eventCallbacks[eventName];
}
}
function removeCallback(eventName, target_id) {
if (target_id && eventCallbacks[target_id]) {
if (!eventCallbacks[target_id][eventName]) {
return false;
}
eventCallbacks[target_id][eventName] = null;
} else {
if (!eventCallbacks[eventName]) {
return false;
}
eventCallbacks[eventName] = null;
}
return true;
}
/**
* Returns a domain's root domain.
* Eg. returns http://vimeo.com when http://vimeo.com/channels is sbumitted
*
* #param url (String): Url to test against.
* #return url (String): Root domain of submitted url
*/
function getDomainFromUrl(url) {
if (url.substr(0, 2) === '//') {
url = window.location.protocol + url;
}
var url_pieces = url.split('/'),
domain_str = '';
for (var i = 0, length = url_pieces.length; i < length; i++) {
if (i < 3) {
domain_str += url_pieces[i];
} else {
break;
}
if (i < 2) {
domain_str += '/';
}
}
return domain_str;
}
function isFunction(obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
}
function isArray(obj) {
return toString.call(obj) === '[object Array]';
}
// Give the init function the Froogaloop prototype for later instantiation
Froogaloop.fn.init.prototype = Froogaloop.fn;
// Listens for the message event.
// W3C
if (window.addEventListener) {
window.addEventListener('message', onMessageReceived, false);
}
// IE
else {
window.attachEvent('onmessage', onMessageReceived);
}
// Expose froogaloop to the global object
return (window.Froogaloop = window.$f = Froogaloop);
})();
////////////////////////////////////////
// Our Script
////////////////////////////////////////
$(document).ready(function () {
// Initiate FitVid.js
$(".containiframeCeleb2").fitVids();
$(".containiframeRiver2").fitVids();
$(".containiframeBach").fitVids();
$(".containiframeLouie").fitVids();
$(".containiframeRiver1").fitVids();
$(".containiframeCeleb1").fitVids();
$(".containiframe").fitVids();
// Iframe/player variables
var iframe = $('#videoCeleb1')[0];
var iframe = $('#videoRiver1')[0];
var iframe = $('#videoLouie')[0];
var iframe = $('#videoBach')[0];
var iframe = $('#videoRiver2')[0];
var iframe = $('#videoCeleb2')[0];
var iframe = $('#video')[0];
var player = $f(iframe);
// Open on play
$('.play').click(function () {
$('.content').css('left', 0)
$('.content').addClass('show')
player.api("play");
})
$('.playcelebrity1').click(function () {
$('.content').css('left', 0)
$('.content').addClass('show')
player.api("playcelebrity1");
})
$('.playcottage1').click(function () {
$('.content').css('left', 0)
$('.content').addClass('show')
player.api("playcottage1");
})
$('.playLouie').click(function () {
$('.content').css('left', 0)
$('.content').addClass('show')
player.api("playLouie");
})
$('.playbachelourette').click(function () {
$('.content').css('left', 0)
$('.content').addClass('show')
player.api("playbachelourette");
})
$('.playcottage2').click(function () {
$('.content').css('left', 0)
$('.content').addClass('show')
player.api("playcottage2");
})
$('.playcelbrity2').click(function () {
$('.content').css('left', 0)
$('.content').addClass('show')
player.api("playcelbrity2");
})
// Closes on click outside
$('.content').click(function () {
$('.content').removeClass('show')
setTimeout(function () {
$('.content').css('left', '-100%')
}, 300);
player.api("pause");
})
});
/* Lazy-man Reset */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Fullscreen Section */
header {
width: 100%;
/* 100% height */
height: 100vh;
color: white;
background: #2980b9;
text-align: center;
padding: 20px;
/* Fancy flex-box centering */
display: flex;
align-items: center;
justify-content: center;
-webkit-display: flex;
-webkit-align-items: center;
-webkit-justify-content: center;
}
header h1 {
font-size: 40px;
font-family: 'Roboto';
font-weight: 700;
max-width: 700px;
margin-bottom: 10px;
}
header p {
font-family: 'Roboto Slab';
font-weight: 400;
font-size: 20px;
max-width: 700px;
margin-bottom: 20px;
opacity: .65;
}
.play {
background-image: url(https://img.youtube.com/vi/YDHFM2HmYe0/default.jpg);
display: block;
width: 120px;
height: 90px;
margin: 0 auto;
/* Important for :after */
position: relative;
}
.play:hover {
background: #333;
cursor: pointer;
}
.play:after {
position: absolute;
/* Centering */
/* CSS Triangle */
}
.playcelebrity1 {
background-image: url(https://img.youtube.com/vi/ebB0eoSY4yU/default.jpg);
display: block;
/* width: 500px;
height: 297px;*/
margin: 0 auto;
/* Important for :after */
position: relative;
}
.playcelebrity1:hover {
background: #333;
cursor: pointer;
}
.playcelebrity1:after {
position: absolute;
/* Centering */
/* CSS Triangle */
}
.playcottage1 {
background-image: url(https://img.youtube.com/vi/YDHFM2HmYe0/default.jpg);
display: block;
width: 120px;
height: 90px;
margin: 0 auto;
/* Important for :after */
position: relative;
}
.playcottage1:hover {
background: #333;
cursor: pointer;
}
.playcottage1:after {
position: absolute;
/* Centering */
/* CSS Triangle */
}
.playLouie {
background-image: url(https://img.youtube.com/vi/ol43MqHED9c/default.jpg);
display: block;
width: 120px;
height: 90px;
margin: 0 auto;
/* Important for :after */
position: relative;
}
.playLouie:hover {
background: #333;
cursor: pointer;
}
.playLouie:after {
position: absolute;
/* Centering */
/* CSS Triangle */
}
.playbachelourette {
background-image: url(https://img.youtube.com/vi/qXy5sCJj2wI/default.jpg);
display: block;
width: 120px;
height: 90px;
margin: 0 auto;
/* Important for :after */
position: relative;
}
.playbachelourette:hover {
background: #333;
cursor: pointer;
}
.playbachelourette:after {
position: absolute;
/* Centering */
/* CSS Triangle */
}
.playcottage2 {
background-image: url(https://img.youtube.com/vi/7OeoQqPqxBg/default.jpg);
display: block;
width: 120px;
height: 90px;
margin: 0 auto;
/* Important for :after */
position: relative;
}
.playcottage2:hover {
background: #333;
cursor: pointer;
}
.playcottage2:after {
position: absolute;
/* Centering */
/* CSS Triangle */
}
.playcelbrity2 {
background-image: url(https://img.youtube.com/vi/lk9tse44BMc/default.jpg);
display: block;
width: 120px;
height: 90px;
margin: 0 auto;
/* Important for :after */
position: relative;
}
.playcelbrity2:hover {
background: #333;
cursor: pointer;
}
.playcelbrity2:after {
position: absolute;
/* Centering */
/* CSS Triangle */
}
/* Fullscreen Overlay */
.content {
width: 100%;
height: 100vh;
/* 50% opacity black */
background: rgba(0, 0, 0, .5);
/* Stays locked on scroll */
position: fixed;
/* On top of the rest*/
z-index: 2;
/* Hidden */
opacity: 0;
/* No interference */
left: -100%;
/* CSS3 Transition */
transition: opacity .5s;
-webkit-transition: opacity .5s;
}
/* 90% width container */
.containiframeCeleb2 {
width: 90%;
/* Centering */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
}
.containiframeRiver2 {
width: 90%;
/* Centering */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
}
.containiframeLouie {
width: 90%;
/* Centering */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
}
.containiframeCeleb1 {
width: 90%;
/* Centering */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
}
.containiframe {
width: 90%;
/* Centering */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
}
.close {
width: 20px;
fill: white;
position: absolute;
right: 0;
/* Bring above video */
top: -30px;
}
.close:hover {
/* 50% opacity white */
fill: rgba(255, 255, 255, 0.5);
cursor: pointer;
}
/* Class to fade in overlay */
.show {
opacity: 1;
}
<title>FullScreen Vimeo Popup with Autoplay and CSS3 Transitions</title>
<body>
<div class="content">
<!--End of the new-->
<div class="containiframeCeleb2">
<!-- SVG Close (X) Icon -->
<svg class="close" xmlns="http://www.w3.org/2000/svg" viewBox="39.2 22.3 25 24.5"><path d="M39.5,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4l10.3-10.3L62,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4c0.5-0.5,0.5-1.3,0-1.8L53.5,34.3l9.8-9.8c0.5-0.5,0.5-1.3,0-1.8c-0.5-0.5-1.3-0.5-1.8,0l-9.8,9.8l-9.8-9.8c-0.5-0.5-1.3-0.5-1.8,0c-0.5,0.5-0.5,1.3,0,1.8l9.8,9.8L39.5,44.6C39,45.1,39,45.9,39.5,46.4z"/></svg>
<!-- Embedded video -->
<iframe id="videoCeleb2" src="https://www.youtube.com/embed/lk9tse44BMc?ecver=1" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
<div class="containiframeRiver2">
<!-- SVG Close (X) Icon -->
<svg class="close" xmlns="http://www.w3.org/2000/svg" viewBox="39.2 22.3 25 24.5"><path d="M39.5,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4l10.3-10.3L62,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4c0.5-0.5,0.5-1.3,0-1.8L53.5,34.3l9.8-9.8c0.5-0.5,0.5-1.3,0-1.8c-0.5-0.5-1.3-0.5-1.8,0l-9.8,9.8l-9.8-9.8c-0.5-0.5-1.3-0.5-1.8,0c-0.5,0.5-0.5,1.3,0,1.8l9.8,9.8L39.5,44.6C39,45.1,39,45.9,39.5,46.4z"/></svg>
<!-- Embedded video -->
<iframe id="videoRiver2" src="https://www.youtube.com/embed/7OeoQqPqxBg?ecver=1" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
<div class="containiframeBach">
<!-- SVG Close (X) Icon -->
<svg class="close" xmlns="http://www.w3.org/2000/svg" viewBox="39.2 22.3 25 24.5"><path d="M39.5,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4l10.3-10.3L62,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4c0.5-0.5,0.5-1.3,0-1.8L53.5,34.3l9.8-9.8c0.5-0.5,0.5-1.3,0-1.8c-0.5-0.5-1.3-0.5-1.8,0l-9.8,9.8l-9.8-9.8c-0.5-0.5-1.3-0.5-1.8,0c-0.5,0.5-0.5,1.3,0,1.8l9.8,9.8L39.5,44.6C39,45.1,39,45.9,39.5,46.4z"/></svg>
<!-- Embedded video -->
<iframe id="videoBach" src="https://www.youtube.com/embed/qXy5sCJj2wI?ecver=1" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
<div class="containiframeLouie">
<!-- SVG Close (X) Icon -->
<svg class="close" xmlns="http://www.w3.org/2000/svg" viewBox="39.2 22.3 25 24.5"><path d="M39.5,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4l10.3-10.3L62,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4c0.5-0.5,0.5-1.3,0-1.8L53.5,34.3l9.8-9.8c0.5-0.5,0.5-1.3,0-1.8c-0.5-0.5-1.3-0.5-1.8,0l-9.8,9.8l-9.8-9.8c-0.5-0.5-1.3-0.5-1.8,0c-0.5,0.5-0.5,1.3,0,1.8l9.8,9.8L39.5,44.6C39,45.1,39,45.9,39.5,46.4z"/></svg>
<!-- Embedded video -->
<iframe id="videoLouie" src="https://www.youtube.com/embed/ol43MqHED9c?ecver=1" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
<div class="containiframeRiver1">
<!-- SVG Close (X) Icon -->
<svg class="close" xmlns="http://www.w3.org/2000/svg" viewBox="39.2 22.3 25 24.5"><path d="M39.5,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4l10.3-10.3L62,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4c0.5-0.5,0.5-1.3,0-1.8L53.5,34.3l9.8-9.8c0.5-0.5,0.5-1.3,0-1.8c-0.5-0.5-1.3-0.5-1.8,0l-9.8,9.8l-9.8-9.8c-0.5-0.5-1.3-0.5-1.8,0c-0.5,0.5-0.5,1.3,0,1.8l9.8,9.8L39.5,44.6C39,45.1,39,45.9,39.5,46.4z"/></svg>
<!-- Embedded video -->
<iframe id="videoRiver1" src="https://www.youtube.com/embed/YDHFM2HmYe0?ecver=1" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
<div class="containiframeCeleb1">
<!-- SVG Close (X) Icon -->
<svg class="close" xmlns="http://www.w3.org/2000/svg" viewBox="39.2 22.3 25 24.5"><path d="M39.5,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4l10.3-10.3L62,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4c0.5-0.5,0.5-1.3,0-1.8L53.5,34.3l9.8-9.8c0.5-0.5,0.5-1.3,0-1.8c-0.5-0.5-1.3-0.5-1.8,0l-9.8,9.8l-9.8-9.8c-0.5-0.5-1.3-0.5-1.8,0c-0.5,0.5-0.5,1.3,0,1.8l9.8,9.8L39.5,44.6C39,45.1,39,45.9,39.5,46.4z"/></svg>
<!-- Embedded video -->
<iframe id="videoCeleb1" src="https://www.youtube.com/embed/ebB0eoSY4yU?ecver=1" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
<div class="containiframe">
<!-- SVG Close (X) Icon -->
<svg class="close" xmlns="http://www.w3.org/2000/svg" viewBox="39.2 22.3 25 24.5"><path d="M39.5,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4l10.3-10.3L62,46.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4c0.5-0.5,0.5-1.3,0-1.8L53.5,34.3l9.8-9.8c0.5-0.5,0.5-1.3,0-1.8c-0.5-0.5-1.3-0.5-1.8,0l-9.8,9.8l-9.8-9.8c-0.5-0.5-1.3-0.5-1.8,0c-0.5,0.5-0.5,1.3,0,1.8l9.8,9.8L39.5,44.6C39,45.1,39,45.9,39.5,46.4z"/></svg>
<!-- Embedded video -->
<iframe id="video" src="https://www.youtube.com/embed/YDHFM2HmYe0?ecver=1" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
</div>
<header>
<div>
<span class="play"> </span>
</div>
<div>
<span class="playcelebrity1"> </span>
</div>
<div>
<span class="playcottage1"> </span>
</div>
<div>
<span class="playLouie"> </span>
</div>
<div>
<span class="playbachelourette"> </span>
</div>
<div>
<span class="playcottage2"> </span>
</div>
<div>
<span class="playcelbrity2"> </span>
</div>
</header>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src="js/index.js"></script>
</body>
</html>
Here is my progress so far (jsfiddle)

I had a project which I should embed multi videos. this is how I done it :
I used Bootstrap modal :
<div id="videoModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<span class="close">×</span>
<iframe id="videoIframe" class="full-width height-480"
src="https://www.youtube.com/watch?v=UM-ZPAF2Dpw" frameborder="0" allowfullscreen></iframe>
</div>
</div>
add this one only once, and in your button pass the youtube video ID like this :
<button onclick="showVideo('UM-ZPAF2Dpw')"><span class="glyphicon glyphicon-triangle-right"></span> Show Video 1</button>
you can have as many as button you like with different video ID
and in your script file you need to have this :
function showVideo(youtubeID){
var url = 'https://www.youtube.com/embed/' + youtubeID
document.getElementById('videoIframe').src = url;
// Get the modal
var modal = document.getElementById('videoModal');
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
modal.style.display = "block";
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
document.getElementById('videoIframe').src = '';
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
document.getElementById('videoIframe').src = '';
}
}
}

Related

How to add a smooth animation to the progress bar

When I click I want to smoothly add segments to the progress bar. They are added but instantly. What could be the problem?
I tried to implement a smooth animation with setInterval, but nothing comes out. Percentages are also added instantly.
let progressBar = document.querySelector(".progressbar");
let progressBarValue = document.querySelector(".progressbar__value");
const body = document.querySelector("body");
let progressBarStartValue = 0;
let progressBarEndValue = 100;
let speed = 50;
body.addEventListener("click", function(e) {
if (progressBarStartValue === progressBarEndValue) {
alert("you have completed all the tasks");
} else {
let progress = setInterval(() => {
if (progressBarStartValue != 100) {
progressBarStartValue += 10;
clearInterval(progress);
}
progressBarValue.textContent = `${progressBarStartValue}%`;
progressBar.style.background = `conic-gradient(
#FFF ${progressBarStartValue * 3.6}deg,
#262623 ${progressBarStartValue * 3.6}deg
)`;
}, speed);
}
});
.progressbar {
position: relative;
height: 150px;
width: 150px;
background-color: #262623;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.progressbar::before {
content: "";
position: absolute;
height: 80%;
width: 80%;
background-color: #0f0f0f;
border-radius: 50%;
}
.progressbar__value {
color: #fff;
z-index: 9;
font-size: 25px;
font-weight: 600;
}
<main class="main">
<section class="statistic">
<div class="container">
<div class="statistic__inner">
<div class="statistic__text">
<h2 class="statistic__title">You're almost there!</h2>
<p class="statistic__subtitle">keep up the good work</p>
</div>
<div class="progressbar"><span class="progressbar__value">0%</span></div>
</div>
</div>
</section>
</main>
This may not be exactly what you're looking for, but with the conic-gradient() implementation you're using, I'd recommend checking out a library call anime.js.
Here's an example with your implementation (same html and css):
// your.js
let progressBar = document.querySelector(".progressbar");
let progressBarValue = document.querySelector(".progressbar__value");
const body = document.querySelector("body");
// Switched to object for target in anime()
let progressBarObject = {
progressBarStartValue: 0,
progressBarEndValue: 100,
progressBarAnimationValue: 0 * 3.6 // New value needed for smoothing the progress bar, since the progress value needs to be multiplied by 3.6
}
// Not necessary, but I recommend changing the event listener to pointerup for better support
// Also not necessary, I changed function to arrow function for my own preference
body.addEventListener("pointerup", e => {
e.preventDefault()
if (progressBarObject.progressBarStartValue === progressBarObject.progressBarEndValue) {
alert("you have completed all the tasks");
} else {
let newValue = 0 // Needed so we can set the value, before it's applied in anime()
if (progressBarObject.progressBarStartValue != 100) {
// Math.ceil() allows us to round to the nearest 10 to guarantee the correct output
newValue = Math.ceil((progressBarObject.progressBarStartValue + 10) / 10) * 10;
}
// Optional: Prevents accidentally going over 100 somehow
if (newValue > 100) {
newValue = 100
}
anime({
targets: progressBarObject,
progressBarStartValue: newValue,
progressBarAnimationValue: newValue * 3.6,
easing: 'easeInOutExpo',
round: 1, // Rounds to nearest 1 so you don't have 0.3339...% displayed in progressBarValue
update: () => {
progressBar.style.backgroundImage = `conic-gradient(
#FFF ${progressBarObject.progressBarAnimationValue}deg,
#262623 ${progressBarObject.progressBarAnimationValue}deg)`;
progressBarValue.textContent = `${progressBarObject.progressBarStartValue}%`;
},
duration: 500
});
}
});
Here's a CodePen using the anime.js CDN: Circular Progress Bar Smoothing
If you don't want to use a javascript library, then I'd recommend switching from the conic-gradient() to something else. I hear using an .svg circle with stroke and stroke-dasharray can work great with CSS transition.
You shouldn't setInterval your progress variable like this. instead, put it as a global variable outside the function then use it to gradually add 1 as long as the start value is less than progress, and you still can control the speed with your speed variable.
let progressBar = document.querySelector(".progressbar");
let progressBarValue = document.querySelector(".progressbar__value");
const body = document.querySelector("body");
let progressBarStartValue = 0;
let progressBarEndValue = 100;
let speed = 50;
let progress = 0;
body.addEventListener("click", function(e) {
if (progressBarStartValue === progressBarEndValue) {
alert("you have completed all the tasks");
} else {
progress += 10;
setInterval(() => {
if (progressBarStartValue < progress) {
progressBarStartValue += 1;
clearInterval();
}
progressBarValue.textContent = `${progressBarStartValue}%`;
progressBar.style.background = `conic-gradient(
#FFF ${progressBarStartValue * 3.6}deg,
#262623 ${progressBarStartValue * 3.6}deg
)`;
}, speed);
}
});
.progressbar {
position: relative;
height: 150px;
width: 150px;
background-color: #262623;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
border: 3px solid red;
}
.progressbar::before {
content: "";
position: absolute;
height: 80%;
width: 80%;
background-color: #0f0f0f;
border-radius: 50%;
border: 3px solid blue;
}
.progressbar__value {
color: #fff;
z-index: 9;
font-size: 25px;
font-weight: 600;
}
<main class="main">
<section class="statistic">
<div class="container">
<div class="statistic__inner">
<div class="statistic__text">
<h2 class="statistic__title">You're almost there!</h2>
<p class="statistic__subtitle">keep up the good work</p>
</div>
<div class="progressbar"><span class="progressbar__value">0%</span></div>
</div>
</div>
</section>
</main>

How to remove the overlay image on only the selected lazyloaded video?

In the script below, I'm lazyloading two videos. My script is designed to remove the overlay image from the selected video when clicked. However, it's also removing the overlay image from the second video and placing it above it. Another click removes the duplicate image, and a third click plays the video.
How do I remove only the image for the selected video in a way that doesn't affect a second video on the page?
const getVideoId = (wistia_vid) => {
const classes = Array.from(wistia_vid.querySelector(".wistia_embed").classList);
const idClass = classes.find((cls) => cls.startsWith("wistia_async_"));
const id = idClass.replace("wistia_async_", "");
return id;
};
const removeElems = (wistia_vid) => {
const toRemove = Array.from(
wistia_vid.querySelectorAll(".wistia__overlay, .embed-youtube__play, .embed-video__play")
);
toRemove.forEach((node) => node.remove());
};
Array.from(document.querySelectorAll(".wistia")).forEach((node) => {
node.addEventListener("click", () => {
const videoId = getVideoId(node);
let wistiaSupportScripts = [
//adds jsonp file to provide security over requests
`https://fast.wistia.com/embed/medias/${videoId}.jsonp`
];
removeElems(node);
//Checks if above scripts are already loaded, and if they are... they won't be loaded again
const id = 'script-ev1';
if (!document.getElementById(id)) {
// const id = 'script-ev1';
var script = document.createElement('script');
script.id = id;
script.onload = () => {
console.log('Ev-1.js loaded and ready to go!');
};
script.src = `https://fast.wistia.com/assets/external/E-v1.js` ;
document.getElementsByTagName('head')[0].appendChild(script);
} else {
console.log(`Ev-1.js script with id: ${videoId} already loaded.`);
}
//loads supporting scripts into head
for (var i = 0; i < wistiaSupportScripts.length; i++) {
let wistiaSupportScript = document.createElement("script");
wistiaSupportScript.src = wistiaSupportScripts[i];
let complete = false;
if (
!complete &&
(!this.readyState ||
this.readyState == "loaded" ||
this.readyState == "complete")
) {
complete = true;
console.log(`JSONP script was added.`);
}
let wistiaContainers = document.querySelector(".wistia");
wistiaContainers ? document.getElementsByTagName("head")[0].appendChild(wistiaSupportScript) : console.log("No Wistia videos here.");
}
window._wq = window._wq || [];
_wq.push({
//globally scoped
id: videoId,
options: {
autoPlay: true,
volume: 0.5
},
onReady: function (video) {
playedOnce = true;
video.popover.show();
video.play();
}
});
});
});
.wistia {
position: relative;
display: block;
width: 100%;
max-width: 500px;
padding: 0;
overflow: hidden;
cursor: pointer;
}
.wistia__overlay {
width: 100%;
height: auto;
}
.wistia::before {
display: block;
content: "";
}
.wistia button.embed-youtube__play {
background: url("https://nextiva.com/assets/svg/play-button.svg") no-repeat center center, rgba(33, 33, 33, 0.8);
background-size: 40%;
background-position: 55%;
border: 0;
border-radius: 50%;
position: absolute;
transition: all 0.2s ease;
-webkit-transition: background 0.2s;
width: 10%;
aspect-ratio: 1/1;
max-height: 15%;
cursor: pointer;
z-index: 10;
display: flex;
justify-content: center;
align-items: center;
top: 50%;
left: 50%;
transform: translate3d(-50%, -50%, 0);
}
.wistia:hover button.embed-youtube__play,
.wistia button.embed-youtube__play:focus-visible,
.wistia button.embed-youtube__play:focus {
background: url("https://nextiva.com/assets/svg/play-button.svg") no-repeat center center, #005fec;
background-size: 40%;
background-position: 55%;
}
.wistia_embed,
.wistia embed,
.wistia iframe {
width: 100%;
max-height: 100%;
}
<div class="wistia">
<picture>
<source srcset="https://embedwistia-a.akamaihd.net/deliveries/48f1d62d1ceddb4284ad9cf67c916235.jpg?auto=format&w=640" media="(min-width: 1200px)">
<source srcset="https://embedwistia-a.akamaihd.net/deliveries/48f1d62d1ceddb4284ad9cf67c916235.jpg?auto=format&w=310" media="(min-width: 768px)">
<img src="https://embedwistia-a.akamaihd.net/deliveries/48f1d62d1ceddb4284ad9cf67c916235.jpg?auto=format&w=310" alt="some text" class="wistia__overlay lazy" loading="lazy">
</picture>
<div class="wistia_embed wistia_async_vhkqhqhzyq videoFoam=true"></div>
<button class="embed-youtube__play"></button>
</div>
<div class="wistia">
<picture>
<source srcset="https://embed-fastly.wistia.com/deliveries/2eab84ad71cf5acd9c7572d36667d255.jpg?auto=format&w=640" media="(min-width: 1200px)">
<source srcset="https://embed-fastly.wistia.com/deliveries/2eab84ad71cf5acd9c7572d36667d255.jpg?auto=format&w=310" media="(min-width: 768px)">
<img src="https://embed-fastly.wistia.com/deliveries/2eab84ad71cf5acd9c7572d36667d255.jpg?auto=format&w=310" alt="Some text" class="wistia__overlay lazy" loading="lazy">
</picture>
<div class="wistia_embed wistia_async_8ei13wuby7 videoFoam=true"></div>
<button class="embed-youtube__play"></button>
</div>
Put this in your CSS:
.wistia_embed {
display: none;
}
.wistia.shown .wistia_embed {
display: block;
}
Then, put this in your JS:
if (!node.classList.contains("shown")) {
node.classList.add("shown");
} else {
return;
}
Right in the beginning of the event listener function.
Explanation
The E-v1.js script shows all the videos at once, when you load this script by the first click with this piece of code:
const id = 'script-ev1';
if (!document.getElementById(id)) {
// const id = 'script-ev1';
var script = document.createElement('script');
script.id = id;
script.onload = () => {
console.log('Ev-1.js loaded and ready to go!');
};
script.src = `https://fast.wistia.com/assets/external/E-v1.js`;
document.getElementsByTagName('head')[0].appendChild(script);
} else {
console.log(`Ev-1.js script with id: ${videoId} already loaded.`);
}
Before you load this script, there are no videos as is, just the <source> elements. You never indicate with you CSS that videos should be invisible; henceforth, they are visible by default, once the E-v1.js script loads them.
Now, when you add this CSS snippet above, you indicate that .wistia_embed elements, which are basically the loaded videos, have to be invisible from the beginning.
With this single line of JS code, only one video will be revealed on click (setting .shown class, which contains display: block; attribute for the .wistia_embed).
Undefined video.popover
I don't know Wistia API that much, but the browser tells that there is no video.popover.show() function. Remove this from your code as well, otherwise the second video won't auto-play by clicking on it.
onReady: function (video) {
playedOnce = true;
video.popover.show(); // remove
video.play();
}
Full working code
const getVideoId = (wistia_vid) => {
const classes = Array.from(wistia_vid.querySelector(".wistia_embed").classList);
const idClass = classes.find((cls) => cls.startsWith("wistia_async_"));
const id = idClass.replace("wistia_async_", "");
return id;
};
const removeElems = (wistia_vid) => {
const toRemove = Array.from(
wistia_vid.querySelectorAll(".wistia__overlay, .embed-youtube__play, .embed-video__play")
);
toRemove.forEach((node) => node.remove());
};
Array.from(document.querySelectorAll(".wistia")).forEach((node) => {
node.addEventListener("click", () => {
if (!node.classList.contains("shown")) {
node.classList.add("shown");
} else {
return;
}
const videoId = getVideoId(node);
let wistiaSupportScripts = [
//adds jsonp file to provide security over requests
`https://fast.wistia.com/embed/medias/${videoId}.jsonp`
];
removeElems(node);
//Checks if above scripts are already loaded, and if they are... they won't be loaded again
const id = 'script-ev1';
if (!document.getElementById(id)) {
// const id = 'script-ev1';
var script = document.createElement('script');
script.id = id;
script.onload = () => {
console.log('Ev-1.js loaded and ready to go!');
};
script.src = `https://fast.wistia.com/assets/external/E-v1.js`;
document.getElementsByTagName('head')[0].appendChild(script);
} else {
console.log(`Ev-1.js script with id: ${videoId} already loaded.`);
}
//loads supporting scripts into head
for (var i = 0; i < wistiaSupportScripts.length; i++) {
let wistiaSupportScript = document.createElement("script");
wistiaSupportScript.src = wistiaSupportScripts[i];
let complete = false;
if (
!complete &&
(!this.readyState ||
this.readyState == "loaded" ||
this.readyState == "complete")
) {
complete = true;
console.log(`JSONP script was added.`);
}
let wistiaContainers = document.querySelector(".wistia");
wistiaContainers ? document.getElementsByTagName("head")[0].appendChild(wistiaSupportScript) : console.log("No Wistia videos here.");
}
window._wq = window._wq || [];
_wq.push({
//globally scoped
id: videoId,
options: {
autoPlay: true,
volume: 0.5
},
onReady: function (video) {
playedOnce = true;
video.play();
}
});
});
});
.wistia {
position: relative;
display: block;
width: 100%;
max-width: 500px;
padding: 0;
overflow: hidden;
cursor: pointer;
}
.wistia__overlay {
width: 100%;
height: auto;
}
.wistia::before {
display: block;
content: "";
}
.wistia button.embed-youtube__play {
background: url("https://nextiva.com/assets/svg/play-button.svg") no-repeat center center, rgba(33, 33, 33, 0.8);
background-size: 40%;
background-position: 55%;
border: 0;
border-radius: 50%;
position: absolute;
transition: all 0.2s ease;
-webkit-transition: background 0.2s;
width: 10%;
aspect-ratio: 1/1;
max-height: 15%;
cursor: pointer;
z-index: 10;
display: flex;
justify-content: center;
align-items: center;
top: 50%;
left: 50%;
transform: translate3d(-50%, -50%, 0);
}
.wistia:hover button.embed-youtube__play,
.wistia button.embed-youtube__play:focus-visible,
.wistia button.embed-youtube__play:focus {
background: url("https://nextiva.com/assets/svg/play-button.svg") no-repeat center center, #005fec;
background-size: 40%;
background-position: 55%;
}
.wistia_embed,
.wistia embed,
.wistia iframe {
width: 100%;
max-height: 100%;
}
.wistia_embed {
display: none;
}
.wistia.shown .wistia_embed {
display: block;
}
<div class="wistia">
<picture>
<source
srcset="https://embedwistia-a.akamaihd.net/deliveries/48f1d62d1ceddb4284ad9cf67c916235.jpg?auto=format&w=640"
media="(min-width: 1200px)">
<source
srcset="https://embedwistia-a.akamaihd.net/deliveries/48f1d62d1ceddb4284ad9cf67c916235.jpg?auto=format&w=310"
media="(min-width: 768px)">
<img src="https://embedwistia-a.akamaihd.net/deliveries/48f1d62d1ceddb4284ad9cf67c916235.jpg?auto=format&w=310"
alt="some text" class="wistia__overlay lazy" loading="lazy">
</picture>
<div class="wistia_embed wistia_async_vhkqhqhzyq videoFoam=true"></div>
<button class="embed-youtube__play"></button>
</div>
<div class="wistia">
<picture>
<source
srcset="https://embed-fastly.wistia.com/deliveries/2eab84ad71cf5acd9c7572d36667d255.jpg?auto=format&w=640"
media="(min-width: 1200px)">
<source
srcset="https://embed-fastly.wistia.com/deliveries/2eab84ad71cf5acd9c7572d36667d255.jpg?auto=format&w=310"
media="(min-width: 768px)">
<img src="https://embed-fastly.wistia.com/deliveries/2eab84ad71cf5acd9c7572d36667d255.jpg?auto=format&w=310"
alt="Some text" class="wistia__overlay lazy" loading="lazy">
</picture>
<div class="wistia_embed wistia_async_8ei13wuby7 videoFoam=true"></div>
<button class="embed-youtube__play"></button>
</div>

don't show pop-up again if it closed using javascript

How can I stop showing pop-up after clicking on close button?
This is my pop-up function, it opens after scrolling to 1300px of page.
$(document).scroll(function() {
var y = $(this).scrollTop();
if (y > 1300) {
$('.popup').fadeIn();
}
});
but when I closed it , it opend again
this is my button fun
function closePopup(){
document.getElementById('popup').style.display = 'none';
}
++ this is my button
<button type="button" class="close" id="close-popup" onclick="closePopup()" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
You can add a boolean control when it's clicked
let popupClosed = false;
function closePopup() {
document.getElementById('popup').style.display = 'none';
popupClosed = true;
}
$(document).scroll(function() {
var y = $(this).scrollTop();
if (y > 1300 && !popupClosed) {
$('.popup').fadeIn();
}
});
You need a way to control when the popup was opened for the first time (or closed).
$(document).scroll(function() {
let y = $(this).scrollTop(),
popup = $('.popup')
if (y > 1300 && ! popup.data('opened')) {
popup.data('opened', true)
popup.fadeIn();
}
});
I replaced your scroll height detection with a button. Just call $('.popup').popupShow() whenever you scroll past 1,300 pixels.
Make sure you call $('.popup').popup(options) with the appropriate close/open callbacks.
Once you close the popup for the first time, a data attribute of doNotOpen will be set to true. Subsequent open attempts will not be allowed, because the open callback checks for the presence of that doNotOpen data value.
function main() {
$('.popup').popup({
title: 'Popup Test',
open: function() {
return !this.data('doNotOpen'); // type boolean
},
close: function() {
this.data('doNotOpen', true);
}
});
$('.show-btn').on('click', function() {
$('.popup').popupShow();
});
}
/**
* #name flex-popup.jquery.js
* #date 2021-03-03
* #author Mr. Polywhirl
*
* Callback when opening a popup.
* #callback openCallback
* #return {boolean} whether to show the popup
*
* Callback when closing a popup.
* #callback closeCallback
*/
(function($) {
var defaultOptions = {
title: null,
content: null
};
var setAndDelete = function($el, prop, props) {
if (props[prop]) {
$el.html(props[prop]);
delete props[prop];
}
};
/**
* #param {string} title
* #param {string} content
* #param {options.openCallback} open
* #param {options.closeCallback} close
*/
$.fn.popup = function(options) {
var opts = $.extend(true, {}, defaultOptions, options);
if (this.is(':empty')) this.popupCreate();
this.find('.popup-close').on('click', function() {
$(this).closest('.popup').popupHide();
});
setAndDelete(this.find('.popup-header-title'), 'title', opts);
setAndDelete(this.find('.popup-content'), 'content', opts);
return this.data(opts).css('display', 'flex').hide();
};
$.fn.popupCreate = function() {
return this
.append($('<div>').addClass('popup-header')
.append($('<div>').addClass('popup-header-title'))
.append($('<div>').addClass('popup-close')))
.append($('<div>').addClass('popup-content'));
};
$.fn.popupShow = function() {
if (this.is(':hidden') && (!this.data('open') || this.data('open').call(this))) {
if (this.data('open')) this.data('open').call(this);
return this.fadeIn();
} else {
if (this.is(':hidden')) {
console.log('Not allowed!');
}
}
};
$.fn.popupHide = function() {
if (!this.is(':hidden')) {
if (this.data('close')) this.data('close').call(this);
return this.fadeOut();
}
};
})(jQuery);
main();
:root {
--popup-background: #AAA;
--popup-header-background: #777;
--popup-content-background: #AAA;
--popup-border-color: #555;
--popup-close-color: #BBB;
--popup-close-hover-color: #DDD;
}
body {
background: #222;
}
.popup {
display: flex;
flex-direction: column;
position: absolute;
top: 25vh;
left: 25vw;
width: 50vw;
height: 50vh;
z-index: 1000;
background: var(--popup-background);
border: thin solid var(--popup-border-color);
}
.popup>.popup-header {
display: flex;
flex-direction: row;
align-items: center;
background: var(--popup-header-background);
padding: 0.25em 0.5em;
}
.popup .popup-header-title {
flex: 1;
text-align: center;
font-weight: bold;
}
.popup .popup-close {
font-size: 2em;
line-height: 1em;
font-weight: bold;
color: var(--popup-close-color);
}
.popup .popup-close:hover {
color: var(--popup-close-hover-color);
cursor: pointer;
}
.popup .popup-close::after {
content: '\00D7';
}
.popup>.popup-content {
background: var(--popup-content-background);
flex: 1;
padding: 0.25em 0.5em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="popup">
<div class="popup-header">
<div class="popup-header-title">Replace this</div>
<div class="popup-close"></div>
</div>
<div class="popup-content">
<h1>Content heading</h1>
<p>Content description here.</p>
</div>
</div>
<button class="show-btn">Show Popup</button>
Note: Here is a mirror on JSFiddle.

Next slide button

I'm having trouble putting a button on the next slide, the mouse and keys of any keyboard works, but wanted to put a button or 2, one to go back and another to move on, I thought of a timer but the success rate was 0% , I'm a good time trying but this really hard, if anyone can help me in this, would help me a lot
/*********************
* Helpers Code
********************/
/**
* #function DOMReady
*
* #param callback
* #param element
* #param listener
* #returns {*}
* #constructor
*/
const DOMReady = ((
callback = () => {},
element = document,
listener = 'addEventListener'
) => {
return (element[listener]) ? element[listener]('DOMContentLoaded', callback) : window.attachEvent('onload', callback);
});
/**
* #function ProjectAPI
*
* #type {{hasClass, addClass, removeClass}}
*/
const ProjectAPI = (() => {
let hasClass,
addClass,
removeClass;
hasClass = ((el, className) => {
if (el === null) {
return;
}
if (el.classList) {
return el.classList.contains(className);
}
else {
return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
}
});
addClass = ((el, className) => {
if (el === null) {
return;
}
if (el.classList) {
el.classList.add(className);
}
else if (!hasClass(el, className)) {
el.className += ' ' + className
}
});
removeClass = ((el, className) => {
if (el === null) {
return;
}
if (el.classList) {
el.classList.remove(className);
}
else if (hasClass(el, className)) {
let reg = new RegExp('(\\s|^)' + className + '(\\s|$)');
el.className = el.className.replace(reg, ' ');
}
});
return {
hasClass: hasClass,
addClass: addClass,
removeClass: removeClass
};
})();
/*********************
* Application Code
********************/
/**
* #function readyFunction
*
* #type {Function}
*/
const readyFunction = (() => {
const KEY_UP = 38;
const KEY_DOWN = 40;
let scrollingClass = 'js-scrolling',
scrollingActiveClass = scrollingClass + '--active',
scrollingInactiveClass = scrollingClass + '--inactive',
scrollingTime = 1350,
scrollingIsActive = false,
currentPage = 1,
countOfPages = document.querySelectorAll('.' + scrollingClass + '__page').length,
prefixPage = '.' + scrollingClass + '__page-',
_switchPages,
_scrollingUp,
_scrollingDown,
_mouseWheelEvent,
_keyDownEvent,
init;
/**
* #function _switchPages
*
* #private
*/
_switchPages = () => {
let _getPageDomEl;
/**
* #function _getPageDomEl
*
* #param page
* #returns {Element}
* #private
*/
_getPageDomEl = (page = currentPage) => {
return document.querySelector(prefixPage + page);
};
scrollingIsActive = true;
ProjectAPI.removeClass(
_getPageDomEl(),
scrollingInactiveClass
);
ProjectAPI.addClass(
_getPageDomEl(),
scrollingActiveClass
);
ProjectAPI.addClass(
_getPageDomEl(currentPage - 1),
scrollingInactiveClass
);
ProjectAPI.removeClass(
_getPageDomEl(currentPage + 1),
scrollingActiveClass
);
setTimeout(
() => {
return scrollingIsActive = false;
},
scrollingTime
);
};
/**
* #function _scrollingUp
*
* #private
*/
_scrollingUp = () => {
if (currentPage === 1) {
return;
}
currentPage--;
_switchPages();
};
/**
* #function _scrollingDown
*
* #private
*/
_scrollingDown = () => {
if (currentPage === countOfPages) {
return;
}
currentPage++;
_switchPages();
};
/**
* #function _mouseWheelEvent
*
* #param e
* #private
*/
_mouseWheelEvent = (e) => {
if (scrollingIsActive) {
return;
}
if (e.wheelDelta > 0 || e.detail < 0) {
_scrollingUp();
}
else if (e.wheelDelta < 0 || e.detail > 0) {
_scrollingDown();
}
};
/**
* #function _keyDownEvent
*
* #param e
* #private
*/
_keyDownEvent = (e) => {
if (scrollingIsActive) {
return;
}
let keyCode = e.keyCode || e.which;
if (keyCode === KEY_UP) {
_scrollingUp();
}
else if (keyCode === KEY_DOWN) {
_scrollingDown();
}
};
/**
* #function init
*
* #note auto-launch
*/
init = (() => {
document.addEventListener(
'mousewheel',
_mouseWheelEvent,
false
);
document.addEventListener(
'DOMMouseScroll',
_mouseWheelEvent,
false
);
document.addEventListener(
'keydown',
_keyDownEvent,
false
);
})();
});
/**
* Launcher
*/
DOMReady(readyFunction);
/***********************
* Variables
**********************/
/***********************
* Project Main Styles
**********************/
*,
*:before,
*:after {
box-sizing: border-box;
margin: 0;
padding: 0; }
body {
font-family: "Open Sans", sans-serif;
background-color: #282828; }
.slider-pages {
overflow: hidden;
position: relative;
zoom: 59%;
width: 94%;
left: 3%;
height: 100vh; }
.slider-page {
position: absolute;
top: 0;
width: 50%;
height: 100vh;
transition: transform 1350ms; }
.slider-page--skew {
overflow: hidden;
position: absolute;
top: 0;
width: 140%;
height: 100%;
background: #282828;
transform: skewX(-18deg); }
.slider-page--left {
left: 0;
transform: translateX(-32.5vh) translateY(100%) translateZ(0); }
.slider-page--left .slider-page--skew {
left: -40%; }
.slider-page--left .slider-page__content {
padding: auto 30% auto 30%;
transform-origin: 100% 0; }
.slider-page--right {
left: 50%;
transform: translateX(32.5vh) translateY(-100%) translateZ(0); }
.slider-page--right .slider-page--skew {
right: -40%; }
.slider-page--right .slider-page__content {
padding: auto 30% auto 30%;
transform-origin: 0 100%; }
.slider-page__content {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
flex-flow: column wrap;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 0 30% 0 30%;
color: #e2e2e2;
background-size: cover;
transform: skewX(18deg);
transition: transform 1350ms; }
.slider-page__title {
margin-bottom: 1em;
font-size: 1em;
text-align: center;
text-transform: uppercase; }
.slider-page__title--big {
font-size: 1.2em; }
.slider-page__description {
font-size: 1em;
text-align: center; }
.slider-page__link {
color: #80a1c1; }
.slider-page__link:hover, .slider-page__link:focus {
color: #6386a9;
text-decoration: none; }
/***********************
* Project JS Styles
**********************/
.js-scrolling__page {
position: absolute;
top: 0;
left: 0;
width: 100%; }
.js-scrolling--active .slider-page {
transform: translateX(0) translateY(0) translateZ(0); }
.js-scrolling--inactive .slider-page__content {
transform: skewX(18deg) scale(0.9); }
.js-scrolling__page-1 .slider-page--left .slider-page__content {
background-image: url("https://cdn.discordapp.com/attachments/584536200052867077/687769359183380537/ram-of-re-zero-starting-life-in-another-world-wallpaper-3440x1440-2148_15.png"); }
.js-scrolling__page-1 .slider-page--right .slider-page__content {
background-color: #282828; }
.js-scrolling__page-2 .slider-page--left .slider-page__content {
background-color: #e2e2e2; }
.js-scrolling__page-2 .slider-page--left .slider-page__title,
.js-scrolling__page-2 .slider-page--left .slider-page__description {
color: #282828; }
.js-scrolling__page-2 .slider-page--right .slider-page__content {
background-image: url("https://cdn.discordapp.com/attachments/584536200052867077/687766774950789160/9ibz1cnnwdp31.png"); }
.js-scrolling__page-3 .slider-page--left .slider-page__content {
background-image: url("https://cdn.discordapp.com/attachments/584536200052867077/687773688782913563/9ibz1cnnwdp31.png"); }
.js-scrolling__page-3 .slider-page--right .slider-page__content {
background-color: #282828; }
<section class="slider-pages">
<article class="js-scrolling__page js-scrolling__page-1 js-scrolling--active">
<div class="slider-page slider-page--left">
<div class="slider-page--skew">
<div class="slider-page__content">
</div>
<!-- /.slider-page__content -->
</div>
<!-- /.slider-page--skew -->
</div>
<!-- /.slider-page slider-page--left -->
<div class="slider-page slider-page--right">
<div class="slider-page--skew">
<div class="slider-page__content">
<h1 class="slider-page__title slider-page__title--big">
Re:Zero kara Hajimeru Isekai Seikatsu
</h1>
<!-- /.slider-page__title slider-page__title--big -->
<h2 class="slider-page__title">
</h2>
<!-- /.slider-page__title -->
<p class="slider-page__description">
End
</p>
<!-- /.slider-page__description -->
</div>
<!-- /.slider-page__content -->
</div>
<!-- /.slider-page--skew -->
</div>
<!-- /.slider-page slider-page--right -->
</article>
<!-- /.js-scrolling__page js-scrolling__page-1 js-scrolling--active -->
<article class="js-scrolling__page js-scrolling__page-2">
<div class="slider-page slider-page--left">
<div class="slider-page--skew">
<div class="slider-page__content">
<h1 class="slider-page__title">
EVANGELION 3.0 + 1.0
</h1>
<!-- /.slider-page__title -->
<p class="slider-page__description">
ENd
</p>
<!-- /.slider-page__description -->
</div>
<!-- /.slider-page__content -->
</div>
<!-- /.slider-page--skew -->
</div>
<!-- /.slider-page slider-page--left -->
<div class="slider-page slider-page--right">
<div class="slider-page--skew">
<div class="slider-page__content">
</div>
<!-- /.slider-page__content -->
</div>
<!-- /.slider-page--skew -->
</div>
<!-- /.slider-page slider-page--right -->
</article>
<!-- /.js-scrolling__page js-scrolling__page-2 -->
You can use the functions you already defined, namely _scrollingUp and _scrollingDown, and assign them to your buttons' onclick events. By doing this, these functions will be called whenever the right button is clicked.
A simplified example would be:
document.getElementById("prev").onclick = _scrollingUp;
document.getElementById("next").onclick = _scrollingDown;
<button id="prev">Previous</button>
<button id="next">Next</button>

Youtube video as div background not working with all videos

I am making use of the following solution for using a Youtube video as a website div background: https://stackoverflow.com/a/45377998
A JSFiddle example can be found in https://jsfiddle.net/350D/uq1vvavf/
The problem I am currently having is that not all videos will be shown. For example, the video in the JSFiddle works properly (https://www.youtube.com/watch?v=R3AKlscrjmQ). However, this video, for example will not work: https://www.youtube.com/watch?v=V5YOhcAof8I
I suspect this may have to do with the signal format (720p, 360p, etc.). I have made an attempt to debug the problem and found that a link for the non-working Youtube video is still returned within the streams array (just like the working video). I appreciate any hints to solving the problem.
HTML:
<video loop muted autoplay playsinline id="video"></video>
<pre></pre>
JS:
var vid = "R3AKlscrjmQ",
streams,
video_focused = true,
video_tag = $("#video"),
video_obj = video_tag.get(0);
$.getJSON("https://query.yahooapis.com/v1/public/yql", {
q: "select * from csv where url='https://www.youtube.com/get_video_info?video_id=" + vid + "'",
format: "json"
}, function(data) {
if (data.query.results && !data.query.results.row.length) {
streams = parse_youtube_meta(data.query.results.row.col0);
video_tag.attr({
src: streams['1080p'] || streams['720p'] || streams['360p']
});
document.addEventListener("visibilitychange", function() {
video_focused = !video_focused ? video_obj.play() : video_obj.pause();
});
} else {
$('pre').text('YQL request error...');
}
});
function parse_youtube_meta(rawdata) {
var data = parse_str(rawdata),
streams = (data.url_encoded_fmt_stream_map + ',' + data.adaptive_fmts).split(','),
result = {};
$.each(streams, function(n, s) {
var stream = parse_str(s),
itag = stream.itag * 1,
quality = false,
itag_map = {
18: '360p',
22: '720p',
37: '1080p',
38: '3072p',
82: '360p3d',
83: '480p3d',
84: '720p3d',
85: '1080p3d',
133: '240pna',
134: '360pna',
135: '480pna',
136: '720pna',
137: '1080pna',
264: '1440pna',
298: '720p60',
299: '1080p60na',
160: '144pna',
139: "48kbps",
140: "128kbps",
141: "256kbps"
};
//if (stream.type.indexOf('o/mp4') > 0) console.log(stream);
if (itag_map[itag]) result[itag_map[itag]] = stream.url;
});
return result;
};
function parse_str(str) {
return str.split('&').reduce(function(params, param) {
var paramSplit = param.split('=').map(function(value) {
return decodeURIComponent(value.replace('+', ' '));
});
params[paramSplit[0]] = paramSplit[1];
return params;
}, {});
}
As a workaround for now I used following solution https://codepen.io/henripeetsmann/pen/KpVVLq thanks to Henri Peetsmann. For me this works fine, even when changing the URL to one from Youtube. The only downside of using Youtube is that now you can't hide related video's when pausing. So I had to cover this part with something else.
HTML
<div class="videobg">
<div class="videobg-width">
<div class="videobg-aspect">
<div class="videobg-make-height">
<div class="videobg-hide-controls">
<iframe src="https://player.vimeo.com/video/8970192?autoplay=1&loop=1&title=0&byline=0&portrait=0" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
</div>
</div>
</div>
</div>
CSS
/* Quick reset */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Make elements as high as viewport */
html {
height: 100%;
}
body {
position: relative;
height: 100%;
}
/* Video background */
.videobg {
position: relative;
width: 100%; /* Set video container element width here */
height: 100%; /* Set video container element height here */
overflow: hidden;
background: #111; /* bg color, if video is not high enough */
}
/* horizontally center the video */
.videobg-width {
position: absolute;
width: 100%; /* Change width value to cover more area*/
height: 100%;
left: -9999px;
right: -9999px;
margin: auto;
}
/* set video aspect ratio and vertically center */
.videobg-aspect {
position: absolute;
width: 100%;
height: 0;
top: -9999px;
bottom: -9999px;
margin: auto;
padding-bottom: 56.25%; /* 16:9 ratio */
overflow: hidden;
}
.videobg-make-height {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
}
.videobg-hide-controls {
box-sizing: content-box;
position: relative;
height: 100%;
width: 100%;
/* Vimeo timeline and play button are ~55px high */
padding: 55px 97.7777px; /* 16:9 ratio */
top: -55px;
left: -97.7777px; /* 16:9 ratio */
}
.videobg iframe {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
border: 0 none;
}
jQuery
var timeoutId;
var $videoBgAspect = $(".videobg-aspect");
var $videoBgWidth = $(".videobg-width");
var videoAspect = $videoBgAspect.outerHeight() / $videoBgAspect.outerWidth();
function videobgEnlarge() {
console.log('resize');
windowAspect = ($(window).height() / $(window).width());
if (windowAspect > videoAspect) {
$videoBgWidth.width((windowAspect / videoAspect) * 100 + '%');
} else {
$videoBgWidth.width(100 + "%")
}
}
$(window).resize(function() {
clearTimeout(timeoutId);
timeoutId = setTimeout(videobgEnlarge, 100);
});
$(function() {
videobgEnlarge();
});

Categories