Skip to content

Instantly share code, notes, and snippets.

@mxfh
Last active December 11, 2015 23:48
Show Gist options
  • Save mxfh/4679442 to your computer and use it in GitHub Desktop.
Save mxfh/4679442 to your computer and use it in GitHub Desktop.
simple overlayed globe canvas
{"description":"simple overlayed globe canvas","endpoint":"","display":"canvas","public":true,"require":[{"name":"topojson","url":"http://d3js.org/topojson.v0.min.js"},{"name":"d3.geo.projection","url":"http://d3js.org/d3.geo.projection.v0.min.js"}],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"world110.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"leap.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"globes.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"ne_110m_world.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"ne_110m_world110m.json":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01}
// simple overlayed globe canvas
// by Max Friedrich Hartmann
// github/twitter: @mxfh
// comments are welcome my javascript skills need some serious improvement
// uses d3.js and topojson
// http://bl.ocks.org/4188334
// basic framework based on simple globe canvas by ejfox
// http://tributary.io/inlet/4670598
// TODO: improve mouse interaction
// TODO: add cities+labels
// TODO: add circles of latitude
// TODO: optimize canvas speed
// TODO: add mirror option
// TODE: add gradient toggle key
// A faster loading Version can be found here:
//
// http://mxfh.github.com/d3canvasglobes/
//
// gotta love Tributary for getting me started
var world, globe, countries,
λA, φA, γA, λB, φB, γB,
rotationA, rotationB, projectionA, projectionB,
context, pathA, pathB,
x, y, xtmp, ytmp, xrel, yrel, flag, shiftflag, altflag;
flag = 0;
shiftflag = 0;
altflag = 0;
// λ (longitude) and φ (latitude) of projection center, rotation angle (γ) counter-clockwise in degrees
// inital seetings
if (λA === undefined) {
λA = 0, φA = -10, γA = 0, λB = -50, φB = -13, γB = 44; // African and South American Coastlines
}
document.onkeydown = function(evt) {
evt = evt || window.event;
if (evt.keyCode === 16) {
shiftflag = 1;
}
if (evt.keyCode === 18) {
altflag = 1;
}
// reset on r or 0
if (evt.keyCode === 82 || evt.keyCode === 48) {
λA = 0; φA = 0; γA = 0; λB = 0; φB = 0; γB = 0;
drawglobes(λA,φA,γA,λB,φB,γB);
}
if (evt.keyCode === 49) {
λA = 0; φA = -10; γA = 0; λB = -50; φB = -13; γB = 44; // Preset 1: African and South American Coastlines
drawglobes(λA,φA,γA,λB,φB,γB);
}
if (evt.keyCode === 50) {
λA = 15; φA = 10; γA = 0; λB = -100; φB = 10; γB = 0; // Preset 2: Europe - America
drawglobes(λA,φA,γA,λB,φB,γB);
}
if (evt.keyCode === 51) {
λA = 0; φA = 90; γA = 0; λB = 120; φB = -90; γB = 0; // Preset 3: Overlayed poles
drawglobes(λA,φA,γA,λB,φB,γB);
}
};
document.onkeyup = function(evt) {
evt = evt || window.event;
if (evt.keyCode == 16) {
shiftflag = 0;
}
if (evt.keyCode === 18) {
altflag = 0;
}
};
world = tributary.world110;
globe = {type: "Sphere"};
countries = topojson.object(world, world.objects.countries);
var displayElement = document.getElementById("display");
var canvasElement = displayElement.getElementsByClassName("tributary_canvas")[0];
context = tributary.ctx;
function drawglobes(λA,φA,γA,λB,φB,γB){
context.clearRect(0, 0, 1000, 1000);
context.fillText( "Drag Mouse to move λ (longitude) and φ (latitude) of projection center." , 670, 20);
context.fillText( "Hold [Shift] to switch globe, hold [Alt] for rotation γ around center." , 693, 32);
context.fillText( "For presets press [1] - [3], [R] or [0] resets both globes to origin." , 711, 44);
rotationA = [-λA, -φA, γA];
rotationB = [-λB, -φB, γB];
// todo: put globe in function pass color and rotations as parameters
projectionA = d3.geo.orthographic().rotate(rotationA).scale(478).translate([495, 490]).clipAngle(88);
projectionB = d3.geo.orthographic().rotate(rotationB).scale(478).translate([495, 490]).clipAngle(88);
pathA = d3.geo.path().projection(projectionA).context(context);
pathB = d3.geo.path().projection(projectionB).context(context);
//console.log("rota:", rotationA, "rotB:", rotationB);
context.beginPath();
context.fillStyle = "#5CA2C9";
pathA(countries);
context.fill();
context.beginPath();
context.fillStyle = "rgba(230, 90, 10, 0.7)";
pathB(countries);
context.fill();
context.strokeStyle = "rgba(0, 0, 0, 0.2)";
context.beginPath();
pathA(globe);
gradient_water = context.createRadialGradient(350,100,0,495,490,480);
gradient_water.addColorStop(0, "rgba(78, 225, 216, 0)");
gradient_water.addColorStop(0.4, "rgba(58, 205, 196, 0.05)");
gradient_water.addColorStop(0.8, "rgba(38, 185, 176, 0.1)");
gradient_water.addColorStop(0.95, "rgba(18, 165, 156, 0.3)");
gradient_water.addColorStop(1, "rgba(0, 145, 136, 0.7)");
context.fillStyle = gradient_water;
context.fill();
context.stroke();
};
drawglobes(λA,φA,γA,λB,φB,γB);
function renderPositionInfo() {
context.clearRect ( 20 , 10 , 250 , 60 );
context.fillStyle = "rgba(0, 0, 0, 0.7)";
if (x !== undefined) {context.fillText("x : " + x , 20, 20);}
if (y !== undefined) {context.fillText("y : " + y , 20, 32);}
context.fillText("λᴬ : " + Math.round(λA) , 60, 20);
context.fillText("λᴮ : " + Math.round(λB) , 100, 20);
context.fillText("φᴬ : " + Math.round(φA) , 60, 32);
context.fillText("φᴮ : " + Math.round(φB) , 100, 32);
if (γA !== 0) {context.fillText("γᴬ : " + Math.round(γA) , 60, 44); }
if (γB !== 0) {context.fillText("γᴮ : " + Math.round(γB) , 100, 44); }
}
renderPositionInfo();
function track(e) {
x = e.offsetX||e.layerX;
y = e.offsetY||e.layerY;
var mousefactor = 80;
if(flag === 1){
xrel = x-xtmp;
yrel = y-ytmp;
if (shiftflag === 0) {
if (altflag === 0) {
λA = λA - xrel/mousefactor;
φA = φA + yrel/mousefactor;
}
if (altflag === 1) {
γA = γA - xrel/mousefactor;
}
}
if (shiftflag === 1) {
if (altflag === 0) {
λB = λB - xrel/mousefactor;
φB = φB + yrel/mousefactor;
}
if (altflag === 1) {
γB = γB - xrel/mousefactor;
}
}
//console.log("drag",xrel, yrel,canvasElement.width);
drawglobes(λA,φA,γA,λB,φB,γB);
}
renderPositionInfo();
}
canvasElement.addEventListener("mousemove", track, false);
canvasElement.addEventListener("mousedown", function(e){
xtmp = e.offsetX||e.layerX;
ytmp = e.offsetY||e.layerY;
//console.log("click",xtmp,ytmp);
flag = 1;
}, false);
canvasElement.addEventListener("mouseup", function(){
flag = 0;
}, false);
//console.log("script executed");
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