Fix broken plugins; add pings plugin; refactor core code
This commit is contained in:
parent
ac1c54968d
commit
4102091a50
41
dist/planetaryjs-noplugins.js
vendored
41
dist/planetaryjs-noplugins.js
vendored
@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 2013 Brandon Tilley
|
* Copyright (c) 2013 Brandon Tilley
|
||||||
*
|
*
|
||||||
* Released under the MIT license
|
* Released under the MIT license
|
||||||
* Date: 2013-12-21T08:56:23.017Z
|
* Date: 2013-12-21T19:00:54.881Z
|
||||||
*/
|
*/
|
||||||
(function (root, factory) {
|
(function (root, factory) {
|
||||||
if (typeof define === 'function' && define.amd) {
|
if (typeof define === 'function' && define.amd) {
|
||||||
@ -28,24 +28,28 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var startDraw = function(planet, canvas, localPlugins, hooks) {
|
var initPlugins = function(planet, localPlugins) {
|
||||||
|
// Add the global plugins to the beginning of the local ones
|
||||||
for (var i = 0; i < plugins.length; i++) {
|
for (var i = 0; i < plugins.length; i++) {
|
||||||
localPlugins.unshift(plugins[i]);
|
localPlugins.unshift(plugins[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localPlugins.length == 0 && planetaryjs.plugins.earth) {
|
// Load the default plugins if none have been loaded so far
|
||||||
planet.loadPlugin(planetaryjs.plugins.earth());
|
if (localPlugins.length == 0) {
|
||||||
|
if (planetaryjs.plugins.earth)
|
||||||
|
planet.loadPlugin(planetaryjs.plugins.earth());
|
||||||
|
if (planetaryjs.plugins.pings)
|
||||||
|
planet.loadPlugin(planetaryjs.plugins.pings());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < localPlugins.length; i++) {
|
for (var i = 0; i < localPlugins.length; i++) {
|
||||||
var plugin = localPlugins[i][0];
|
localPlugins[i](planet);
|
||||||
var config = localPlugins[i][1];
|
|
||||||
plugin(planet, config);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
planet.canvas = canvas;
|
var runOnInitHooks = function(planet, canvas, hooks) {
|
||||||
planet.context = canvas.getContext('2d');
|
// onInit hooks can be asynchronous if they take a parameter;
|
||||||
|
// iterate through them one at a time
|
||||||
if (hooks.onInit.length) {
|
if (hooks.onInit.length) {
|
||||||
var completed = 0;
|
var completed = 0;
|
||||||
var doNext = function(callback) {
|
var doNext = function(callback) {
|
||||||
@ -71,6 +75,15 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var startDraw = function(planet, canvas, localPlugins, hooks) {
|
||||||
|
initPlugins(planet, localPlugins);
|
||||||
|
|
||||||
|
planet.canvas = canvas;
|
||||||
|
planet.context = canvas.getContext('2d');
|
||||||
|
|
||||||
|
runOnInitHooks(planet, canvas, hooks);
|
||||||
|
};
|
||||||
|
|
||||||
var planetaryjs = {
|
var planetaryjs = {
|
||||||
plugins: {},
|
plugins: {},
|
||||||
|
|
||||||
@ -79,8 +92,8 @@
|
|||||||
return planetaryjs;
|
return planetaryjs;
|
||||||
},
|
},
|
||||||
|
|
||||||
loadPlugin: function(plugin, defaultOptions) {
|
loadPlugin: function(plugin) {
|
||||||
plugins.push([plugin, defaultOptions || {}]);
|
plugins.push(plugin);
|
||||||
},
|
},
|
||||||
|
|
||||||
planet: function() {
|
planet: function() {
|
||||||
@ -103,8 +116,8 @@
|
|||||||
hooks.onDraw.push(fn);
|
hooks.onDraw.push(fn);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadPlugin: function(plugin, defaultOptions) {
|
loadPlugin: function(plugin) {
|
||||||
localPlugins.push([plugin, defaultOptions || {}]);
|
localPlugins.push(plugin);
|
||||||
},
|
},
|
||||||
|
|
||||||
withSavedContext: function(fn) {
|
withSavedContext: function(fn) {
|
||||||
|
|||||||
2
dist/planetaryjs-noplugins.min.js
vendored
2
dist/planetaryjs-noplugins.min.js
vendored
@ -1,2 +1,2 @@
|
|||||||
/*! Planetary.js 0.0.0 | (c) 2013 Brandon Tilley | Released under MIT License */
|
/*! Planetary.js 0.0.0 | (c) 2013 Brandon Tilley | Released under MIT License */
|
||||||
!function(n,t){"function"==typeof define&&define.amd?define(["d3","topojson"],t):"object"==typeof exports?module.exports=t(require("d3"),require("topojson")):n.planetaryjs=t(n.d3,n.topojson,n)}(this,function(n,t,o){"use strict";var e=null;o&&(e=o.planetaryjs);var i=[],r=function(t,o,e){n.timer(function(){t.context.clearRect(0,0,o.width,o.height);for(var n=0;n<e.onDraw.length;n++)e.onDraw[n]()})},a=function(n,t,o,e){for(var a=0;a<i.length;a++)o.unshift(i[a]);0==o.length&&c.plugins.earth&&n.loadPlugin(c.plugins.earth());for(var a=0;a<o.length;a++){var u=o[a][0],f=o[a][1];u(n,f)}if(n.canvas=t,n.context=t.getContext("2d"),e.onInit.length){var s=0,h=function(n){var t=e.onInit[s];t.length?t(function(){s++,n()}):(t(),s++,setTimeout(n,0))},l=function(){s>=e.onInit.length?r(n,t,e):h(l)};h(l)}else r(n,t,e)},c={plugins:{},noConflict:function(){return o.planetaryjs=e,c},loadPlugin:function(n,t){i.push([n,t||{}])},planet:function(){var t=[],o={onInit:[],onDraw:[]},e={draw:function(n){a(e,n,t,o)},onInit:function(n){o.onInit.push(n)},onDraw:function(n){o.onDraw.push(n)},loadPlugin:function(n,o){t.push([n,o||{}])},withSavedContext:function(n){if(!this.context)throw new Error("No canvas to fetch context for");this.context.save(),n(this.context),this.context.restore()}};return e.projection=n.geo.orthographic().clipAngle(90).precision(0),e.path=n.geo.path().projection(e.projection),e}};return c});
|
!function(n,t){"function"==typeof define&&define.amd?define(["d3","topojson"],t):"object"==typeof exports?module.exports=t(require("d3"),require("topojson")):n.planetaryjs=t(n.d3,n.topojson,n)}(this,function(n,t,o){"use strict";var e=null;o&&(e=o.planetaryjs);var i=[],r=function(t,o,e){n.timer(function(){t.context.clearRect(0,0,o.width,o.height);for(var n=0;n<e.onDraw.length;n++)e.onDraw[n]()})},u=function(n,t){for(var o=0;o<i.length;o++)t.unshift(i[o]);0==t.length&&(s.plugins.earth&&n.loadPlugin(s.plugins.earth()),s.plugins.pings&&n.loadPlugin(s.plugins.pings()));for(var o=0;o<t.length;o++)t[o](n)},c=function(n,t,o){if(o.onInit.length){var e=0,i=function(n){var t=o.onInit[e];t.length?t(function(){e++,n()}):(t(),e++,setTimeout(n,0))},u=function(){e>=o.onInit.length?r(n,t,o):i(u)};i(u)}else r(n,t,o)},a=function(n,t,o,e){u(n,o),n.canvas=t,n.context=t.getContext("2d"),c(n,t,e)},s={plugins:{},noConflict:function(){return o.planetaryjs=e,s},loadPlugin:function(n){i.push(n)},planet:function(){var t=[],o={onInit:[],onDraw:[]},e={draw:function(n){a(e,n,t,o)},onInit:function(n){o.onInit.push(n)},onDraw:function(n){o.onDraw.push(n)},loadPlugin:function(n){t.push(n)},withSavedContext:function(n){if(!this.context)throw new Error("No canvas to fetch context for");this.context.save(),n(this.context),this.context.restore()}};return e.projection=n.geo.orthographic().clipAngle(90).precision(0),e.path=n.geo.path().projection(e.projection),e}};return s});
|
||||||
260
dist/planetaryjs.js
vendored
260
dist/planetaryjs.js
vendored
@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 2013 Brandon Tilley
|
* Copyright (c) 2013 Brandon Tilley
|
||||||
*
|
*
|
||||||
* Released under the MIT license
|
* Released under the MIT license
|
||||||
* Date: 2013-12-21T08:56:22.909Z
|
* Date: 2013-12-21T19:00:54.985Z
|
||||||
*/
|
*/
|
||||||
(function (root, factory) {
|
(function (root, factory) {
|
||||||
if (typeof define === 'function' && define.amd) {
|
if (typeof define === 'function' && define.amd) {
|
||||||
@ -28,24 +28,28 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var startDraw = function(planet, canvas, localPlugins, hooks) {
|
var initPlugins = function(planet, localPlugins) {
|
||||||
|
// Add the global plugins to the beginning of the local ones
|
||||||
for (var i = 0; i < plugins.length; i++) {
|
for (var i = 0; i < plugins.length; i++) {
|
||||||
localPlugins.unshift(plugins[i]);
|
localPlugins.unshift(plugins[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localPlugins.length == 0 && planetaryjs.plugins.earth) {
|
// Load the default plugins if none have been loaded so far
|
||||||
planet.loadPlugin(planetaryjs.plugins.earth());
|
if (localPlugins.length == 0) {
|
||||||
|
if (planetaryjs.plugins.earth)
|
||||||
|
planet.loadPlugin(planetaryjs.plugins.earth());
|
||||||
|
if (planetaryjs.plugins.pings)
|
||||||
|
planet.loadPlugin(planetaryjs.plugins.pings());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < localPlugins.length; i++) {
|
for (var i = 0; i < localPlugins.length; i++) {
|
||||||
var plugin = localPlugins[i][0];
|
localPlugins[i](planet);
|
||||||
var config = localPlugins[i][1];
|
|
||||||
plugin(planet, config);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
planet.canvas = canvas;
|
var runOnInitHooks = function(planet, canvas, hooks) {
|
||||||
planet.context = canvas.getContext('2d');
|
// onInit hooks can be asynchronous if they take a parameter;
|
||||||
|
// iterate through them one at a time
|
||||||
if (hooks.onInit.length) {
|
if (hooks.onInit.length) {
|
||||||
var completed = 0;
|
var completed = 0;
|
||||||
var doNext = function(callback) {
|
var doNext = function(callback) {
|
||||||
@ -71,6 +75,15 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var startDraw = function(planet, canvas, localPlugins, hooks) {
|
||||||
|
initPlugins(planet, localPlugins);
|
||||||
|
|
||||||
|
planet.canvas = canvas;
|
||||||
|
planet.context = canvas.getContext('2d');
|
||||||
|
|
||||||
|
runOnInitHooks(planet, canvas, hooks);
|
||||||
|
};
|
||||||
|
|
||||||
var planetaryjs = {
|
var planetaryjs = {
|
||||||
plugins: {},
|
plugins: {},
|
||||||
|
|
||||||
@ -79,8 +92,8 @@
|
|||||||
return planetaryjs;
|
return planetaryjs;
|
||||||
},
|
},
|
||||||
|
|
||||||
loadPlugin: function(plugin, defaultOptions) {
|
loadPlugin: function(plugin) {
|
||||||
plugins.push([plugin, defaultOptions || {}]);
|
plugins.push(plugin);
|
||||||
},
|
},
|
||||||
|
|
||||||
planet: function() {
|
planet: function() {
|
||||||
@ -103,8 +116,8 @@
|
|||||||
hooks.onDraw.push(fn);
|
hooks.onDraw.push(fn);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadPlugin: function(plugin, defaultOptions) {
|
loadPlugin: function(plugin) {
|
||||||
localPlugins.push([plugin, defaultOptions || {}]);
|
localPlugins.push(plugin);
|
||||||
},
|
},
|
||||||
|
|
||||||
withSavedContext: function(fn) {
|
withSavedContext: function(fn) {
|
||||||
@ -127,97 +140,154 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
planetaryjs.plugins.topojson = function(planet, config) {
|
planetaryjs.plugins.topojson = function(config) {
|
||||||
planet.onInit(function(done) {
|
return function(planet) {
|
||||||
if (config.world) {
|
planet.onInit(function(done) {
|
||||||
planet.world = config.world;
|
if (config.world) {
|
||||||
setTimeout(done, 0);
|
planet.world = config.world;
|
||||||
} else {
|
setTimeout(done, 0);
|
||||||
var file = config.file || 'world-110m.json'
|
} else {
|
||||||
d3.json(file, function(err, world) {
|
var file = config.file || 'world-110m.json'
|
||||||
if (err) {
|
d3.json(file, function(err, world) {
|
||||||
throw new Error("Could not load JSON " + file);
|
if (err) {
|
||||||
}
|
throw new Error("Could not load JSON " + file);
|
||||||
planet.world = world;
|
}
|
||||||
done();
|
planet.world = world;
|
||||||
});
|
done();
|
||||||
}
|
});
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
planetaryjs.plugins.oceans = function(planet, config) {
|
|
||||||
planet.onDraw(function() {
|
|
||||||
planet.withSavedContext(function(context) {
|
|
||||||
context.beginPath();
|
|
||||||
planet.path.context(context)({type: 'Sphere'});
|
|
||||||
|
|
||||||
context.fillStyle = config.fill || 'black';
|
|
||||||
context.fill();
|
|
||||||
|
|
||||||
if (config.stroke != false) {
|
|
||||||
context.strokeStyle = config.stroke;
|
|
||||||
context.stroke();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
planetaryjs.plugins.land = function(planet, config) {
|
planetaryjs.plugins.oceans = function(config) {
|
||||||
var land = null;
|
return function(planet) {
|
||||||
|
planet.onDraw(function() {
|
||||||
|
planet.withSavedContext(function(context) {
|
||||||
|
context.beginPath();
|
||||||
|
planet.path.context(context)({type: 'Sphere'});
|
||||||
|
|
||||||
planet.onInit(function() {
|
context.fillStyle = config.fill || 'black';
|
||||||
land = topojson.feature(planet.world, planet.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();
|
context.fill();
|
||||||
}
|
|
||||||
|
|
||||||
if (config.stroke) {
|
if (config.stroke != false) {
|
||||||
context.strokeStyle = config.stroke;
|
context.strokeStyle = config.stroke;
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
planetaryjs.plugins.land = function(config) {
|
||||||
|
return function(planet) {
|
||||||
|
var land = null;
|
||||||
|
|
||||||
|
planet.onInit(function() {
|
||||||
|
land = topojson.feature(planet.world, planet.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 countries = planet.world.objects.countries;
|
||||||
|
borders = topojson.mesh(planet.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();
|
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.size = options.size || 500;
|
||||||
|
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, ping);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
pings = newPings;
|
||||||
|
};
|
||||||
|
|
||||||
|
var drawPing = function(planet, context, now, ping) {
|
||||||
|
var dT = now - ping.time;
|
||||||
|
var alpha = 1 - (dT / 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(dT / ping.options.size)();
|
||||||
|
context.beginPath();
|
||||||
|
planet.path.context(context)(circle);
|
||||||
|
context.stroke();
|
||||||
|
};
|
||||||
|
|
||||||
|
return function (planet) {
|
||||||
|
planet.addPing = addPing;
|
||||||
|
|
||||||
|
planet.onDraw(function() {
|
||||||
|
var now = new Date();
|
||||||
|
planet.withSavedContext(function(context) {
|
||||||
|
drawPings(planet, context, now);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
planetaryjs.plugins.borders = function(planet, config) {
|
|
||||||
var borders = null;
|
|
||||||
planet.onInit(function() {
|
|
||||||
var countries = planet.world.objects.countries;
|
|
||||||
borders = topojson.mesh(planet.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(options) {
|
|
||||||
var options = options || {};
|
|
||||||
var topojsonOptions = options.topojson || {};
|
|
||||||
var oceanOptions = options.oceans || {};
|
|
||||||
var landOptions = options.land || {};
|
|
||||||
var bordersOptions = options.borders || {};
|
|
||||||
|
|
||||||
return function(planet, options) {
|
|
||||||
planetaryjs.plugins.topojson(planet, topojsonOptions);
|
|
||||||
planetaryjs.plugins.oceans(planet, oceanOptions);
|
|
||||||
planetaryjs.plugins.land(planet, landOptions);
|
|
||||||
planetaryjs.plugins.borders(planet, bordersOptions);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
2
dist/planetaryjs.min.js
vendored
2
dist/planetaryjs.min.js
vendored
@ -1,2 +1,2 @@
|
|||||||
/*! Planetary.js 0.0.0 | (c) 2013 Brandon Tilley | Released under MIT License */
|
/*! Planetary.js 0.0.0 | (c) 2013 Brandon Tilley | Released under MIT License */
|
||||||
!function(n,t){"function"==typeof define&&define.amd?define(["d3","topojson"],t):"object"==typeof exports?module.exports=t(require("d3"),require("topojson")):n.planetaryjs=t(n.d3,n.topojson,n)}(this,function(n,t,o){"use strict";var e=null;o&&(e=o.planetaryjs);var i=[],r=function(t,o,e){n.timer(function(){t.context.clearRect(0,0,o.width,o.height);for(var n=0;n<e.onDraw.length;n++)e.onDraw[n]()})},l=function(n,t,o,e){for(var l=0;l<i.length;l++)o.unshift(i[l]);0==o.length&&u.plugins.earth&&n.loadPlugin(u.plugins.earth());for(var l=0;l<o.length;l++){var a=o[l][0],s=o[l][1];a(n,s)}if(n.canvas=t,n.context=t.getContext("2d"),e.onInit.length){var c=0,f=function(n){var t=e.onInit[c];t.length?t(function(){c++,n()}):(t(),c++,setTimeout(n,0))},h=function(){c>=e.onInit.length?r(n,t,e):f(h)};f(h)}else r(n,t,e)},u={plugins:{},noConflict:function(){return o.planetaryjs=e,u},loadPlugin:function(n,t){i.push([n,t||{}])},planet:function(){var t=[],o={onInit:[],onDraw:[]},e={draw:function(n){l(e,n,t,o)},onInit:function(n){o.onInit.push(n)},onDraw:function(n){o.onDraw.push(n)},loadPlugin:function(n,o){t.push([n,o||{}])},withSavedContext:function(n){if(!this.context)throw new Error("No canvas to fetch context for");this.context.save(),n(this.context),this.context.restore()}};return e.projection=n.geo.orthographic().clipAngle(90).precision(0),e.path=n.geo.path().projection(e.projection),e}};return u.plugins.topojson=function(t,o){t.onInit(function(e){if(o.world)t.world=o.world,setTimeout(e,0);else{var i=o.file||"world-110m.json";n.json(i,function(n,o){if(n)throw new Error("Could not load JSON "+i);t.world=o,e()})}})},u.plugins.oceans=function(n,t){n.onDraw(function(){n.withSavedContext(function(o){o.beginPath(),n.path.context(o)({type:"Sphere"}),o.fillStyle=t.fill||"black",o.fill(),0!=t.stroke&&(o.strokeStyle=t.stroke,o.stroke())})})},u.plugins.land=function(n,o){var e=null;n.onInit(function(){e=t.feature(n.world,n.world.objects.land)}),n.onDraw(function(){n.withSavedContext(function(t){t.beginPath(),n.path.context(t)(e),0!=o.fill&&(t.fillStyle=o.fill||"white",t.fill()),o.stroke&&(t.strokeStyle=o.stroke,t.stroke())})})},u.plugins.borders=function(n,o){var e=null;n.onInit(function(){var o=n.world.objects.countries;e=t.mesh(n.world,o,function(n,t){return n.id!==t.id})}),n.onDraw(function(){n.withSavedContext(function(t){t.beginPath(),n.path.context(t)(e),t.strokeStyle=o.stroke||"gray",t.stroke()})})},u.plugins.earth=function(n){var n=n||{},t=n.topojson||{},o=n.oceans||{},e=n.land||{},i=n.borders||{};return function(n){u.plugins.topojson(n,t),u.plugins.oceans(n,o),u.plugins.land(n,e),u.plugins.borders(n,i)}},u});
|
!function(n,t){"function"==typeof define&&define.amd?define(["d3","topojson"],t):"object"==typeof exports?module.exports=t(require("d3"),require("topojson")):n.planetaryjs=t(n.d3,n.topojson,n)}(this,function(n,t,o){"use strict";var e=null;o&&(e=o.planetaryjs);var i=[],r=function(t,o,e){n.timer(function(){t.context.clearRect(0,0,o.width,o.height);for(var n=0;n<e.onDraw.length;n++)e.onDraw[n]()})},l=function(n,t){for(var o=0;o<i.length;o++)t.unshift(i[o]);0==t.length&&(s.plugins.earth&&n.loadPlugin(s.plugins.earth()),s.plugins.pings&&n.loadPlugin(s.plugins.pings()));for(var o=0;o<t.length;o++)t[o](n)},u=function(n,t,o){if(o.onInit.length){var e=0,i=function(n){var t=o.onInit[e];t.length?t(function(){e++,n()}):(t(),e++,setTimeout(n,0))},l=function(){e>=o.onInit.length?r(n,t,o):i(l)};i(l)}else r(n,t,o)},a=function(n,t,o,e){l(n,o),n.canvas=t,n.context=t.getContext("2d"),u(n,t,e)},s={plugins:{},noConflict:function(){return o.planetaryjs=e,s},loadPlugin:function(n){i.push(n)},planet:function(){var t=[],o={onInit:[],onDraw:[]},e={draw:function(n){a(e,n,t,o)},onInit:function(n){o.onInit.push(n)},onDraw:function(n){o.onDraw.push(n)},loadPlugin:function(n){t.push(n)},withSavedContext:function(n){if(!this.context)throw new Error("No canvas to fetch context for");this.context.save(),n(this.context),this.context.restore()}};return e.projection=n.geo.orthographic().clipAngle(90).precision(0),e.path=n.geo.path().projection(e.projection),e}};return s.plugins.topojson=function(t){return function(o){o.onInit(function(e){if(t.world)o.world=t.world,setTimeout(e,0);else{var i=t.file||"world-110m.json";n.json(i,function(n,t){if(n)throw new Error("Could not load JSON "+i);o.world=t,e()})}})}},s.plugins.oceans=function(n){return function(t){t.onDraw(function(){t.withSavedContext(function(o){o.beginPath(),t.path.context(o)({type:"Sphere"}),o.fillStyle=n.fill||"black",o.fill(),0!=n.stroke&&(o.strokeStyle=n.stroke,o.stroke())})})}},s.plugins.land=function(n){return function(o){var e=null;o.onInit(function(){e=t.feature(o.world,o.world.objects.land)}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(e),0!=n.fill&&(t.fillStyle=n.fill||"white",t.fill()),n.stroke&&(t.strokeStyle=n.stroke,t.stroke())})})}},s.plugins.borders=function(n){return function(o){var e=null;o.onInit(function(){var n=o.world.objects.countries;e=t.mesh(o.world,n,function(n,t){return n.id!==t.id})}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(e),t.strokeStyle=n.stroke||"gray",t.stroke()})})}},s.plugins.earth=function(n){var n=n||{},t=n.topojson||{},o=n.oceans||{},e=n.land||{},i=n.borders||{};return function(n){s.plugins.topojson(t)(n),s.plugins.oceans(o)(n),s.plugins.land(e)(n),s.plugins.borders(i)(n)}},s.plugins.pings=function(){var t=[],o=function(n,o,e){var e=e||{};e.color=e.color||"white",e.ttl=e.ttl||2e3,e.size=e.size||500,t.push({lat:n,lng:o,time:new Date,options:e})},e=function(n,o,e){for(var r=[],l=0;l<t.length;l++){var u=t[l],a=e-u.time;a<=u.options.ttl&&(r.push(u),i(n,o,e,u))}t=r},i=function(t,o,e,i){var r=e-i.time,l=1-r/i.options.ttl,u=n.rgb(i.options.color);u="rgba("+u.r+","+u.g+","+u.b+","+l+")",o.strokeStyle=u;var a=n.geo.circle().origin([i.lng,i.lat]).angle(r/i.options.size)();o.beginPath(),t.path.context(o)(a),o.stroke()};return function(n){n.addPing=o,n.onDraw(function(){var t=new Date;n.withSavedContext(function(o){e(n,o,t)})})}},s});
|
||||||
39
src/body.js
39
src/body.js
@ -11,24 +11,28 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var startDraw = function(planet, canvas, localPlugins, hooks) {
|
var initPlugins = function(planet, localPlugins) {
|
||||||
|
// Add the global plugins to the beginning of the local ones
|
||||||
for (var i = 0; i < plugins.length; i++) {
|
for (var i = 0; i < plugins.length; i++) {
|
||||||
localPlugins.unshift(plugins[i]);
|
localPlugins.unshift(plugins[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localPlugins.length == 0 && planetaryjs.plugins.earth) {
|
// Load the default plugins if none have been loaded so far
|
||||||
planet.loadPlugin(planetaryjs.plugins.earth());
|
if (localPlugins.length == 0) {
|
||||||
|
if (planetaryjs.plugins.earth)
|
||||||
|
planet.loadPlugin(planetaryjs.plugins.earth());
|
||||||
|
if (planetaryjs.plugins.pings)
|
||||||
|
planet.loadPlugin(planetaryjs.plugins.pings());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < localPlugins.length; i++) {
|
for (var i = 0; i < localPlugins.length; i++) {
|
||||||
var plugin = localPlugins[i][0];
|
localPlugins[i](planet);
|
||||||
var config = localPlugins[i][1];
|
|
||||||
plugin(planet, config);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
planet.canvas = canvas;
|
var runOnInitHooks = function(planet, canvas, hooks) {
|
||||||
planet.context = canvas.getContext('2d');
|
// onInit hooks can be asynchronous if they take a parameter;
|
||||||
|
// iterate through them one at a time
|
||||||
if (hooks.onInit.length) {
|
if (hooks.onInit.length) {
|
||||||
var completed = 0;
|
var completed = 0;
|
||||||
var doNext = function(callback) {
|
var doNext = function(callback) {
|
||||||
@ -54,6 +58,15 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var startDraw = function(planet, canvas, localPlugins, hooks) {
|
||||||
|
initPlugins(planet, localPlugins);
|
||||||
|
|
||||||
|
planet.canvas = canvas;
|
||||||
|
planet.context = canvas.getContext('2d');
|
||||||
|
|
||||||
|
runOnInitHooks(planet, canvas, hooks);
|
||||||
|
};
|
||||||
|
|
||||||
var planetaryjs = {
|
var planetaryjs = {
|
||||||
plugins: {},
|
plugins: {},
|
||||||
|
|
||||||
@ -62,8 +75,8 @@
|
|||||||
return planetaryjs;
|
return planetaryjs;
|
||||||
},
|
},
|
||||||
|
|
||||||
loadPlugin: function(plugin, defaultOptions) {
|
loadPlugin: function(plugin) {
|
||||||
plugins.push([plugin, defaultOptions || {}]);
|
plugins.push(plugin);
|
||||||
},
|
},
|
||||||
|
|
||||||
planet: function() {
|
planet: function() {
|
||||||
@ -86,8 +99,8 @@
|
|||||||
hooks.onDraw.push(fn);
|
hooks.onDraw.push(fn);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadPlugin: function(plugin, defaultOptions) {
|
loadPlugin: function(plugin) {
|
||||||
localPlugins.push([plugin, defaultOptions || {}]);
|
localPlugins.push(plugin);
|
||||||
},
|
},
|
||||||
|
|
||||||
withSavedContext: function(fn) {
|
withSavedContext: function(fn) {
|
||||||
|
|||||||
235
src/plugins.js
235
src/plugins.js
@ -1,93 +1,150 @@
|
|||||||
planetaryjs.plugins.topojson = function(planet, config) {
|
planetaryjs.plugins.topojson = function(config) {
|
||||||
planet.onInit(function(done) {
|
return function(planet) {
|
||||||
if (config.world) {
|
planet.onInit(function(done) {
|
||||||
planet.world = config.world;
|
if (config.world) {
|
||||||
setTimeout(done, 0);
|
planet.world = config.world;
|
||||||
} else {
|
setTimeout(done, 0);
|
||||||
var file = config.file || 'world-110m.json'
|
} else {
|
||||||
d3.json(file, function(err, world) {
|
var file = config.file || 'world-110m.json'
|
||||||
if (err) {
|
d3.json(file, function(err, world) {
|
||||||
throw new Error("Could not load JSON " + file);
|
if (err) {
|
||||||
}
|
throw new Error("Could not load JSON " + file);
|
||||||
planet.world = world;
|
}
|
||||||
done();
|
planet.world = world;
|
||||||
});
|
done();
|
||||||
}
|
});
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
planetaryjs.plugins.oceans = function(planet, config) {
|
|
||||||
planet.onDraw(function() {
|
|
||||||
planet.withSavedContext(function(context) {
|
|
||||||
context.beginPath();
|
|
||||||
planet.path.context(context)({type: 'Sphere'});
|
|
||||||
|
|
||||||
context.fillStyle = config.fill || 'black';
|
|
||||||
context.fill();
|
|
||||||
|
|
||||||
if (config.stroke != false) {
|
|
||||||
context.strokeStyle = config.stroke;
|
|
||||||
context.stroke();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
planetaryjs.plugins.land = function(planet, config) {
|
planetaryjs.plugins.oceans = function(config) {
|
||||||
var land = null;
|
return function(planet) {
|
||||||
|
planet.onDraw(function() {
|
||||||
planet.onInit(function() {
|
planet.withSavedContext(function(context) {
|
||||||
land = topojson.feature(planet.world, planet.world.objects.land);
|
context.beginPath();
|
||||||
})
|
planet.path.context(context)({type: 'Sphere'});
|
||||||
|
|
||||||
planet.onDraw(function() {
|
context.fillStyle = config.fill || 'black';
|
||||||
planet.withSavedContext(function(context) {
|
context.fill();
|
||||||
context.beginPath();
|
|
||||||
planet.path.context(context)(land);
|
if (config.stroke != false) {
|
||||||
|
context.strokeStyle = config.stroke;
|
||||||
if (config.fill != false) {
|
context.stroke();
|
||||||
context.fillStyle = config.fill || 'white';
|
}
|
||||||
context.fill();
|
});
|
||||||
}
|
});
|
||||||
|
};
|
||||||
if (config.stroke) {
|
};
|
||||||
context.strokeStyle = config.stroke;
|
|
||||||
context.stroke();
|
planetaryjs.plugins.land = function(config) {
|
||||||
}
|
return function(planet) {
|
||||||
});
|
var land = null;
|
||||||
});
|
|
||||||
};
|
planet.onInit(function() {
|
||||||
|
land = topojson.feature(planet.world, planet.world.objects.land);
|
||||||
planetaryjs.plugins.borders = function(planet, config) {
|
})
|
||||||
var borders = null;
|
|
||||||
planet.onInit(function() {
|
planet.onDraw(function() {
|
||||||
var countries = planet.world.objects.countries;
|
planet.withSavedContext(function(context) {
|
||||||
borders = topojson.mesh(planet.world, countries, function(a, b) {
|
context.beginPath();
|
||||||
return a.id !== b.id;
|
planet.path.context(context)(land);
|
||||||
});
|
|
||||||
});
|
if (config.fill != false) {
|
||||||
|
context.fillStyle = config.fill || 'white';
|
||||||
planet.onDraw(function() {
|
context.fill();
|
||||||
planet.withSavedContext(function(context) {
|
}
|
||||||
context.beginPath();
|
|
||||||
planet.path.context(context)(borders);
|
if (config.stroke) {
|
||||||
context.strokeStyle = config.stroke || 'gray';
|
context.strokeStyle = config.stroke;
|
||||||
context.stroke();
|
context.stroke();
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
};
|
});
|
||||||
|
};
|
||||||
planetaryjs.plugins.earth = function(options) {
|
};
|
||||||
var options = options || {};
|
|
||||||
var topojsonOptions = options.topojson || {};
|
planetaryjs.plugins.borders = function(config) {
|
||||||
var oceanOptions = options.oceans || {};
|
return function(planet) {
|
||||||
var landOptions = options.land || {};
|
var borders = null;
|
||||||
var bordersOptions = options.borders || {};
|
planet.onInit(function() {
|
||||||
|
var countries = planet.world.objects.countries;
|
||||||
return function(planet, options) {
|
borders = topojson.mesh(planet.world, countries, function(a, b) {
|
||||||
planetaryjs.plugins.topojson(planet, topojsonOptions);
|
return a.id !== b.id;
|
||||||
planetaryjs.plugins.oceans(planet, oceanOptions);
|
});
|
||||||
planetaryjs.plugins.land(planet, landOptions);
|
});
|
||||||
planetaryjs.plugins.borders(planet, bordersOptions);
|
|
||||||
|
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.size = options.size || 500;
|
||||||
|
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, ping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pings = newPings;
|
||||||
|
};
|
||||||
|
|
||||||
|
var drawPing = function(planet, context, now, ping) {
|
||||||
|
var dT = now - ping.time;
|
||||||
|
var alpha = 1 - (dT / 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(dT / ping.options.size)();
|
||||||
|
context.beginPath();
|
||||||
|
planet.path.context(context)(circle);
|
||||||
|
context.stroke();
|
||||||
|
};
|
||||||
|
|
||||||
|
return function (planet) {
|
||||||
|
planet.addPing = addPing;
|
||||||
|
|
||||||
|
planet.onDraw(function() {
|
||||||
|
var now = new Date();
|
||||||
|
planet.withSavedContext(function(context) {
|
||||||
|
drawPings(planet, context, now);
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user