This amazing script by Noah Veltman allows to create videos from d3.
npm install canvas topojson d3 rw
node draw.js | ffmpeg -y -c:v png -f image2pipe -r 20 -i - -an -c:v libx264 -pix_fmt yuv420p -movflags +faststart myvideo.mp4
This amazing script by Noah Veltman allows to create videos from d3.
npm install canvas topojson d3 rw
node draw.js | ffmpeg -y -c:v png -f image2pipe -r 20 -i - -an -c:v libx264 -pix_fmt yuv420p -movflags +faststart myvideo.mp4
| // 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 = 960, | |
| height = 540; | |
| 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(240) | |
| .translate([width / 2, height / 2]) | |
| .clipAngle(90) | |
| .precision(.1); | |
| var path = d3.geoPath() | |
| .projection(projection) | |
| .context(context); | |
| // Draw 60 frames | |
| d3.range(600).forEach(function(frame){ | |
| // Spin the globe a bit more each time | |
| projection.rotate([frame * 0.6]); | |
| context.clearRect(width, height); | |
| // Water | |
| context.fillStyle = "#23b4d8"; | |
| context.beginPath(); | |
| path({type: "Sphere"}); | |
| context.fill(); | |
| // Countries | |
| countries.features.forEach(function(country, i){ | |
| context.fillStyle = d3.interpolateRainbow(Math.sin(i + frame/10)); | |
| 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()); | |
| }); |