JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js"></script>
<button>Toggle Projection</button>
CSS
body {
padding:0;
margin:0;
}
.foreground {
fill: none;
stroke: #000;
stroke-width: 1px;
pointer-events: all;
cursor: -webkit-grab;
cursor: -moz-grab;
}
.foreground.dragging {
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
}
.state-mesh {
stroke:#BABFA1;
fill:transparent;
}
.graticule {
stroke: #E3E3E3;
fill: transparent;
}
.land {
fill: #4D4C33;
}
.jelly {
fill: rgba(0, 0, 255, 0.1);
}
button {
position: absolute;
display: block;
background: #ff0000;
color: white;
bottom: 30px;
right: 30px;
border: 0;
outline: 0;
cursor: pointer;
}
JavaScript
var app = {
orthographic: 1
};
function bootstrapApplication(world) {
app.d3win = d3.select(window);
app.width = window.innerWidth;
app.height = window.innerHeight;
app.svg = d3.select('body')
.append('svg')
.attr('width', app.width)
.attr('height', app.height)
.on('mousedown', function() {
d3.select(this).classed('dragging', true);
})
.on('mouseup', function() {
d3.select(this).classed('dragging', false);
});;
app.g = app.svg.append('g');
//app.projection = ortho2Equi();
app.projection = orthographic();
app.path = d3.geo.path().projection(app.projection);
app.g.append('path')
.datum(d3.geo.graticule())
.attr('class', 'graticule')
.attr('d', app.path);
app.g.append('path')
.datum({
type: 'Sphere'
})
.attr('class', 'jelly foreground')
.attr('d', app.path);
app.g.append('path')
.datum(topojson.feature(world, world.objects.land))
.attr('class', 'land foreground')
.attr('d', app.path);
app.g.append('path')
.datum(topojson.mesh(world, world.objects.countries))
.attr('class', 'state-mesh foreground')
.attr('d', app.path)
app.g.call(setupDrag());
app.paths = app.svg.selectAll("path");
d3.select('button').on('click', function() {
app.svg.transition()
.duration(2000)
.tween("projection", function() {
return function(_) {
app.projection.alpha(_);
app.paths.attr("d", app.path);
};
})
.transition()
.each('end', function() {
app.projection = app.orthographic ? equi2ortho() : ortho2Equi();
app.path.projection(app.projection);
alert('ended');
})
app.orthographic = !app.orthographic;
});
}
function interpolatedProjection(a, b) {
var projection = d3.geo.projection(raw)
.scale(1);
var center = projection.center;
var clip = projection.clipAngle;
var translate = projection.translate;
var α;
function raw(λ, φ) {
var...