Skip to content

Instantly share code, notes, and snippets.

Last active September 8, 2017 11:21
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save grossbart/8743585 to your computer and use it in GitHub Desktop.
Save grossbart/8743585 to your computer and use it in GitHub Desktop.

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 crop and 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;
cursor: ew-resize;
margin: 60px auto 0 auto;
opacity: 0;
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)]);
.on('mousemove', onMove)
.on('mouseleave', onRelease)
.on('touchstart', function(){ d3.event.preventDefault() })
.on('touchmove', onMove)
.on('touchend', onRelease)
width: pct(100),
height: px(frameWidth)
.style('opacity', 1)
'border-radius': px(frameWidth),
width: px(frameWidth)
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 pct(val){ return val + '%'; }
function px(val){ return val + 'px'; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment