<div class="background-fullscreen--idle background-fullscreen" data-background-image="../../.html">
</div>
<div class="background-fullscreen--idle background-fullscreen" data-background-image="{{ path '{{backgroundImagePath}}' }}">
{{#if selfHostVideoPath}}
<video class="background-fullscreen__video" data-videopath={{ selfHostVideoPath }} type="video/mp4" autoplay muted loop playsinline>
</video>
{{/if}}
{{#if youtubeid}}
<div class="youtube__iframe-wrapper" data-youtubeid="{{youtubeid}}">
</div>
{{/if}}
{{#if vimeoid}}
<iframe class="iframe vimeo__iframe" data-vimeoid="{{vimeoid}}"
frameborder="0"
webkitallowfullscreen
mozallowfullscreen
allowfullscreen
>
</iframe>
{{/if}}
</div>
/* No context defined for this component. */
'use strict';
var novicell = novicell || {};
novicell.pageheaderVideoFullscreenSelfHost =
novicell.pageheaderVideoFullscreenSelfHost ||
new function () {
this.init = function () {
if (screenWidth()) {
const fullscreenBackground = document.querySelector(".background-fullscreen") || false;
if (fullscreenBackground) {
// Remove class associated with background image
fullscreenBackground.classList.remove("background-fullscreen--idle");
// Add class associated with ajax gif loader
fullscreenBackground.classList.add("background-fullscreen--loading");
}
const videoList = document.querySelectorAll(".background-fullscreen__video") || false;
this.removeAjaxLoader = function (element) {
// Function for removing the class associated with the ajax loading gif.
element.classList.remove("background-fullscreen--loading");
};
if (videoList) {
// Make the data-videopath the actual src of the video element
for (let i = 0; i < videoList.length; i++) {
videoList[i].src = videoList[i].dataset.videopath;
// Remove ajax loader when play event triggers
videoList[i].addEventListener("play", () => {
novicell.pageheaderVideoFullscreenSelfHost.removeAjaxLoader(fullscreenBackground);
})
}
}
}
};
}();
function screenWidth() {
return window.screen.width > 768;
}
'use strict';
var novicell = novicell || {};
novicell.pageheaderVideoFullscreenVimeo =
novicell.pageheaderVideoFullscreenVimeo ||
new function () {
this.init = function () {
if (screenWidth()) {
const fullscreenBackground = document.querySelector(".background-fullscreen") || false;
if (fullscreenBackground) {
// Remove class associated with background image
fullscreenBackground.classList.remove("background-fullscreen--idle");
// Add class associated with ajax gif loader
fullscreenBackground.classList.add("background-fullscreen--loading");
}
const vimeoIframeList = document.querySelector(".vimeo__iframe") || false;
this.removeAjaxLoader = function (element) {
// Function for removing the class associated with the ajax loading gif.
element.classList.remove("background-fullscreen--loading");
};
if (vimeoIframeList) {
const vimeoId = vimeoIframeList.dataset.vimeoid;
const fullUrl = `https://player.vimeo.com/video/${vimeoId}?autoplay=1&loop=1&color=000000&title=0&byline=0&portrait=0&muted=1&controls=0&background=1`;
const shortUrl = `https://vimeo.com/${vimeoId}`;
validateVimeoId(shortUrl)
.then(response => {
if (response === 200) {
// Load video if the vimeo id exists
vimeoIframeList.src = fullUrl;
} else {
// If bad status, we remove the iframe and add the fallback BG image
fullscreenBackground.style.backgroundImage = `url(${fullscreenBackground.dataset.backgroundImage})`;
vimeoIframeList.remove();
}
}).then(() => {
// As we are not using the vimeo API, we can't listen for events on the Iframe.
// Consequently, I've had to make a guesstimate on when's a relatively good time to remove the ajax loader
setTimeout(() => {
novicell.pageheaderVideoFullscreenVimeo.removeAjaxLoader(fullscreenBackground);
}, 5000);
}).catch(err => console.log(err));
}
}
};
}();
function screenWidth() {
return window.screen.width > 768;
}
// Function for checking vimeo video validity
function validateVimeoId(url) {
let options = {
method: 'GET'
};
// Anything but status 200 will throw an error
return fetch(`https://vimeo.com/api/oembed.json?url=${encodeURIComponent(url)}`, options)
.then((response) => {
if (response.status === 200) {
return response.status;
} else {
throw Error(`Bad response: ${response.status}`);
}
})
.catch(err => console.log(err));
}
'use strict';
var novicell = novicell || {};
novicell.pageheaderVideoFullscreenYT =
novicell.pageheaderVideoFullscreenYT ||
new function () {
this.init = function () {
if (screenWidth()) {
const fullscreenBackground = document.querySelector(".background-fullscreen") || false;
if (fullscreenBackground) {
// Remove class associated with background image
fullscreenBackground.classList.remove("background-fullscreen--idle");
// Add class associated with ajax gif loader
fullscreenBackground.classList.add("background-fullscreen--loading");
}
const youtubeIframeList = document.querySelector(".youtube__iframe-wrapper") || false;
this.removeAjaxLoader = function (element) {
// Function for removing the class associated with the ajax loading gif.
element.classList.remove("background-fullscreen--loading");
};
if (youtubeIframeList) {
let videoStart = 0;
let youtubeid = youtubeIframeList.dataset.youtubeid;
let tag = document.createElement("script");
tag.src = "https://www.youtube.com/player_api";
let lastScriptTag = document.getElementsByTagName("script")[
document.getElementsByTagName("script").length - 1
];
lastScriptTag.parentNode.insertBefore(tag, lastScriptTag);
this.changeCaseState = function (e) {
// Already written as switch case as there are more possibilities that might be implemented in the future.
// In this case, we remove the background gif when the video starts playing.
// See list of available cases on official YT embed docs on Playback_status
switch (e.data) {
// Case 1 is "video is playing"
case 1:
{
novicell.pageheaderVideoFullscreenYT.removeAjaxLoader(fullscreenBackground);
break;
}
}
};
this.onPlayerReady = function (event) {
event.target.mute();
event.target.seekTo(videoStart);
};
this.onErrorResponse = function (event) {
// In case of bad response, kill the player and add the background image.
// Currently, the url for the BG image is stored on the background-fullscreen wrapper itself.
// An alternative would be having a css class added that holds a background image attribute and the path value already, and simply append the classname to the element
fullscreenBackground.style.backgroundImage = `url(${fullscreenBackground.dataset.backgroundImage})`;
event.target.destroy();
novicell.pageheaderVideoFullscreenYT.removeAjaxLoader(fullscreenBackground);
};
this.onYouTubeFullscreenIframeAPIReady = function () {
let player = new YT.Player(youtubeIframeList, {
videoId: youtubeid,
playerVars: {
autoplay: 1,
autohide: 1,
loop: 1,
// Playlist is required, otherwise the video refuses to loop for some reason
playlist: youtubeid,
modestbranding: 1,
rel: 0,
controls: 0,
disablekb: 1,
enablejsapi: 0,
iv_load_policy: 3
},
events: {
onReady: novicell.pageheaderVideoFullscreenYT.onPlayerReady,
onError: novicell.pageheaderVideoFullscreenYT.onErrorResponse,
onStateChange: novicell.pageheaderVideoFullscreenYT.changeCaseState
}
});
};
window.addEventListener(
"load",
function () {
novicell.pageheaderVideoFullscreenYT.onYouTubeFullscreenIframeAPIReady();
},
true
);
}
}
};
}();
function screenWidth() {
return window.screen.width > 768;
}
/**
* Component: pageheader-video-fullscreen
*/
.background-fullscreen {
/* Position it relative if you want to be able to scroll below the video */
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: -1;
pointer-events: none;
overflow: hidden;
background-size: cover;
background-image: none;
&--idle {
background-image: url("/dist/images/placeholder-images/hero--mona-eendra-313518.jpg");
}
&--loading {
background-image: url("/dist/images/outro_2-loader.gif");
background-size: auto;
background-repeat: no-repeat;
background-position: center;
}
& iframe {
width: 100vw;
height: 56.25vw;
/* Given a 16:9 aspect ratio, 9/16*100 = 56.25 */
min-height: 100vh;
min-width: 190vh;
/* Given a 16:9 aspect ratio, 16/9*100 = 177.77 */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
&__video {
position: fixed;
right: 0;
bottom: 0;
min-width: 100%;
min-height: 100%;
}
&__foreground {
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
font-size: 1.7em;
text-decoration: overline underline;
}
}
In production, consider having preconnect links in the head for faster connection with YT and Vimeo:
link rel=”preconnect” href=”https://player.vimeo.com"
link rel=”preconnect” href=”https://www.youtube.com"