HTML5 presentation with motion background

I was recently looking for a way to present our church’s worship lyrics on top of a motion background. I naturally turned to PowerPoint, but quickly found out that the only way to achieve a seamless transition between slides is to combine all the lyrics on a single slide and use animations to show and hide the lyric text.

This was a clunky solution, and there is a software market specifically for this use case. However, instead of splurging on new software, I wondered if my simple requirements could be met using a HTML5 web page. The only requirements were that:

  • A full screen, edge-to-edge video could be set as the background. It should automatically start and loop.
  • The keyboard arrow and space keys can be used for navigation between slides.
  • Multi-line text must be centered vertically and horizontally on the screen.

I initially looked into using reveal.js and impress.js. It was unclear if the former already supported video backgrounds or if it was still in development only. The latter seemed extremely complicated for my simple use case.

Looking into browser presentations using jQuery, I came across this article which provided a way to navigate between slides represented as divs. There was additional code to support visual navigation buttons in a footer which I didn’t need, so consequently stripped out. It also used a old style way of adding a jQuery keyboard event handler, so I updated that. I also replaced a simple jQuery hide/show with a fadeOut/fadeIn for a little jazz.

I then looked into the video requirement and found this article which had exactly what I needed to create an edge-to-edge video with autoplay and looping. Relevant code:

<video autoplay loop id="bgvid">
  <source src="motion-background.mp4" type="video/mp4">
</video>

#bgvid {
  position: fixed;
  right: 0; bottom: 0;
  min-width: 100%; min-height: 100%;
  width: auto; height: auto;
  z-index: -100;
  background-size: cover;
}

I then needed a way to both vertically and horizontally center text, and I investigated what Flexbox could provide since I had full control of what browser was used (although Chrome has supported Flexbox for a while). While the CSS was extremely simple, I wasn’t sure why my paragraphs on each slide were displayed inline. It turned out that I needed an extra div, so instead of this structure:

<div class="slide">
  <p>Line 1</p>
  <p>Line 2</p>
  <p>Line 3</p>
</div>

I needed this structure:

<div class="slide">
  <div class="content">
    <p>Line 1</p>
    <p>Line 2</p>
    <p>Line 3</p>
  </div>
</div>

Not having any motion backgrounds on hand, I found that www.motionbackgrounds.co had some decent free videos that I could use to test out the concept.

Combining the above, it all looked pretty good in full screen mode. The only deficiency is the lack of a presenter view, where the presentation can be started full screen on a separate monitor. There appears to be an solution using Firefox, but it didn’t seem robust when I tried it.

The source code and example presentation is available on GitHub. I’ve included a motion background created using Premiere tutorial to avoid copyright issues.

Adding CSRF token to jQuery AJAX requests

When using a jQuery-supported framework such as Backbone, underlying jQuery AJAX requests are typically abstracted at the model layer. To insert Cross-Site Request Forgery (CSRF) tokens or other session data into the request, one method is to proxy a method in the call stack and add the token via an option (example). This does have a disadvantage if you need to call $.ajax directly as you’ll need to again insert the CSRF token as a header option.

The DRY way? Use jQuery’s ajaxPrefilter API:

$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
  var token;
  if (!options.crossDomain) {
    token = $('meta[name="csrf-token"]').attr('content');
    if (token) {
      return jqXHR.setRequestHeader('X-CSRF-Token', token);
    }
  }
});