Skip to content

Instantly share code, notes, and snippets.

@tlfrd
Last active January 1, 2020 08:31
Show Gist options
  • Save tlfrd/0880fbf1bc462d1f28d8514ed8371aea to your computer and use it in GitHub Desktop.
Save tlfrd/0880fbf1bc462d1f28d8514ed8371aea to your computer and use it in GitHub Desktop.
Orthographic Pulse
license: mit

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.

<!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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment