Skip to content

Instantly share code, notes, and snippets.

Last active June 12, 2017 03:35
Show Gist options
  • Save kforeman/b11e691c7377c845b2257664701c3917 to your computer and use it in GitHub Desktop.
Save kforeman/b11e691c7377c845b2257664701c3917 to your computer and use it in GitHub Desktop.
flubber tests
license: mit

Testing of veltman/flubber Built with


  1. Some countries break when calling flubber.combine on them.
  • E.g. if you add the United States back in (by removing 840 from the end of line 46) you'll get an error that: Uncaught RangeError: Can't collapse topology into 10 pieces.

  • Changing maxSegmentLength can cause more countries to break.

  1. While circlePath(x,y,radius) (line 31) returns a perfect SVG circle path, the result of interpolating to it is ~octagonal.
  • Decreasing maxSegmentLength makes it more circular, but at the expense of performance.

  • Could be fixed by calling one final transition to go from the final interpolated step to the circle, but maybe that should be a built-in feature of the interpolator?

  • EDIT: should be fixed by

<!DOCTYPE html>
<meta charset="utf-8">
<script src=""></script>
<script src=""></script>
<script src=""></script>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
var width = 960,
height = 500;
var rows = 10,
cols = 20;
var svg ="body").append("svg")
.attr("width", width)
.attr("height", height);
.defer(d3.json, "")
function circlePath(x, y, radius) {
var l = `${x - radius},${y}`,
r = `${x + radius},${y}`,
pre = `A${radius},${radius},0,1,1`;
return `M${l}${pre},${r}${pre},${l}Z`;
.attr("d", circlePath(width/2, height/2, 15))
.style("fill", "red");
function drawMap(error, worldMap) {
// hackily get rid of Canada, Indonesia, Russia, USA...
worldMap.objects.countries.geometries =
worldMap.objects.countries.geometries.filter(function(d) {
return [124,360,643,840].indexOf( : === -1;
var feature = topojson.feature(worldMap, worldMap.objects.countries);
var proj = d3.geoEquirectangular()
.fitSize([width, height], feature);
var geoPath = d3.geoPath().projection(proj);
var path = svg.selectAll("country")
.style("fill", "steelblue")
.attr("d", function(d) { return geoPath(d); });
var inward =,i) {
return flubber.combine(flubber.splitPathString(geoPath(d)),
{ single: true });
var outward =,i) {
return flubber.separate(circlePath((1+(i%cols))*(width/cols),
{ single: true });
function morph() {
.attrTween("d", function(d,i) {
return inward[i];
.attrTween("d", function(d,i) {
return outward[i];
//.on("end", morph)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment