A “Behind the Scenes” Look - Making of the Hunger Games Capitol Tour in HTML5

The Hunger Games: The Capitol Tour is an immersive virtual journey that takes place in the capitol city of Panem, the seat of the Hunger Games authoritarian power. Powered by HTML5 and CSS3, this hardware-accelerated experience seeks to evolve the way fans and movies interact with one another. Developed in partnership with Internet Explorer and Lionsgate, and the Digital Agencies at Ignition Interactive and The Nerdery, The Capitol Tour is a glimpse into the universe of the Hunger Games. Here you’ll find a technical tear down that digs into the technologies underlying the experience, sandbox where you can explore a few of the prototypes that went into The Capitol Tour, and some links to resources for getting started and digging into HTML5 programming.

Visit Site

The pages of the bestselling trilogy "The Hunger Games" introduced readers to a captivating set of characters living in a harsh, post-apocalyptic world, and on Friday March 23, the movie adaptation of the first book will bring that world to life. With an IP like The Hunger Games, a standard trailer website would not do the movie justice. It needed the kind of web experience that pushes the limits of what HTML5 can do, bringing fans into the universe of The Hunger Games to interact with environments in new and exciting ways. That was the goal in bringing the Panem’s Capitol City to life with HTML5 and CSS3 technologies available in Internet Explorer and other modern browsers.

How image skewing came to life in an HTML5-enabled browser

For the "Now Arriving" panels that appear on the pillars in the Welcome Center, we were faced with the task of creating a skewed image that needed to be rendered on-the-fly, since it included images and names of friends pulled dynamically from the visitor's Facebook and Twitter accounts.

We initially created a number of different prototypes in order to determine the best way of achieving the skewed effect.

We opted to use HTML5 canvas because of the different affine 2D transforms available, such as scale, translate, and rotate. Canvas offers no native "skew" transformation; however, a skew transform can still be achieved by specifying a custom 2d transformation matrix, as follows:

var context = myCanvas.getContext('2d');
context.transform(1, skewX, skewY, 1, 0, 0);

Using this code to skew in the y direction would produce an image along these lines:

While interesting, it is not quite the effect we want. The top and bottom of the image need to be skewed at different angles in order to get the perspective we want. Unfortunately, this effect is impossible to achieve using a single 2d transformation (short of creating a true 3d mesh, using as the image as texture map).

Nonetheless, in our 2d world we were able to simulate the same effect by creating a clipping area that bounded the area we wanted. Before the image is drawn to the canvas, we created a trapezoidal path, and used this as clipping region for the image:

context.moveTo(p1.x, p1.y)
context.lineTo(p2.x, p2.y)
context.lineTo (p3.x, p3.y)
context.lineTo (p4.x, p4.y)

The output was as follows:

Unfortunately, this method clearly has an issue since a significant portion of the bottom of the image is cut off. Therefore, we needed a different approach altogether -- the solution turned out to be a software pixel shader.

The shader was created by capturing an array of pixels in the original unskewed image. We then mapped these pixels to fill a trapezoidal area. The pixel-by-pixel manipulation done by the pixel shader ended up being very computationally expensive, and therefore not feasible for real-time rendering/animation of the effect.

The final solution, which circumvented the issues encountered by the previous attempts, was to slice the original image into n different vertical slices. Each slice was independently transformed by a different skew amount. The code used to achieve this effect is as follows:

// parameters
var image = document.getElementById('sourceImage');
var skewTop = 63;
var skewBottom = 40;
var width = 220;
var height = 48;
var numSlices = 18;
// set up skew values
var skewTopSlice = skewTop / height;
var skewBottomSlice = -skewBottom / height;
var skewSlice = (skewTopSlice - skewBottomSlice) / numSlices;
var sliceHeight = Math.floor(height / numSlices);
var skew;
var x = 0;
var y = 0;
// iterate through each slice and transform appropriately
for (var i = 0; i < numSlices; i++) {
skew = skewTopSlice - (i * skewSlice);
y = i * sliceHeight;
this.transform(1, skew, 0, 1, sx, sy);
this.drawImage(image, x, y, width, sliceHeight, x, y, width, sliceHeight);

This allows us to skew the bottom and top of the image independently, which we could adjust as needed, based on the placement of the image within the scene:

For greater convenience, we extended the canvas context prototype as follows, so that the skew effect could be re-used:

CanvasRenderingContext2D.prototype.drawImagePerspective = function(image, x, y, numSlices, skewTop, skewBottom, width, height) {
// skew code here
Which can be called as follows:
document.getElementById('sourceImage'), //image
0, //x
0, //y
18, //numSlices
63, //skewTop
40, //skewBottom
220, //width
48 //height

By using Canvas in HTML5 we were able to achieve the look and feel we were hoping for with a dynamically displayed skewed 2D image on a 3D surface! Cool.

This effect demonstrated why hardware acceleration in a browser like Internet Explorer 10 and 9 is so important to the web.

To learn more about developing with HTML5 canvas, click here:

Thanks for reading Part 1 – Image Skewing of our multipart series on the technologies powering The Capitol Tour! Be sure to check back weekly as we continue our deep dive into HTML5 technologies.

Coming soon!

  • Part 2 – Leveraging Developer Tools
  • Part 3 – Event Model
  • Part 4 – Sprite Animations
  • Part 5 – Text Curvature

To learn more about developing in HTML5, click here: http://msdn.microsoft.com/ie