index.html
<!DOCTYPE html>
<html>
<head>
<title>Map Arc Transition</title>
<style>
.states {
fill: #ccc;
stroke: #fff;
stroke-width: 0.5px;
stroke-linejoin: round;
stroke-linecap: round;
}
.arc {
fill: none;
stroke: red;
stroke-width: 2px;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<svg width="500" height="500"></svg>
<script>
var width = 500,
height = 500;
var svg = d3.select("svg");
var projection = d3.geoMercator()
.scale(2800)
.rotate([86, 0])
.center([0, 43.2])
.translate([width / 2, height / 2]);
var path = d3.geoPath().projection(projection);
var clipPath = svg.append("defs")
.append("clipPath").attr("id", "circle-clip")
.append("circle")
.attr("cy", "50%")
.attr("cx", "50%")
.attr("r", "50%")
.attr("fill", "transparent");
var g = svg.append("g")
.attr("clip-path", "url(#circle-clip)");
var aa = [-83.7377, 42.2733];
var chi = [-87.732, 41.8338];
function link(p1, p2) {
var start = projection(p1);
var end = projection(p2);
return "M" + start[0] + "," + start[1]
+ "C" + (start[0] + end[0]) / 2 + "," + start[1]
+ " " + (start[0] + end[0]) / 2 + "," + start[1]
+ " " + end[0] + "," + end[1];
}
function transition(path) {
path.transition()
.duration(1000)
.attrTween("stroke-dasharray", tweenDash);
}
function tweenDash() {
var l = this.getTotalLength(),
i = d3.interpolateString("0," + l, l + "," + l);
return function (t) { return i(t); };
}
function translateAlong(path, attr) {
var l = path.getTotalLength();
return function (d, i, a) {
return function (t) {
var p = path.getPointAtLength(t * l);
return p[attr];
};
};
}
d3.json("us-states.json", function (error, us) {
if (error) throw error;
g.selectAll("path")
.data(us.features)
.enter().append("path")
.attr("class", "states")
.attr("d", path);
g.append("path")
.attr("class", "arc")
.attr("d", link(aa, chi))
.call(transition);
var pAA = projection(aa);
var circle = g.append("circle")
.attr("width", 0)
.attr("height", 0)
.attr("fill", "blue")
.attr("cx", pAA[0])
.attr("cy", pAA[1])
.attr("r", 15);
circle.transition()
.duration(1000)
.attrTween("cx", translateAlong(d3.select("path.arc").node(), "x"))
.attrTween("cy", translateAlong(d3.select("path.arc").node(), "y"));
});
</script>
</body>
</html>