171 lines
4.1 KiB
JavaScript
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);
|
|
};
|
|
});
|
|
} |