Fullscreen Video Slideshow with BigVideo.js

A tutorial about how to create a slideshow-like fullscreen video background using BigVideo.js, a jQuery plugin for big background video.

Fullscreen Video Slideshow with BigVideo.js

(Please note that the ZIP file does not contain any video files due to their size.)

BigVideo.js is a jQuery plugin that makes it easy to create fit-to-fill background video on a web page. It can play silent ambient background video (or series of videos), or used as a player to show video playlist.

In this tutorial, we’ll be creating a page that shows a series of video screens, showcasing the free HD stock video footage and animated backgrounds available on Beachfront B-Roll.

Before we get started, give some thought as to whether using this technique at all is appropriate for your project. Background video is bandwidth heavy and can be a big drag on the user’s browser performance. If your site is already video-heavy or incorporating big video is essential to the design and purpose of your site, then using this technique may be a great choice. However, if you can accomplish the same goal with using cinemagraphs for example, maybe that is a better choice. This tutorial is can be helpful to you in either case, as we cover using big background images as well.

The first thing you’ll need to do is get video content. In this case, we went to Beachfront B-Roll and downloaded a few of their free videos. Some of them were quite large in file size, so I used Quicktime Pro to trim them to about 10 seconds or so in length. For each of the videos, we will also need to create a poster image image of the first frame of the video. I used Photoshop to save a 960×540 jpeg for each image. I used a trick of applying a .5 pixel blur and a quality setting of 50 to get a smaller file size (afterall, these are background images, so having a little blurriness on them is not a bad thing).

The Markup

First, let’s do the markup for the page:

We have a header on the center of the screen. Then we have a wrapper div that contains all the different video screens. Then, there is a button we will use to navigate between the screens.

<header>
    <h1>Fullscreen Video Slideshow <span>with BigVideo.js</span></h1>
    <p>The videos in this demo are from <a href="http://beachfrontprod.blogspot.com" target="_blank">Beachfront B-Roll</a>, a great place to download unique HD stock video footage and animated backgrounds for any production purpose (for free!).</p>
    <p><small>A demo for</small> <a href="http://dfcb.github.com/BigVideo.js/" target="_blank">BigVideo.js</a> <small>by <a href="http://twitter.com/johnpolacek" target="_blank" rel="author">@johnpolacek</a></small></p>
</header>

<div class="wrapper">
    <div class="screen" id="screen-1" data-video="vid/bird.mp4">
        <img src="img/bird.jpg" class="big-image" />
        <h1 class="video-title">#1 Bird</h1>
    </div>
    <div class="screen" id="screen-2" data-video="vid/satellite.mp4">
        <img src="img/satellite.jpg" class="big-image" />
        <h1 class="video-title">#2 Satellite</h1>
    </div>
    <div class="screen" id="screen-3" data-video="vid/camera.mp4">
        <img src="img/camera.jpg" class="big-image" />
        <h1 class="video-title">#3 Camera</h1>
    </div>
    <div class="screen" id="screen-4" data-video="vid/spider.mp4">
        <img src="img/spider.jpg" class="big-image" />
        <h1 class="video-title">#4 Spider</h1>
    </div>
    <div class="screen" id="screen-5" data-video="vid/dandelion.mp4">
        <img src="img/dandelion.jpg" class="big-image" />
        <h1 class="video-title">#5 Dandelion</h1>
    </div>
</div>

<nav id="next-btn">
    <a href="#" class="next-icon"></a>
</nav>

The CSS

Before we get into the video, we need to style the page.

Since navigation will be handled by a single big next button, we set the body overflow to hidden. While we’re at it, we’ll make all text on the page white.

html, body {
    margin: 0;
    padding: 0;
    color: #fff;
    overflow: hidden;
    font-family: 'Open Sans Condensed', Arial, sans-serif;
    font-weight: 300;
    font-size: 1em;
}

Next, for the wrapper, we know we have five content screens, so we set the width to 500% (100% per screen) and the height to 100%. We are going to navigate the page by animating the wrapper’s horizontal position, so it will use absolute positioning. We’ll use a z-index of zero to keep the wrapper content in the background.

Note the data-video attribute. This is where our script will grab the url for the video for each screen.

.wrapper {
    position: absolute;
    width: 500%;
    height: 100%;
    z-index: 0;
}

We’ll position the header in the center of the page and make. Also, give it a high z-index so it stays on top of our background content.

header {
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 999;
    color: #fff;
    background: rgba(0,0,0,0.5);
    padding: 60px;
    width: 400px;
    height: 400px;
    border-radius: 50%;
    margin: -200px 0 0 -200px;
    text-align: center;
}

We want each screen to fill the height and width of the screen, so we set the height to 100%, and the width to 100% divided by the number of screens, in this case this results in 20%. Let’s set them to float left and make the positioning relative so we can absolutely position content inside the screens. We center the position of the image inside the screen div, so we keep the overflow hidden.

.screen {
    position: relative;
    height: 100%; 
    width: 20%; /*  NOTE:numVideos/100%  */
    float: left;
    overflow: hidden;
}

Inside the screen divs, we have a large image of the first frame of the video and a video title. For the image, we use min-width, min-height to make sure the size of the image is never smaller than the size of the .screen container div (which is always the size of the browser window) and set height and width to auto so the image’s aspect ratio is maintained.

.big-image {
    min-width: 100%;
    min-height: 100%; 
    height: auto;
    width: auto; 
}

Let’s put the video titles in the bottom left, make the font size really big and have them be 50% transparent.

.video-title {
    position: absolute;
    bottom: 5%;
    left: 5%;
    opacity: .5;
    margin: 0;
    padding: 0;
    line-height: .65;
    font-size: 4em;
    text-transform: uppercase;
}

Next up, the arrow button. I’ve made a pure CSS arrow button using a technique of putting a box with a border top and left, then rotating that box 45 degrees and putting it inside a div with a large border-radius turning it into a circle. (Note: We will make the rotation work by applying an IE filter for rotating 45 degrees from Boog Design’s excellent Matrix Calculator. See the head of the HTML for the conditional comment.)

nav {
    position:absolute; 
    right: 5%; 
    top: 45%; 
    padding: 20px; 
    background: #000; 
    border-radius: 40px; 
    opacity: .4; 
    cursor: pointer;}
    nav: hover {
    opacity: .6;
}

.next-icon {
    display: block;
    border-top: solid 2px #fff; 
    border-right: solid 2px #fff; 
    width: 20px; 
    height: 20px;
    position: relative;
    left: -5px;
    -webkit-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    -o-transform: rotate(45deg);
    transform: rotate(45deg);
    color: #fff;
    text-decoration: none;
}

The JavaScript

Ok, here’s where we make stuff happen. First, link to all the scripts at the bottom of the page, before the closing body tag. Download the BigVideo.js Github Repo. In addition to BigVideo.js and its dependencies, we will be using jQuery Transit for animations.

<!-- BigVideo Dependencies -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/jquery-1.7.2.min.js"></script>')</script>
<script src="js/jquery-ui-1.8.22.custom.min.js"></script>
<script src="js/jquery.imagesloaded.min.js"></script>
<script src="http://vjs.zencdn.net/c/video.js"></script>

<!-- BigVideo -->
<script src="js/bigvideo.js"></script>

<!-- Tutorial Demo -->
<script src="js/jquery.transit.min.js"></script>

Before we get to the video, let’s set up navigation. We will need some vars to help manage navigation.

$(function() {
    var screenIndex = 1,
    numScreens = $('.screen').length,
    isTransitioning = false,
    transitionDur = 1000;
}

Let’s go over what these vars do.

  • screenIndex – keeps track of what screen we are looking at
  • numScreens – the number of screens (in our case 5)
  • isTransition – boolean to prevent extra clicking interfering with the navigation
  • transitionDur – how fast the animation scrolls

Now, add a next button click event and callback to do navigation.

$('#next-btn').on('click', function(e) {
    e.preventDefault();
    if (!isTransitioning) {
        next();
    }
});

function next() {
    isTransitioning = true;
    
    // update video index
    if (screenIndex === numScreens) {
        screenIndex = 1;
    } else {
        screenIndex++;
    }
    
    $('.wrapper').transit(
        {'left':'-'+(100*(screenIndex-1))+'%'},
        transitionDur,
        onTransitionComplete);
}

function onTransitionComplete() {
    isTransitioning = false;
}

Now, that our navigation is working, time to set up the video. When creating a video heavy site, it is important to consider mobile devices. Typically they do not support autoplay, meaning ambient background video will not work. There are tricks to get around this, but we should also consider that it is likely that the user is on a lower bandwidth connection. One thing to consider would be to provide non-video content to these users. In this demo, we will demonstrate how to do that using Modernizr, which you should link to in the document head.

First, add a var for BigVideo (BV) and an isTouch boolean to the top of our script, which gets set by Modernizr’s touch feature detection.

var screenIndex = 1,
    numScreens = $('.screen').length,
    isTransitioning = false,
    transitionDur = 1000,
    BV,
    isTouch = Modernizr.touch;
   

Next, initialize BigVideo for non-touch devices. Create a showVideo() function where we will grab the video filepath from the data-video attribute for the current screen being viewed. Add a showVideo() call to the onTransitionComplete callback function. Also, when the video is loaded and ready to play, we need to fade the framegrab image out. To do that, we use the Video.js api to add a ‘loadeddata’ event listener to the BigVideo player. We attach a callback function to that event which makes the image of the current screen fade out so the video is displayed.

var screenIndex = 1,
    numScreens = $('.screen').length,
    isTransitioning = false,
    transitionDur = 1000,
    BV,
    isTouch = Modernizr.touch;

// Next button click goes to next div
$('#next-btn').on('click', function(e) {
    e.preventDefault();
    if (!isTransitioning) {
        next();
    }
});

if (!isTouch) {
    // initialize BigVideo
    BV = new $.BigVideo({forceAutoplay:isTouch});
    BV.init();
    showVideo();
    
    BV.getPlayer().addEvent('loadeddata', function() {
        onVideoLoaded();
    });

    // adjust image positioning so it lines up with video
    $bigImage
        .css('position','relative')
        .imagesLoaded(adjustImagePositioning);
    // and on window resize
    $(window).on('resize', adjustImagePositioning);
}

// Next button click goes to next div
$('#next-btn').on('click', function(e) {
    e.preventDefault();
    if (!isTransitioning) {
        next();
    }
});

function showVideo() {
    BV.show($('#screen-'+screenIndex).attr('data-video'),{ambient:true});
}

function next() {
    isTransitioning = true;
    
    // update video index, reset image opacity if starting over
    if (screenIndex === numScreens) {
        $bigImage.css('opacity',1);
        screenIndex = 1;
    } else {
        screenIndex++;
    }
    
    if (!isTouch) {
        $('#big-video-wrap').transit({'left':'-100%'},transitionDur)
    }
        
    $('.wrapper').transit(
        {'left':'-'+(100*(screenIndex-1))+'%'},
        transitionDur,
        onTransitionComplete);
}

function onVideoLoaded() {
    $('#screen-'+screenIndex).find('.big-image').transit({'opacity':0},200)
}

function onTransitionComplete() {
    isTransitioning = false;
    if (!isTouch) {
        $('#big-video-wrap')
            .css('left',0);
        showVideo();
    }
}

Tidying up

You may notice that the big image and the big video don’t line up during the fade animation, resulting in a bothersome jump in position.This is because the video is centered inside the screen. To fix the problem, we need also need to center our images. To do that, we create a function that adjusts the positioning of the images.

function adjustImagePositioning() {
    $bigImage.each(function(){
        var $img = $(this),
            img = new Image();

        img.src = $img.attr('src');

        var windowWidth = $window.width(),
            windowHeight = $window.height(),
            r_w = windowHeight / windowWidth,
            i_w = img.width,
            i_h = img.height,
            r_i = i_h / i_w,
            new_w, new_h, new_left, new_top;

        if( r_w > r_i ) {
            new_h   = windowHeight;
            new_w   = windowHeight / r_i;
        }
        else {
            new_h   = windowWidth * r_i;
            new_w   = windowWidth;
        }

        $img.css({
            width   : new_w,
            height  : new_h,
            left    : ( windowWidth - new_w ) / 2,
            top     : ( windowHeight - new_h ) / 2
        })

    });

}

Call the function on document ready and attach it to a window resize event.

$bigImage
    .css('position','relative')
    .imagesLoaded(adjustImagePositioning);
// and on window resize
$(window).on('resize', adjustImagePositioning);

Now the images and videos should be aligned, resulting in a clean transition between the poster image and the video.

Please note that the ZIP file does not contain any video files due to their size.

Tagged with:

John Polacek

John is a Chicago-based web developer and designer working in the trenches doing big agency/big client work. In his spare time, he writes fun jQuery plugins like Scrollorama, draws indie comics and builds silly sites like areyouabrogrammer.com.

Stay up to date with the latest web design and development news and relevant updates from Codrops.

Feedback 82

Comments are closed.
  1. Preaty cool this bigvideo plugin… Imagine some animation with a video as a background and some html-defined and animated characters moving and interacting on top of it. Fully featured movie using the lates tools and technologies.

  2. PERFECT entry site but…
    I just can’t figure it out how to make video running. I just see my custom still image. Hmm?
    Help? PLEASE?

    • Please let us know what browser you are using? Note that the download file does not contain any videos like mentioned in the last part of the tut. Also, you will probably need a server environment for some browsers (i.e. Firefox). Cheers, ML

  3. Here it plays perfeclty on Firefox (updated) and on IE9.
    But it doesn’t work on Opera (display a still image) and on Google Chrome.

  4. Firefox playback isn’t as nice due to using a Flash fallback for .h264. I’ve just added the ability to use Ogg or WebM as a second source so that Firefox will play native HTML5 video instead of Flash. I’ve posted Ogg and WebM examples on the repo.

    • Great! But where I can see the code for all together – mp4, ogv, webm? Because on index.html I saw the code only for mp4. And it does’t work in Firefox – I see only the picture, but not the video.

  5. Hi John, I have a question, how I can add another picture in to the screen. I mean 6 photo? please help me,.

    <!– *****8

    wall wraps

    outdoor signs

  6. I can get this to work locally with the video I have chosen, but when I upload, video will never start.

    How do you get the videos you used to load so quickly?

    • Hi,
      I had some problem first but then I soon realised video playing problem is not a rocket science. 🙂
      In souce code (html) just enter the name of your video clip you have on your server and that ‘s pretty much it.

      My fresh example from today (still experimenting) downbelow.

      – vid/drift02.mp4 >>> vid is my source map on server / name of the video (you can use, mp4, mov,… just about anything)
      – img/PP.jpg >>> img is source map on server / image is actualy first frame of the video clip

      <!–#1 PP–>

      And USEFUL Quote from Mr. Polacek about he video and options:
      “For best results, I recommend using Vimeo. Sign up for Vimeo Pro, then use their direct mp4 link to serve the video. Vimeo not only has solid bandwidth for delivering video, they do great compression. If you start with a high def source at a bitrate of 10mbps or more, it does such a nice job that you can probably get away with using the standard def source as your background video.”

      Hope it helped! 🙂

    • Example was gone so again and without . Hope it will work now.
      SORRY 2 ALL!

      div class=”wrapper”
      div class=”screen” id=”screen-1″ data-video=”vid/drift02.mp4″
      img src=”img/PP.jpg” class=”big-image” /
      !–#1 PP–
      /div
      /div

      Cheers!

  7. Awesome tutorial…!!!
    One question: is it possible to also play the audio of the video?
    Thanks and once again: brilliant tutorial!

    • Change

      function showVideo() { BV.show($('#screen-'+screenIndex).attr('data-video'),{ambient:true}); }

      to

      function showVideo() { BV.show($('#screen-'+screenIndex).attr('data-video'),{ambient:false}); }

      in your HTML file and it will pay audio (but also show some kind of control panel). More information on the original project site: http://dfcb.github.com/BigVideo.js/

  8. downloaded the zip, then during extraction, you file prompted a warning of encryption loss does not work in Firefox under your current setup

  9. Preaty cool this bigvideo plugin…
    Is there a way to play also the audio & stop the loop.

  10. Hi, I tried this script and I must say it is very nice but I must say that I find some problems:
    1. Does not work with Opera browser (because it uses webm video)
    2. IE9 does not work in the loop mode
    3. does not work well in firefox (because it uses ogv video)

    You can solve these problems? you know how to fix these bugs?
    regards Alfonso

  11. Hi. This is an excellent tutorial.
    Can someone explain me why it’s not requiring all the other formats of video webm, flv, ogv?? Why it’s not working in mobile devices ( I tested on Android mobile phone )

    • If the condition if (!isTouch) { is commented I can see in my android mobile phone. But still in iPad and iPhone it’s not playing the video.

  12. Cool tutorial. The use of a circle background for the text is neat, but I don’t understand the header CSS that’s used to make it happen. I’ve checked with both Firefox and Chrome and they render it the same in that the resulting circle is 400x400px. The CSS suggests that with the extra 60px of padding on all sides of the header, it would cause the resulting circle to expand the circle an extra 120px. I don’t understand why that’s not happening.

  13. Hi,

    Is it possible to have the page auto link after a video is played to another page?

    If so, how would I code that?

    Thanks
    Chris

  14. Hi, thanx for this awesome tutorial 😀
    is that possible to make the slideshows auto play?

  15. Hello. On IE, the next button advances the video, but does not move the title. Do you have a solution?

  16. Hi,

    Thanks for the tutorial. I struggled before to combine bigvideo.js with a slider to achieve this effect, but I failed.

    I started with your tutorial and then added some content. Somewhere along the road I lost a feature, and I can’t bring it back. When I slide, the content slides, the video stays. When the transition is complete, the video changes for the one that should be in the new slide. So the old one is not pushed away, it just stays there until the new one is loaded.

    Can you think of any reason for this to happen ?

    Thank you,
    Andi Stancu

    • Update: I figured out the problem is about the way I call a specific slide number. If I use your next() function everything works well. This is how I do it: http://l.cq.tl/t5VK

      I’m currently trying to figure out a better way to call specific slides. Also, can you think of a solution to skip slides ? For example if I’m in slide 2 and I wanna go straight to slide 4 ? This way it would look more like the content loads from the side, rather then a full screen slider.

      Either way, thank you so much for this tutorial 🙂

    • 1. In bigvideo.js, find and replace ‘body’ with your ‘div-name’.

      2. In bigvideo.css change the postion of big-video-wrap from fixed to absolute.

  17. Somehow this stopped working for me with Firefox 18.0 on Windows 7.
    Can anyone confirm?

  18. Hi…Its good , i need some help from all, iam a junior devoloper , hope you will solve my problem.

    1. how to play youtube videos as background (it saves bandwidth).

    2. auto play option for vedios.

    3. navigation for vedios.

    hope to here from you…Thanks in Advance

  19. Love what this script does! … but having a slight issue and wondering if you’ll help me out:
    I’m trying to play 4 different videos as backgrounds in 4 different divs using your script.
    I’ve placed the first frame/mobile image as a background of the 1st child div of the video div.
    I’ve set both divs to:
    position: relative; height: 100%; width: 100%; overflow: hidden;

    using html:

    doesn’t seem to work yet, the image shows fine, but the script isn’t making it disappear or play the video…

    How is the script supposed to look like for this (while using Modernizr)? ty

    this is what my script currently looks like:
    var BV = new $.BigVideo(); BV.init(); if (Modernizr.touch) { BV = new $.BigVideo({forceAutoplay:isTouch}); BV.init(); showVideo(); BV.getPlayer().addEvent('loadeddata', function() { onVideoLoaded(); }); // adjust image positioning so it lines up with video $bigImage .css('position','relative') .imagesLoaded(adjustImagePositioning); // and on window resize $(window).on('resize', adjustImagePositioning); } else { function showVideo() { BV.show($('#big-video-play').attr('data-video'),{ambient:true}); }; }; function onVideoLoaded() { $('#big-video-play').find('.big-video-wrap-image').transit({'opacity':0},200) };

  20. .. I’d edit my previous post if it’d let me but…
    another example of something I tried and failed was the following script,
    it did play the video but at the top of the main container.. not within the video’s container…
    any ideas?
    var BV = new $.BigVideo(); BV.init(); if (Modernizr.touch) { } else { BV.show($('#big-video-play').attr('data-video'),{altSource:$('#big-video-play').attr('data-video2')}); $('#big-video-play').find('.big-video-wrap-image').transit({'opacity':0},200); }

  21. Are these dependency’s really needed? And why?

    js/jquery-ui-1.8.22.custom.min.js js/jquery.imagesloaded.min.js

  22. Is there some way to properly randomize slides? I have spent my whole day trying to do this, and I actually got it once by putting complete divs in an array in JS, but that requires insane amounts of very chaotic code. The problem is that I can’t just randomly pick the video; it has to have the required picture and text too.

    • Alright, I did it! 😀 After 3 days of amateur coding and tutorials I managed to randomize the slides.
      First of all, just putting the slide code in an array doesn’t work, because the ID’s need to follow up. You can’t have screen-9 coming before screen-3, or the video won’t play. So I had to only put the parts of the code that come after the ID in an array. I have a horribly long javascript file now, but it works!

      var slides = []; slides.push('HTML') slides.push('HTML') (var len = slides.length; var chosen = []; for (var i = 0; i<=7; i++) { var randy = Math.floor(Math.random() * len); chosen[i] = slides[randy]; for (k=0; k<=i-1; k++) { if (chosen[k] == chosen[i]) { i--; } } } document.write('<div class="screen" id="screen-2" ' + chosen.splice(0,1) + '<div class="screen" id="screen-3" ' + chosen.splice(0,1) + '<div class="screen" id="screen-4" ' + chosen.splice(0,1) + '<div class="screen" id="screen-5" ' + chosen.splice(0,1) + '<div class="screen" id="screen-6" ' + chosen.splice(0,1) + '<div class="screen" id="screen-7" ' + chosen.splice(0,1) + '<div class="screen" id="screen-8" ' + chosen.splice(0,1) + '<div class="screen" id="screen-9" ' + chosen.splice(0,1));

      Basically it takes the first variable out of the ‘chosen’ array (which is a randomized list of all the screens), adds it and then goes to the next screen.

      So yeah, thought I’d share this, since others may want to do the same sometime 🙂

  23. Here is my problem, i want this video to play in mobile devices. iOs , Android ect. i used below code but still did not works. please help me.
    var screenIndex = 1, numScreens = $('.screen').length, isTransitioning = false, transitionDur = 1000, BV, isTouch = Modernizr.touch;

  24. i want to make a website with this plugin but, is there any option that allow to play video’s sound?

  25. Agreed, awesome script.

    I have a question similar to sarah’s.

    I’m trying to add your horizontal BV slide functionality to a vertically scrolling site. The site is one page and each section is full screen. When I attempt to do this, I notice two things wrong in firebug.

    1. The div id=”big-video-wrap” does not show up and the slider defaults to the img.

    2. The “#next-btn” does not advance to the next slide.

    Is there a work around for implementing this fullscreen slide functionality to a section of a one-page-designed sight?

    Thanks again,
    ck

  26. Do you have an example of how one might add a button to the tutorial code to turn sound off and on?

    Great job, by the way!

  27. 1. Is it possible to loop the videofile with sound?
    2. How do i dipslay the image after the video is finished?

    • I want to know the answer to number 2 as for #1 just change the volume to 100 in the bigvideo.js file

  28. How do I make the header text scrollable? If a user has toolbars or resizes the window, not all text in the header shows and there is no scrollbar…

  29. Hi I am using this and in the JS settings i turned the LOOP off and once the video stops it shows a video still, how can I get it to show the image that is placed in the “big-image” class