Skip to content

Instantly share code, notes, and snippets.

Forked from grossbart/
Created January 31, 2014 21:45
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?

A short code excerpt from this visualization I created for the longform article “Iouri Podladtchikov – You only fly once” by the Neue Zürcher Zeitung.

It's a very simple way to create an interactive animation based on video material. Hover over the image to go through the animation.

I used Final Cut Pro to export the frames of a short video sequence, which I then stitched together into a single film strip using ImageMagick: convert folder-of-stills/* +append filmstrip.jpg

<!DOCTYPE html>
<meta charset="utf-8">
<script src=""></script>
<style type="text/css">
.viewer {
border: 5px solid #6d95ad;
border-radius: 110px;
cursor: ew-resize;
margin: 60px auto 0 auto;
overflow: hidden;
var frameWidth = 0,
numberOfFrames = 0,
posToFrame = d3.scale.linear().clamp(true);
var viewer ='body').append('div')
.attr('class', 'viewer');
var frames = viewer.append('img')
.attr('src', 'filmstrip.jpg')
.on('load', init);
function init() {
frameWidth = this.offsetHeight;
numberOfFrames = this.offsetWidth / this.offsetHeight;
.domain([frameWidth, 0])
.range([0, ((numberOfFrames - 1) * -frameWidth)]);
width: px(frameWidth),
height: px(frameWidth)
.on('mousemove', onMove)
.on('touchmove', onMove)
.on('mouseleave', onRelease)
.on('touchend', onRelease)
function onMove(){ frameAtPos(d3.mouse(this)[0]) }
function onRelease(){ frameAtPos(frameWidth) }
function frameAtPos(pos) {'margin-left', posToFrame(pos) + 'px');
function interpolateFrame(a, b) {
return function(t) {
return Math.floor(((b - a) * t)/frameWidth) * frameWidth
function px(val){
return val + 'px';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment