Skip to content

Instantly share code, notes, and snippets.

@veltman
Created July 2, 2016 04:33
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save veltman/f694a1e5cbec0ed7af4334fe95190d7e to your computer and use it in GitHub Desktop.
Save veltman/f694a1e5cbec0ed7af4334fe95190d7e to your computer and use it in GitHub Desktop.
D3 frames to video
// Pipe to ffmpeg with something like:
// node draw.js | ffmpeg -y -c:v png -f image2pipe -r 20 -i - -an -c:v libx264 -pix_fmt yuv420p -movflags +faststart myvideo.mp4
var Canvas = require("canvas"),
d3 = require("d3"),
topojson = require("topojson"),
rw = require("rw"),
world = require("./world-110m.json");
var width = 1280,
height = 720;
var canvas = new Canvas(width, height),
context = canvas.getContext("2d");
var countries = topojson.feature(world, world.objects.countries),
mesh = topojson.mesh(world, world.objects.countries);
var projection = d3.geoOrthographic()
.scale(280)
.translate([width / 2, height / 2])
.clipAngle(90)
.precision(.1);
var path = d3.geoPath()
.projection(projection)
.context(context);
// Draw 60 frames
d3.range(60).forEach(function(frame){
// Spin the globe a bit more each time
projection.rotate([frame * 6]);
context.clearRect(width, height);
// Water
context.fillStyle = "#23b4d8";
context.beginPath();
path({type: "Sphere"});
context.fill();
// Countries
countries.features.forEach(function(country){
context.fillStyle = d3.interpolateRainbow(Math.random());
context.beginPath();
path(country);
context.fill();
});
// Borders
context.beginPath();
path(mesh);
context.stroke();
// Pipe to stdout but squash EPIPE
rw.writeFileSync("/dev/stdout", canvas.toBuffer());
});
@Fil
Copy link

Fil commented Jul 2, 2016

amazing! thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment