Story of a Knight: the making of

The travel of a medieval knight through fullscreen DOM. The ‘making of’ the demo that has won the November Dev Derby.

Technologies used:

Markup And Style

Markup and style are organized in this way:

  • An external wrapper that contains everything
  • Three controls boxes with fixed positions and high z-index
  • An internal wrapper that contains the Google Maps iframe, canvas path and 8 div elements for the story

The external wrapper and control boxes

The external wrapper contains:

  • The audio tag with ogg and mp3 sources, on top left;
  • The div which is populated with fullscreen switcher if the browser supports it, on top right;
  • The navigation with numbers to move through the canvas path, on bottom right.

<div id="external-wrapper">
  <audio controls="controls">
    <source src="assets/saltarello.ogg" type="audio/ogg" />
    <source src="assets/saltarello.mp3" type="audio/mp3" />
    Your browser does not support the audio element.
  <div id="fullscreen-control">
  <ul class="navigation">
    <li class="active"><a href="#start">1</a></li>
    <li><a href="#description">2</a></li>

The internal wrapper

The internal wrapper contains:

  • The iframe with the big Google Map embedded, absolutely positioned with negative x and y;
  • A div of the same size and the same absolute position of the map, but with a bigger z-index, which has a “background-size: cover” semi-transparent image of old paper to give a parchment effect;
  • The canvas path (once activated the javascript plugin, it will be drawn here);
  • The 8 divs that tells the story with texts and images, absolutely positioned.

<div class="wrapper">
  <iframe width="5000" height="4500" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src=";t=k&amp;ll=44.660839,14.811584&amp;spn=8.79092,13.730164&amp;z=9&amp;output=embed"></iframe>
  <div style="position: absolute; top: -2000px; left: -1100px; background: transparent url(assets/bg_paper.jpg) no-repeat top left; width: 5000px; height: 4500px;background-size: cover;opacity: 0.4;z-index: 999;"></div>
  <div class="demo">
    <img src="assets/knight.png" alt="">
    <h1><span>&#8225;</span> Story of a Knight <span>&#8225;</span></h1>
    <span class="arrow">&#8224;</span> Of Venetian lagoon AD 1213 <span class="arrow">&#8224;</span>
  <div class="description">
    <span class="big">He learnedthe profession of arms<br/>in an Apennines' fortress.</span>
    <img src="assets/weapons.png" alt="" style="position: absolute; top: 180px; left: 20px;">


The Scrollpath plugin

Available at

First we need to embed the jQuery library in the last part of the page

<script src=""></script>

Then we can call the scrollpath.js plugin, the demo.js where we give the instructions to draw the canvas path and initiate it, the easing.js to have a smooth movement (also include the scrollpath.css in the head of the document).

<script src="script/min.jquery.scrollpath.js"></script>
<script src="script/demo.js"></script>
<script src="script/jquery.easing.js"></script>
<link rel="stylesheet" type="text/css" href="style/scrollpath.css" />

Let’s see the relevant parts of the demo.js file:

  1. At the beginning there are the instructions for drawing the path, using the methods “moveTo”, “lineTo”, “arc” and declaring x/y coordinates;
  2. Then there’s the initialization of the plugin on the internal wrapper;
  3. Finally there’s the navigation implementation with smooth scrolling.
  function init() {
  /* ========== DRAWING THE PATH AND INITIATING THE PLUGIN ============= */
  var path = $.fn.scrollPath("getPath");
  // Move to 'start' element
  path.moveTo(400, 50, {name: "start"});
  // Line to 'description' element
  path.lineTo(400, 800, {name: "description"});
  // Arc down and line
  path.arc(200, 1200, 400, -Math.PI/2, Math.PI/2, true);
  // We're done with the path, let's initiate the plugin on our wrapper element
  $(".wrapper").scrollPath({drawPath: true, wrapAround: true});
  // Add scrollTo on click on the navigation anchors
  $(".navigation").find("a").each(function() {
    var target = this.getAttribute("href").replace("#", "");
    $(this).click(function(e) {
      // Include the jQuery easing plugin (
      // for extra easing functions like the one below
      $.fn.scrollPath("scrollTo", target, 1000, "easeInOutSine");
  /* ===================================================================== */

The jQuery-FullScreen plugin

Available at

To cap it all, the fullscreen. Include the jQuery-FullScreen plugin, then verify with a script if the browser supports the functionality: in case yes, it will append the switcher on the top right corner; then initialize it on the external wrapper to push everything fullscreen.

<script src="script/jquery.fullscreen.js"></script>
  (function () {
    //Fullscreen for modern browser
      var fullScreenButton = $('#fullscreen-control').append('<a id="goFullScreen">Watch full screen</a>');{


The hardest part was to figure out which size/zoom level give to the Google Maps iframe and then where to position it in relation to the div with the canvas.
The other thing that has reserved some problems was the loading time: I had initially placed the video of a medieval battle in slow-motion along the path, but then I removed it because the page was loaded too slowly

As you have seen everything is very simple, the good result depends only on the right mix of technology, storytelling and aesthetics. I think that the front-end is entering in a golden age, a period rich of expressive opportunities: languages and browsers are evolving rapidly, so there’s the chance to experiment mixing different techniques and obtain creative results.

View full post on Mozilla Hacks – the Web developer blog

Tagged on: , ,

Leave a Reply