codepens/d3-map-projections/dist/script.js

171 lines
4.1 KiB
JavaScript

var canvasAny = d3.select("canvas#any"),
ctxAny = canvasAny.node().getContext("2d"),
canvasAnyWidth = +canvasAny.attr("width"),
canvasAnyHeight = +canvasAny.attr("height");
var projectionAny = d3
.geoMercator()
.rotate([-160, 0, -23.4])
.fitSize([canvasAnyWidth, canvasAnyHeight], {
type: "Sphere"
});
var geoPathGeneratorAny = d3
.geoPath()
.projection(projectionAny)
.context(ctxAny);
var canvasOrtho = d3.select("canvas#ortho"),
ctxOrtho = canvasOrtho.node().getContext("2d"),
canvasOrthoWidth = +canvasOrtho.attr("width"),
canvasOrthoHeight = +canvasOrtho.attr("height");
var projectionOrtho = d3
.geoOrthographic()
.rotate([-160, 0, -23.4])
.fitSize([canvasOrthoWidth, canvasOrthoHeight], {
type: "Sphere"
});
var geoPathGeneratorOrtho = d3
.geoPath()
.projection(projectionOrtho)
.context(ctxOrtho);
var selectElement = document.querySelector("select#projectionChoice");
selectElement.addEventListener("change", function(evt) {
changeProjection(evt.target.value);
});
var axialTilt = -23.4;
var axialTiltElement = document.querySelector("input#axialTilt");
axialTiltElement.addEventListener("change", function(evt) {
changeAxialTilt(evt.target.checked);
});
var geoCircles = {
type: "GeometryCollection",
geometries: []
};
for (var longitude = -180; longitude < 180; longitude += 15) {
for (var latitude = -90; latitude <= 90; latitude += 15) {
geoCircles.geometries.push(
d3
.geoCircle()
.center([longitude, latitude])
.radius(1)()
);
}
}
drawSphereAndCircles(geoCircles);
d3
.json("https://unpkg.com/world-atlas@1.1.4/world/110m.json")
.then(function(loadedTopoJson) {
var topology = topojson.presimplify(loadedTopoJson);
topology = topojson.simplify(topology, 1.1);
var worldGeoJson = topojson.feature(
topology,
topology.objects.land
);
d3.timer(function(elapsed) {
geoPathGeneratorAny
.projection()
.rotate([elapsed * 0.005 - 160, 0, axialTilt]);
geoPathGeneratorOrtho
.projection()
.rotate([elapsed * 0.005 - 160, 0, axialTilt]);
ctxOrtho.clearRect(0, 0, canvasOrthoWidth, canvasOrthoHeight);
ctxAny.clearRect(0, 0, canvasAnyWidth, canvasAnyHeight);
drawWorld(worldGeoJson);
drawSphereAndCircles(geoCircles);
});
var totalOptions = selectElement.options.length;
var intervalTimer = d3.interval(function() {
if (selectElement.selectedIndex === totalOptions - 1) {
selectElement.selectedIndex = 1;
} else {
selectElement.selectedIndex++;
}
selectElement.dispatchEvent(new Event("change"));
}, 2500);
selectElement.addEventListener("focus", function() {
intervalTimer.stop();
});
});
function drawWorld(worldGeoJson) {
ctxOrtho.beginPath();
ctxOrtho.fillStyle = "#b2df8a";
geoPathGeneratorOrtho(worldGeoJson);
ctxOrtho.fill();
ctxOrtho.closePath();
ctxAny.beginPath();
ctxAny.fillStyle = "#b2df8a";
geoPathGeneratorAny(worldGeoJson);
ctxAny.fill();
ctxAny.closePath();
}
function drawSphereAndCircles(geoCircles) {
ctxOrtho.beginPath();
ctxOrtho.fillStyle = "#1f78b4";
geoPathGeneratorOrtho(geoCircles);
ctxOrtho.fill();
ctxOrtho.closePath();
ctxOrtho.beginPath();
ctxOrtho.strokeStyle = "#1f78b4";
geoPathGeneratorOrtho({ type: "Sphere" });
ctxOrtho.stroke();
ctxOrtho.closePath();
ctxAny.beginPath();
ctxAny.fillStyle = "#1f78b4";
geoPathGeneratorAny(geoCircles);
ctxAny.fill();
ctxAny.closePath();
ctxAny.beginPath();
ctxAny.strokeStyle = "#1f78b4";
geoPathGeneratorAny({ type: "Sphere" });
ctxAny.stroke();
ctxAny.closePath();
}
function changeProjection(d3ProjectionName) {
var newProjection = d3[d3ProjectionName]().fitSize(
[canvasAnyWidth, canvasAnyHeight],
{
type: "Sphere"
}
);
geoPathGeneratorAny.projection(newProjection);
}
function changeAxialTilt(checked) {
var newAxialTilt = checked ? -23.4 : 0;
d3
.select({})
.transition()
.duration(1250)
.tween(null, function() {
var interpolator = d3.interpolate(axialTilt, newAxialTilt);
return function(t) {
axialTilt = interpolator(t);
};
});
}