Noah Veltman
WNYC Data News
@veltman
github.com/veltman/gifs
Screen capture doesn't scale.
...is easy to automate.
...accepts you for who you are.
Turn JS animations into gifs or videos in a way that:
  // Set stuff up
  draw(t) {
    // Draw everything
    requestAnimationFrame(draw);
  }
  requestAnimationFrame(draw);  var Canvas = require("canvas");
  var myCanvas = new Canvas(600, 600);
  var context = myCanvas.getContext("2d");
  context.fillStyle = "papayawhip";
  context.fillRect(100, 100, 400, 400);
  fs.writeFile("whipit.png", canvas.toBuffer(), etc);Easy to automate
Lots of control
Canvas only
Lots of dependencies
  var svg2png = require("svg2png"),
      d3 = require("d3"),
      jsdom = require("jsdom"),
      ...SVG goodness
PhantomJS weirdness
  var gif = new GIF();
  for (var i = 0; i < numFrames; i++) {
    drawFrame(i * duration / frames);
    gif.addFrame(myCanvas, {
      delay: duration / frames,
    });
  }
  gif.render();Browser goodness
On-demand gifs
Hard to automate
No video
  d3.selectAll(".districts")
    .transition()
    .delay(function(d,i){
      return i * 20;
    })
    .ease("cubic-in-out")
    .attr("d",newPath);  $(".box").animate({
    width: "400px",
    height: "200px",
    ...
  });1. Create a transition
2. Check each element
3. Save all their updaters
4. Run them later
  dots.transition()
    .something()
    .very()
    .complicated();
  var jumpToTime = dots.record(true);Kind of works
D3 only
Can't go backwards
Is bad
  // Set stuff up
  draw(t) {
    // Draw everything
    requestAnimationFrame(draw);
  }
  requestAnimationFrame(draw);  var fakeTime = 0;
  Date.now = function() {
    return fakeTime;
  };
  window.requestAnimationFrame = function(cb) {
    saveFrame();
    fakeTime += 17;
    setTimeout(cb,0);
  };Accepts you for who you are
Breaks everything else
You should probably still just use screen capture
But maybe not?
Videos!
Noah Veltman
WNYC Data News
@veltman