Creating visualizations like this one but using canvas is possible.
The technique is the same as when using it with SVG with the problem that Canvas hasn’t got a method to get the whole length of a path. To do it, I’ve created a hidden SVG first. This other page has a nice explanation about how the SVG path animation work.
The path is the Trans Mongolian train route taken from here but redrawn, since the original is a multi line.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var width = 700,
height = 500;
var canvas = d3.select("body").append("canvas")
.attr("width", width)
.attr("height", height);
var context = canvas.node().getContext("2d");
var projection = d3.geo.stereographic()
.scale(900)
.translate([width / 2, height / 2])
.rotate([-90, -60])
.clipAngle(180 - 1e-4)
.clipExtent([[0, 0], [width, height]])
.precision(1);
var path = d3.geo.path()
.projection(projection);
//.context(context);
var graticule = d3.geo.graticule();
d3.json("transsiberian.json", function(error, transsiberian) {
d3.json("world-110m.json", function(error, world) {
var countries = topojson.feature(world, world.objects.countries);
var track = topojson.feature(transsiberian, transsiberian.objects.transsiberian);
var pathEl = d3.select("body").append("svg").append("path").attr("d", path(track));
var length = pathEl.node().getTotalLength();
d3.select("svg").remove;
d3.transition()
.duration(5000)
.ease("linear")
.tween("zoom", function() {
return function(t) {
context.clearRect(0, 0, width, height);
context.strokeStyle = '#aaa';
context.fillStyle = '#ccc';
context.beginPath();
path.context(context)(graticule());
context.lineWidth = 0.2;
context.strokeStyle = 'rgba(30,30,30, 0.5)';
context.stroke();
context.beginPath();
path.context(context)(countries);
context.fill();
context.beginPath();
path.context(context)(countries);
context.stroke();
context.lineWidth = 1;
context.strokeStyle = 'rgba(120,60,60, 1)';
context.setLineDash([length]);
context.lineDashOffset = length*(1-t);
context.beginPath();
path.context(context)(track);
context.stroke();
context.setLineDash([]);
}
});
});
});
d3.select(self.frameElement).style("height", height + "px");
</script>
_ A id N
0
{"type":"Topology","objects":{"transsiberian":{"type":"GeometryCollection","geometries":[{"type":"LineString","arcs":[0]}]}},"arcs":[[[0,9201],[156,-120],[194,-59],[227,55],[219,-107],[79,113],[377,-47],[362,402],[123,7],[162,219],[154,-76],[78,-146],[218,164],[199,45],[74,171],[157,-58],[111,77],[199,-68],[452,226],[124,-370],[259,-71],[282,-417],[327,-440],[475,226],[227,-25],[486,-189],[227,431],[238,303],[223,6],[82,-73],[233,142],[147,-157],[71,32],[165,-185],[86,8],[230,231],[152,-51],[125,-188],[110,-547],[270,-239],[371,-1243],[-72,-347],[128,-148],[147,168],[51,140],[152,107],[32,-185],[-181,-382],[-24,-417],[10,-343],[-38,-369],[123,-375],[-36,-366],[62,-15],[98,-627],[136,-491],[78,-145],[76,-440],[89,-135],[50,-275],[140,-522],[109,-793],[20,-433],[-27,-171],[29,-469],[201,374],[117,-426],[77,-71]]],"transform":{"scale":[0.007878988395981626,0.0017309748573365665],"translate":[37.6488658453382,39.8482804429875]}}
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]