Experimenting with d3.geoCircle to create animated circles on an orthographic projection.
This animation needs to be tweened because d3.transition doesn't really work with geoCircle.
| license: mit | 
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <script src="https://d3js.org/topojson.v2.min.js"></script> | |
| <style> | |
| body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
| .ocean { | |
| fill: #dadada; | |
| } | |
| .geoCircle { | |
| fill: red; | |
| fill-opacity: 0.5; | |
| stroke: red; | |
| stroke-width: 2px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <script> | |
| const margin = {top: 50, right: 0, bottom: 50, left: 0}; | |
| const width = 960 - margin.left - margin.right, | |
| height = 500 - margin.top - margin.bottom; | |
| var svg = d3.select("body").append("svg") | |
| .attr("width", width + margin.left + margin.right) | |
| .attr("height", height + margin.top + margin.bottom) | |
| .append("g") | |
| .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
| const config = { | |
| radius: 90 * 0.5, | |
| center: [0.1278, 51.5074] | |
| } | |
| d3.json("https://unpkg.com/[email protected]/world/110m.json", (error, world) => { | |
| var land = topojson.feature(world, world.objects.land); | |
| var projection = d3.geoOrthographic() | |
| .fitSize([width, height], land) | |
| .clipAngle(90) | |
| .precision(0); | |
| var path = d3.geoPath() | |
| .projection(projection); | |
| var geoCircle = d3.geoCircle(); | |
| var ocean = svg.append("circle") | |
| .attr("class", "ocean") | |
| .attr("cx", width / 2) | |
| .attr("cy", height / 2) | |
| .attr("r", height / 2); | |
| var earth = svg.append("path") | |
| .datum(land) | |
| .attr("d", path); | |
| var circle = svg.append("path") | |
| .datum({endAngle: 0}) | |
| .attr("class", "geoCircle") | |
| .attr("d", d => path(geoCircle.center(config.center).radius(d.endAngle)())); | |
| circle.transition() | |
| .delay(1000) | |
| .duration(4000) | |
| .ease(d3.easeLinear) | |
| .attrTween("d", geoCircleTween(config.radius)); | |
| function geoCircleTween(newAngle) { | |
| return function(d) { | |
| var interpolate = d3.interpolate(d.endAngle, newAngle); | |
| return function(t) { | |
| d.endAngle = interpolate(t); | |
| return path(geoCircle.center(config.center).radius(d.endAngle)()); | |
| }; | |
| }; | |
| } | |
| }); | |
| </script> | |
| </body> |