Skip to content

Instantly share code, notes, and snippets.

@martgnz
Last active October 3, 2023 04:20
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save martgnz/c1a5addfb6c2ec914f2d0bc9b3112b71 to your computer and use it in GitHub Desktop.
Save martgnz/c1a5addfb6c2ec914f2d0bc9b3112b71 to your computer and use it in GitHub Desktop.
Canvas Globe
license: mit
border: none
<!DOCTYPE html>
<meta charset="utf-8" />
<body>
<link href='https://fonts.googleapis.com/css?family=Roboto:400,400italic' rel='stylesheet' type='text/css'>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script src="https://unpkg.com/rbush@1.4.3/rbush.js"></script>
<script src="https://unpkg.com/spamjs@1.1.0/spam.min.js"></script>
<script type='text/javascript'>
var graticule = d3.geo.graticule();
// Canvas radial gradient
var x = 960 / 2,
y = 500 / 2,
// Radii of the start glow.
innerRadius = 60,
// Radii of the end glow.
outerRadius = 480,
// Radius of the entire circle.
radius = 480;
// Canvas doesn't support letter spacing :___)
// https://www.cs.tut.fi/~jkorpela/chars/spaces.html
var circles = [
{ name: "S W I T Z E R L A N D", coordinates: [8.424757, 46.94344] }
];
// SIX-PER-EM SPACE
var continents = [
{ name: "A M E R I C A", coordinates: [-80.262723, 40.26839] },
{ name: "A F R I C A", coordinates: [5.889621, 5.409892] },
{ name: "A S I A", coordinates: [80.041964, 35.059898] }
];
// THIN spaces
var oceans = [
{ name: "A T L A N T I C", coordinates: [-38.934598, 22.964389] },
{ name: "O C E A N", coordinates: [-36.571317, 16.993163] }
];
d3.json("world.json", function(error, d) {
topojson.presimplify(d);
var map = new StaticCanvasMap({
element: "body",
width: 960,
height: 500,
projection: d3.geo
.orthographic()
.clipAngle(90)
.precision(0.1)
.scale(240)
.rotate([0, -45, 0]),
data: [
{
features: topojson.feature(d, d.objects["countries"]),
static: {
prepaint: function(parameters) {
parameters.context.beginPath();
parameters.path({ type: "Sphere" });
parameters.context.lineWidth = 2;
parameters.context.strokeStyle = "rgb(198, 197, 197)";
parameters.context.stroke();
var gradient = parameters.context.createRadialGradient(
x,
y,
innerRadius,
x,
y,
outerRadius
);
gradient.addColorStop(0, "rgb(230, 239, 239)");
gradient.addColorStop(1, "rgb(200, 200, 200)");
parameters.context.fillStyle = gradient;
parameters.context.fill();
parameters.context.beginPath();
parameters.path(graticule());
parameters.context.lineWidth = 0.2;
parameters.context.strokeStyle = "rgba(30,30,30, 0.1)";
parameters.context.stroke();
},
paintfeature: function(parameters, d) {
parameters.context.lineWidth = 0.5 / parameters.scale;
parameters.context.strokeStyle = "rgba(0,0,0, 0.3)";
parameters.context.stroke();
if (d.properties.sovereignt === "Switzerland") {
parameters.context.fillStyle = "orange";
} else {
parameters.context.fillStyle = "#f1ede6";
}
parameters.context.fill();
},
postpaint: function(parameters) {
for (var i in circles) {
parameters.context.beginPath();
parameters.context.textAlign = "center";
var circle = circles[i];
var projectedPoint = parameters.map
.settings()
.projection(circle.coordinates);
parameters.context.arc(
projectedPoint[0],
projectedPoint[1] / parameters.scale,
10 / parameters.scale,
0,
2 * Math.PI,
true
);
parameters.context.font = "18px Roboto";
parameters.context.fillStyle = "rgba(70, 70, 70, 0.8)";
parameters.context.fillText(
circle.name,
projectedPoint[0],
projectedPoint[1] - 15
);
parameters.context.strokeStyle = "rgb(126, 120, 117)";
parameters.context.lineWidth = 1.5 / parameters.scale;
parameters.context.stroke();
}
for (var i in continents) {
parameters.context.beginPath();
parameters.context.textAlign = "center";
var continent = continents[i];
var projectedPoint = parameters.map
.settings()
.projection(continent.coordinates);
parameters.context.font = "16px Roboto";
parameters.context.fillStyle = "rgba(155, 155, 155, 1)";
parameters.context.fillText(
continent.name,
projectedPoint[0],
projectedPoint[1] - 15
);
parameters.context.stroke();
}
for (var i in oceans) {
parameters.context.beginPath();
parameters.context.textAlign = "center";
var ocean = oceans[i];
var projectedPoint = parameters.map
.settings()
.projection(ocean.coordinates);
parameters.context.font = "italic 16px Roboto";
parameters.context.fillStyle = "rgba(122, 148, 149, 0.8)";
parameters.context.fillText(
ocean.name,
projectedPoint[0],
projectedPoint[1] - 15
);
parameters.context.stroke();
}
}
}
}
]
});
map.init();
});
</script>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment