First, you will create a few variables required for initialization. We’ll come back to this list as the application grows, but, for now, it’s lean:
var width = 960,
height = 600,
projectionScale = height / 2.1,
translation = [width / 2, height / 2];
You are setting the width and height of the Canvas as well as the scale and the translation of the globe. Each projection has their own ideal starting scale. You can play with this number to find the right scale. You will use the width and height straight away, setting up the Canvas and its context:
var canvas = d3.select('#canvas-container').append('canvas')
.attr('id', 'canvas-globe')
.attr('width', width)
.attr('height', height);
var context = canvas.node().getContext('2d');
No magic here. Note that we have a div with the #canvas-container ID in our HTML, in which you add the main Canvas.
Let’s also produce a bufferCanvas. You learned about the benefits of buffer Canvases in the preceding chapter. In short, rendering an image in memory and copying it onto your main Canvas is more performant than rendering an image directly onto the main Canvas:
var bufferCanvas = document.createElement('canvas');
var bufferContext = bufferCanvas.getContext('2d');
bufferContext.canvas.width = width;
bufferContext.canvas.height = height;
A rather central part of building a globe is the right projection. Building a globe reduces our options dramatically to the d3.geoOrthographic() projection, a 2D globe projection which is part of the standard d3-geo module. You already used it in chapter 5, Click-Click Boom! Applying Interactivity to Your Map. Let's set it up first:
var projection = d3.geoOrthographic()
.scale(projectionScale)
.translate(translation)
.clipAngle(90);
We applied the scale and translation array we specified above, as well as the .clipAngle() to 90 degrees to always clip the backside of the projection, our globe.
As we use the bufferCanvas for all our drawings, we will tie our projection to a path generator that will exclusively draw to the buffer Canvas , as follows:
var bufferPath = d3.geoPath()
.projection(projection)
.context(bufferContext);
There are two more geo helpers you will create: a base sphere and a graticule:
var sphere = { type: 'Sphere' };
var grid = d3.geoGraticule()();
Both are geo-visualization primitives. The sphere is, well, a sphere you use to underlay your globe with. You can then fill it or give it an outline to give your globe a round shape beyond the countries. A graticule is a grid of the main meridians (longitude lines) and parallels (latitude lines) 10 degrees apart from each other (and, yes, you need four parentheses to produce the actual graticule object). We shall see them in action very soon.