planetary.js/src/plugins.js

151 lines
4.3 KiB
JavaScript

planetaryjs.plugins.topojson = function(config) {
return function(planet) {
planet.plugins.topojson = {};
planet.onInit(function(done) {
if (config.world) {
planet.plugins.topojson.world = config.world;
setTimeout(done, 0);
} else {
var file = config.file || 'world-110m.json'
d3.json(file, function(err, world) {
if (err) {
throw new Error("Could not load JSON " + file);
}
planet.plugins.topojson.world = world;
done();
});
}
});
};
};
planetaryjs.plugins.oceans = function(config) {
return function(planet) {
planet.onDraw(function() {
planet.withSavedContext(function(context) {
context.beginPath();
planet.path.context(context)({type: 'Sphere'});
context.fillStyle = config.fill || 'black';
context.fill();
});
});
};
};
planetaryjs.plugins.land = function(config) {
return function(planet) {
var land = null;
planet.onInit(function() {
var world = planet.plugins.topojson.world;
land = topojson.feature(world, world.objects.land);
})
planet.onDraw(function() {
planet.withSavedContext(function(context) {
context.beginPath();
planet.path.context(context)(land);
if (config.fill != false) {
context.fillStyle = config.fill || 'white';
context.fill();
}
if (config.stroke) {
context.strokeStyle = config.stroke;
context.stroke();
}
});
});
};
};
planetaryjs.plugins.borders = function(config) {
return function(planet) {
var borders = null;
planet.onInit(function() {
var world = planet.plugins.topojson.world;
var countries = world.objects.countries;
borders = topojson.mesh(world, countries, function(a, b) {
return a.id !== b.id;
});
});
planet.onDraw(function() {
planet.withSavedContext(function(context) {
context.beginPath();
planet.path.context(context)(borders);
context.strokeStyle = config.stroke || 'gray';
context.stroke();
});
});
};
};
planetaryjs.plugins.earth = function(config) {
var config = config || {};
var topojsonOptions = config.topojson || {};
var oceanOptions = config.oceans || {};
var landOptions = config.land || {};
var bordersOptions = config.borders || {};
return function(planet) {
planetaryjs.plugins.topojson(topojsonOptions)(planet);
planetaryjs.plugins.oceans(oceanOptions)(planet);
planetaryjs.plugins.land(landOptions)(planet);
planetaryjs.plugins.borders(bordersOptions)(planet);
};
};
planetaryjs.plugins.pings = function(config) {
var pings = [];
var addPing = function(lat, lng, options) {
var options = options || {};
options.color = options.color || 'white';
options.ttl = options.ttl || 2000;
options.angle = options.angle || 5;
pings.push({ lat: lat, lng: lng, time: new Date(), options: options });
};
var drawPings = function(planet, context, now) {
var newPings = [];
for (var i = 0; i < pings.length; i++) {
var ping = pings[i];
var alive = now - ping.time;
if (alive < ping.options.ttl) {
newPings.push(ping);
drawPing(planet, context, now, alive, ping);
}
}
pings = newPings;
};
var drawPing = function(planet, context, now, alive, ping) {
var alpha = 1 - (alive / ping.options.ttl);
var color = d3.rgb(ping.options.color);
color = "rgba(" + color.r + "," + color.g + "," + color.b + "," + alpha + ")";
context.strokeStyle = color;
var circle = d3.geo.circle().origin([ping.lng, ping.lat])
.angle(alive / ping.options.ttl * ping.options.angle)();
context.beginPath();
planet.path.context(context)(circle);
context.stroke();
};
return function (planet) {
planet.plugins.pings = {
add: addPing
};
planet.onDraw(function() {
var now = new Date();
planet.withSavedContext(function(context) {
drawPings(planet, context, now);
});
});
};
};