Testing of veltman/flubber Built with blockbuilder.org
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.
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 https://github.com/veltman/flubber/pull/2/files
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/flubber"></script>
<script src="https://d3js.org/topojson.v3.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
var width = 960,
height = 500;
var rows = 10,
cols = 20;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
d3.queue()
.defer(d3.json, "https://unpkg.com/world-atlas@1.1.4/world/110m.json")
.await(drawMap);
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`;
}
svg.append("path")
.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(d.id? +d.id : +d.properties.id) === -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")
.data(feature.features)
.enter().append("path")
.style("fill", "steelblue")
.attr("d", function(d) { return geoPath(d); });
var inward = feature.features.map(function(d,i) {
return flubber.combine(flubber.splitPathString(geoPath(d)),
circlePath((1+(i%cols))*(width/cols),
(Math.floor(i/cols)+1)*(height/rows),
15),
{ single: true });
});
var outward = feature.features.map(function(d,i) {
return flubber.separate(circlePath((1+(i%cols))*(width/cols),
(Math.floor(i/cols)+1)*(height/rows),
15),
flubber.splitPathString(geoPath(d)),
{ single: true });
});
function morph() {
path
.transition().delay(2000).duration(3000)
.attrTween("d", function(d,i) {
return inward[i];
})
.transition().delay(2000).duration(3000)
.attrTween("d", function(d,i) {
return outward[i];
})
//.on("end", morph)
}
morph();
}
</script>
</body>
https://d3js.org/d3.v4.min.js
https://unpkg.com/flubber
https://d3js.org/topojson.v3.min.js