Skip to content

Instantly share code, notes, and snippets.

@bpb54321
Last active June 4, 2018 00:01
Show Gist options
  • Save bpb54321/0110de84fff8846b99d6c206f1d4873d to your computer and use it in GitHub Desktop.
Save bpb54321/0110de84fff8846b99d6c206f1d4873d to your computer and use it in GitHub Desktop.
Script which responsively loads a background video from a number of video resolutions based on screen size. Fades the new video in.
<div class="hero js-scale-media-container">
<video class="hero__video js-scale-media" autoplay playsinline loop muted>
<source src="fpo/video/toky_background_sd_640x360.mp4" type="video/mp4">
</video>
<div class="hero__overlay-block">
<div class="hero__slash-label animate-slide-up-100px-from-below-fade-in">At Toky</div>
<h1 class="hero__header-1 animate-slide-up-100px-from-below-fade-in-first-delay">We believe our world can be more thoughtful, more humane, and more beautiful.</h1>
<a href="/what-we-do/" class="hero__link-button animate-slide-up-100px-from-below-fade-in-second-delay">About TOKY</a>
</div>
<a href="#expertise" aria-label="Scroll to the next section.">
<svg class="bouncing-arrow animate-bounce-up-down"><use xlink:href="#bouncing-arrow" /></svg>
</a>
</div>
@keyframes animate-fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes animate-fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.hero {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
&__video {
display: block;
position: absolute;
top: 50%;
left: 50%;
width: auto;
min-width: 100%;
height: auto;
min-height: 100%;
transform: translate(-50%, -50%);
opacity: 1;
background-color: $color-grey-2;
@media print {
display: none;
}
&.animate-fade-out {
animation-name: animate-fade-out;
animation-duration: $bg-video-timing;
animation-timing-function: linear;
animation-fill-mode: both;
}
&.animate-fade-in {
animation-name: animate-fade-in;
animation-duration: $bg-video-timing;
animation-timing-function: linear;
animation-fill-mode: both;
}
}
&__overlay-block {
display: block;
position: absolute;
top: 50%;
left: 50%;
box-sizing: border-box;
width: 75%;
max-width: 850px;
transform: translate(-50%, -50%);
}
&__header-1 {
margin: 0;
margin-bottom: 1em;
color: $color-white;
font-family: $font-header;
font-weight: $font-regular;
@media (max-width: $bp-main) {
font-size: 7.5vw;
line-height: 1.2;
}
@media (min-width: #{$bp-main+1}) and (max-width: $bp-tablet) {
font-size: 6vw;
line-height: 1.1;
}
@media (min-width: #{$bp-tablet+1}) and (max-width: $bp-desktop) {
font-size: 5vw;
line-height: 1.1;
}
@media (min-width: #{$bp-desktop+1}) and (max-width: $bp-wide) {
@include rem-font-size(55px, 1);
}
@media (min-width: $bp-wide) {
@include rem-font-size(70px, 1);
}
}
&__slash-label {
@include rem-font-size(15px, 1.2, 4px);
margin-bottom: 1em;
color: $color-red;
font-family: $font-body;
font-weight: $font-medium;
text-transform: uppercase;
&::after {
content: '\002F';
padding-left: 0.4em;
}
}
&__link-button {
@include rem-font-size(16px, 10px, 0);
display: inline-block;
padding: 11px 22px;
transition: background-color 0.5s, color 0.5s;
border: 2px solid $color-red;
border-radius: 1px;
background-color: transparent;
color: $color-white;
font-weight: $font-medium;
text-decoration: none;
@media (min-width: #{$bp-main+1}) {
padding: 12px 25px;
line-height: 16px;
}
&:hover {
background-color: $color-red;
color: $color-white;
}
}
}
*::-webkit-media-controls-start-playback-button {
display: none;
-webkit-appearance: none;
}
(function (Site, $, undefined) {
'use strict';
/**
* bgVideo
*
* The below functions assume that a global variable has been loaded called
* homepage_video_sources, which is an array of video sources, ordered from
* smallest to largest.
* All the video sources should have the same aspect ratio.
*/
Site.bgVideo = function () {
var $hero_video_original = $('.hero__video');
var hero_video_original = $hero_video_original[0];
var $hero_video_new;
var hero_video_new;
var current_video_index = 0;
var num_video_srcs = 0;
function switchOldWithNew() {
$hero_video_new.off('animationend.bgVideo');
$hero_video_new.removeClass('animateFadeIn');
$hero_video_original.remove();
$hero_video_original = $hero_video_new;
hero_video_original = hero_video_new;
$hero_video_new = undefined;
hero_video_new = undefined;
}
function playNewVideoAtCurrentTime() {
$hero_video_new.off('loadedmetadata.bgVideo');
$hero_video_new.prop('currentTime', $hero_video_original.prop('currentTime'));
hero_video_new.play();
$hero_video_original.addClass('animate-fade-out');
$hero_video_new.addClass('animate-fade-in');
$hero_video_new.on('animationend.bgVideo', switchOldWithNew);
}
// Load the appropriately sized video into the <video> src attribute
function loadResponsiveVideoSrc() {
var window_height = Site.$window.height();
var window_width = Site.$window.width();
var current_video_height = hero_video_original.videoHeight;
var current_video_width = hero_video_original.videoWidth;
var candidate_video;
var candidate_video_width;
var candidate_video_height;
var is_candidate_video_smaller_than_current_video;
/*
* Default value for optimum video index is the index of the largest
* video. If smaller videos work, use those.
*/
var optimum_video_index = num_video_srcs - 1;
// Don't run this function until the first frame of video is loaded
if (current_video_width <= 0 || current_video_height <= 0) {
$hero_video_original.on('loadeddata.bgVideo', loadResponsiveVideoSrc);
return;
}
else {
$hero_video_original.off('loadeddata.bgVideo');
}
for (var i = 0; i < num_video_srcs; i++) {
candidate_video = window.homepage_video_sources[i];
candidate_video_width = candidate_video.width;
candidate_video_height = candidate_video.height;
if ((candidate_video_width >= window_width) && (candidate_video_height >= window_height)) {
optimum_video_index = i;
break;
}
}
is_candidate_video_smaller_than_current_video = candidate_video_width < current_video_width;
if ((optimum_video_index !== current_video_index) && !is_candidate_video_smaller_than_current_video) {
$hero_video_new = $hero_video_original
.clone()
.insertBefore($hero_video_original);
hero_video_new = $hero_video_new[0];
// hero_video_new.currentTime can be set once loadedmetadata is fired
$hero_video_new.on('loadedmetadata.bgVideo', playNewVideoAtCurrentTime);
// Load new source
$hero_video_new.attr('src', window.homepage_video_sources[optimum_video_index].src);
}
}
// Initial video set up for hero video
if ($hero_video_original.length > 0) {
num_video_srcs = window.homepage_video_sources.length;
Site.$window.debounce('resize', loadResponsiveVideoSrc, 100);
/*
* Remove autoplay attribute from video to help when adding new video
* sources
*/
$hero_video_original.removeAttr('autoplay');
loadResponsiveVideoSrc();
}
};
}(window.Site = window.Site || {}, jQuery));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment