Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06002ea0c8 |
62
CHANGELOG.md
62
CHANGELOG.md
@ -1,65 +1,3 @@
|
|||||||
v1.1.2 (2015/11/22)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* Update LICENSE and copyright notices
|
|
||||||
|
|
||||||
v1.1.1 (2014/05/18)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* Set `planetaryjs` on root when using AMD
|
|
||||||
|
|
||||||
v1.1.0 (2014/02/03)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
**Core**
|
|
||||||
|
|
||||||
* Add `stop` method
|
|
||||||
* Add `onStop` hooks
|
|
||||||
|
|
||||||
v1.0.3 (2014/01/23)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* Don't disable adaptive resampling on the projection
|
|
||||||
|
|
||||||
v1.0.2 (2014/01/16)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* Update version dependencies for D3 and TopoJSON
|
|
||||||
|
|
||||||
v1.0.1 (2013/01/02)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* Add D3 and TopoJSON as dependencies in `package.json`
|
|
||||||
|
|
||||||
v1.0.0 (2013/12/31)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
First stable release
|
|
||||||
|
|
||||||
v1.0.0-rc.2 (2013/12/26)
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
* Fix load order of global plugins
|
|
||||||
* Expose planet instance as `this` in event callbacks
|
|
||||||
|
|
||||||
v1.0.0-rc.1 (2013/12/24)
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
* `zoom` plugin's `initialScale` can be set to `0`
|
|
||||||
|
|
||||||
v0.3.0
|
|
||||||
------
|
|
||||||
|
|
||||||
* Reverse the order of `lat` and `lng` parameters of the `add` method of the `pings` plugin
|
|
||||||
|
|
||||||
v0.2.2
|
|
||||||
------
|
|
||||||
|
|
||||||
* Add `afterZoom` and `afterDrag` hooks to the `zoom` and `drag` plugins
|
|
||||||
|
|
||||||
v0.2.1
|
|
||||||
------
|
|
||||||
|
|
||||||
* Implement the `drag` and `zoom` plugins
|
* Implement the `drag` and `zoom` plugins
|
||||||
|
|
||||||
v0.2.0
|
v0.2.0
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2013 Michelle Tilley
|
Copyright (c) 2013 Brandon Tilley
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
|
|||||||
@ -15,11 +15,6 @@ Requirements
|
|||||||
* [D3](http://d3js.org/) version 3
|
* [D3](http://d3js.org/) version 3
|
||||||
* [TopoJSON](https://github.com/mbostock/topojson) version 1
|
* [TopoJSON](https://github.com/mbostock/topojson) version 1
|
||||||
|
|
||||||
Download
|
|
||||||
--------
|
|
||||||
|
|
||||||
Download Planetary.js from the [Planetary.js web site](http://planetaryjs.com/download/).
|
|
||||||
|
|
||||||
Quick Start
|
Quick Start
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|||||||
12
bower.json
12
bower.json
@ -1,12 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "planetary.js",
|
"name": "planetary.js",
|
||||||
"version": "1.1.2",
|
"version": "0.2.1",
|
||||||
"main": "dist/planetaryjs.min.js",
|
"main": "dist/planetaryjs.min.js",
|
||||||
"description": "Awesome interactive globes for the web",
|
"description": "Awesome interactive globes for the web",
|
||||||
"homepage": "http://planetaryjs.com",
|
"homepage": "http://planetaryjs.com",
|
||||||
"authors": [
|
"authors": [ "Brandon Tilley <brandon@brandontilley.com>" ],
|
||||||
"Michelle Tilley <michelle@michelletilley.net>"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"ignore": [
|
"ignore": [
|
||||||
".git",
|
".git",
|
||||||
@ -23,10 +21,8 @@
|
|||||||
"topojson": "1.x"
|
"topojson": "1.x"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"globe",
|
"globe", "globes",
|
||||||
"globes",
|
"planet", "planets",
|
||||||
"planet",
|
|
||||||
"planets",
|
|
||||||
"d3",
|
"d3",
|
||||||
"topojson"
|
"topojson"
|
||||||
]
|
]
|
||||||
|
|||||||
50
dist/planetaryjs-noplugins.js
vendored
50
dist/planetaryjs-noplugins.js
vendored
@ -1,14 +1,12 @@
|
|||||||
/*! Planetary.js v1.1.3
|
/*! Planetary.js v0.2.1
|
||||||
* Copyright (c) 2013 Michelle Tilley
|
* Copyright (c) 2013 Brandon Tilley
|
||||||
*
|
*
|
||||||
* Released under the MIT license
|
* Released under the MIT license
|
||||||
* Date: 2018-10-30T18:49:58.804Z
|
* Date: 2013-12-22T22:19:14.765Z
|
||||||
*/
|
*/
|
||||||
(function (root, factory) {
|
(function (root, factory) {
|
||||||
if (typeof define === 'function' && define.amd) {
|
if (typeof define === 'function' && define.amd) {
|
||||||
define(['d3', 'topojson'], function(d3, topojson) {
|
define(['d3', 'topojson'], factory);
|
||||||
return (root.planetaryjs = factory(d3, topojson, root));
|
|
||||||
});
|
|
||||||
} else if (typeof exports === 'object') {
|
} else if (typeof exports === 'object') {
|
||||||
module.exports = factory(require('d3'), require('topojson'));
|
module.exports = factory(require('d3'), require('topojson'));
|
||||||
} else {
|
} else {
|
||||||
@ -23,11 +21,7 @@
|
|||||||
|
|
||||||
var doDrawLoop = function(planet, canvas, hooks) {
|
var doDrawLoop = function(planet, canvas, hooks) {
|
||||||
d3.timer(function() {
|
d3.timer(function() {
|
||||||
if (planet.stopped) {
|
planet.context.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
planet.context.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
for (var i = 0; i < hooks.onDraw.length; i++) {
|
for (var i = 0; i < hooks.onDraw.length; i++) {
|
||||||
hooks.onDraw[i]();
|
hooks.onDraw[i]();
|
||||||
}
|
}
|
||||||
@ -36,19 +30,19 @@
|
|||||||
|
|
||||||
var initPlugins = function(planet, localPlugins) {
|
var initPlugins = function(planet, localPlugins) {
|
||||||
// Add the global plugins to the beginning of the local ones
|
// Add the global plugins to the beginning of the local ones
|
||||||
for (var i = plugins.length - 1; i >= 0; i--) {
|
for (var i = 0; i < plugins.length; i++) {
|
||||||
localPlugins.unshift(plugins[i]);
|
localPlugins.unshift(plugins[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the default plugins if none have been loaded so far
|
// Load the default plugins if none have been loaded so far
|
||||||
if (localPlugins.length === 0) {
|
if (localPlugins.length == 0) {
|
||||||
if (planetaryjs.plugins.earth)
|
if (planetaryjs.plugins.earth)
|
||||||
planet.loadPlugin(planetaryjs.plugins.earth());
|
planet.loadPlugin(planetaryjs.plugins.earth());
|
||||||
if (planetaryjs.plugins.pings)
|
if (planetaryjs.plugins.pings)
|
||||||
planet.loadPlugin(planetaryjs.plugins.pings());
|
planet.loadPlugin(planetaryjs.plugins.pings());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < localPlugins.length; i++) {
|
for (var i = 0; i < localPlugins.length; i++) {
|
||||||
localPlugins[i](planet);
|
localPlugins[i](planet);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -74,7 +68,7 @@
|
|||||||
var check = function() {
|
var check = function() {
|
||||||
if (completed >= hooks.onInit.length) doDrawLoop(planet, canvas, hooks);
|
if (completed >= hooks.onInit.length) doDrawLoop(planet, canvas, hooks);
|
||||||
else doNext(check);
|
else doNext(check);
|
||||||
};
|
}
|
||||||
doNext(check);
|
doNext(check);
|
||||||
} else {
|
} else {
|
||||||
doDrawLoop(planet, canvas, hooks);
|
doDrawLoop(planet, canvas, hooks);
|
||||||
@ -82,14 +76,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
var startDraw = function(planet, canvas, localPlugins, hooks) {
|
var startDraw = function(planet, canvas, localPlugins, hooks) {
|
||||||
|
initPlugins(planet, localPlugins);
|
||||||
|
|
||||||
planet.canvas = canvas;
|
planet.canvas = canvas;
|
||||||
planet.context = canvas.getContext('2d');
|
planet.context = canvas.getContext('2d');
|
||||||
|
|
||||||
if (planet.stopped !== true) {
|
|
||||||
initPlugins(planet, localPlugins);
|
|
||||||
}
|
|
||||||
|
|
||||||
planet.stopped = false;
|
|
||||||
runOnInitHooks(planet, canvas, hooks);
|
runOnInitHooks(planet, canvas, hooks);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -109,8 +100,7 @@
|
|||||||
var localPlugins = [];
|
var localPlugins = [];
|
||||||
var hooks = {
|
var hooks = {
|
||||||
onInit: [],
|
onInit: [],
|
||||||
onDraw: [],
|
onDraw: []
|
||||||
onStop: []
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var planet = {
|
var planet = {
|
||||||
@ -128,24 +118,13 @@
|
|||||||
hooks.onDraw.push(fn);
|
hooks.onDraw.push(fn);
|
||||||
},
|
},
|
||||||
|
|
||||||
onStop: function(fn) {
|
|
||||||
hooks.onStop.push(fn);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadPlugin: function(plugin) {
|
loadPlugin: function(plugin) {
|
||||||
localPlugins.push(plugin);
|
localPlugins.push(plugin);
|
||||||
},
|
},
|
||||||
|
|
||||||
stop: function() {
|
|
||||||
planet.stopped = true;
|
|
||||||
for (var i = 0; i < hooks.onStop.length; i++) {
|
|
||||||
hooks.onStop[i](planet);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
withSavedContext: function(fn) {
|
withSavedContext: function(fn) {
|
||||||
if (!this.context) {
|
if (!this.context) {
|
||||||
throw new Error("No canvas to fetch context for");
|
throw new Error("No canvas to fetch context for")
|
||||||
}
|
}
|
||||||
|
|
||||||
this.context.save();
|
this.context.save();
|
||||||
@ -155,7 +134,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
planet.projection = d3.geo.orthographic()
|
planet.projection = d3.geo.orthographic()
|
||||||
.clipAngle(90);
|
.clipAngle(90)
|
||||||
|
.precision(0);
|
||||||
planet.path = d3.geo.path().projection(planet.projection);
|
planet.path = d3.geo.path().projection(planet.projection);
|
||||||
|
|
||||||
return planet;
|
return planet;
|
||||||
|
|||||||
4
dist/planetaryjs-noplugins.min.js
vendored
4
dist/planetaryjs-noplugins.min.js
vendored
@ -1,2 +1,2 @@
|
|||||||
/*! Planetary.js 1.1.3 | (c) 2013 Michelle Tilley | Released under MIT License */
|
/*! Planetary.js 0.2.1 | (c) 2013 Brandon Tilley | Released under MIT License */
|
||||||
!function(n,t){"function"==typeof define&&define.amd?define(["d3","topojson"],function(o,e){return n.planetaryjs=t(o,e,n)}):"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(){if(t.stopped)return!0;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=i.length-1;o>=0;o--)t.unshift(i[o]);for(0===t.length&&(s.plugins.earth&&n.loadPlugin(s.plugins.earth()),s.plugins.pings&&n.loadPlugin(s.plugins.pings())),o=0;o<t.length;o++)t[o](n)},p=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)},c=function(n,t,o,e){n.canvas=t,n.context=t.getContext("2d"),n.stopped!==!0&&u(n,o),n.stopped=!1,p(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:[],onStop:[]},e={plugins:{},draw:function(n){c(e,n,t,o)},onInit:function(n){o.onInit.push(n)},onDraw:function(n){o.onDraw.push(n)},onStop:function(n){o.onStop.push(n)},loadPlugin:function(n){t.push(n)},stop:function(){e.stopped=!0;for(var n=0;n<o.onStop.length;n++)o.onStop[n](e)},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),e.path=n.geo.path().projection(e.projection),e}};return s});
|
!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={plugins:{},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});
|
||||||
99
dist/planetaryjs.js
vendored
99
dist/planetaryjs.js
vendored
@ -1,14 +1,12 @@
|
|||||||
/*! Planetary.js v1.1.3
|
/*! Planetary.js v0.2.1
|
||||||
* Copyright (c) 2013 Michelle Tilley
|
* Copyright (c) 2013 Brandon Tilley
|
||||||
*
|
*
|
||||||
* Released under the MIT license
|
* Released under the MIT license
|
||||||
* Date: 2018-10-30T18:49:58.667Z
|
* Date: 2013-12-22T22:19:14.641Z
|
||||||
*/
|
*/
|
||||||
(function (root, factory) {
|
(function (root, factory) {
|
||||||
if (typeof define === 'function' && define.amd) {
|
if (typeof define === 'function' && define.amd) {
|
||||||
define(['d3', 'topojson'], function(d3, topojson) {
|
define(['d3', 'topojson'], factory);
|
||||||
return (root.planetaryjs = factory(d3, topojson, root));
|
|
||||||
});
|
|
||||||
} else if (typeof exports === 'object') {
|
} else if (typeof exports === 'object') {
|
||||||
module.exports = factory(require('d3'), require('topojson'));
|
module.exports = factory(require('d3'), require('topojson'));
|
||||||
} else {
|
} else {
|
||||||
@ -23,11 +21,7 @@
|
|||||||
|
|
||||||
var doDrawLoop = function(planet, canvas, hooks) {
|
var doDrawLoop = function(planet, canvas, hooks) {
|
||||||
d3.timer(function() {
|
d3.timer(function() {
|
||||||
if (planet.stopped) {
|
planet.context.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
planet.context.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
for (var i = 0; i < hooks.onDraw.length; i++) {
|
for (var i = 0; i < hooks.onDraw.length; i++) {
|
||||||
hooks.onDraw[i]();
|
hooks.onDraw[i]();
|
||||||
}
|
}
|
||||||
@ -36,19 +30,19 @@
|
|||||||
|
|
||||||
var initPlugins = function(planet, localPlugins) {
|
var initPlugins = function(planet, localPlugins) {
|
||||||
// Add the global plugins to the beginning of the local ones
|
// Add the global plugins to the beginning of the local ones
|
||||||
for (var i = plugins.length - 1; i >= 0; i--) {
|
for (var i = 0; i < plugins.length; i++) {
|
||||||
localPlugins.unshift(plugins[i]);
|
localPlugins.unshift(plugins[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the default plugins if none have been loaded so far
|
// Load the default plugins if none have been loaded so far
|
||||||
if (localPlugins.length === 0) {
|
if (localPlugins.length == 0) {
|
||||||
if (planetaryjs.plugins.earth)
|
if (planetaryjs.plugins.earth)
|
||||||
planet.loadPlugin(planetaryjs.plugins.earth());
|
planet.loadPlugin(planetaryjs.plugins.earth());
|
||||||
if (planetaryjs.plugins.pings)
|
if (planetaryjs.plugins.pings)
|
||||||
planet.loadPlugin(planetaryjs.plugins.pings());
|
planet.loadPlugin(planetaryjs.plugins.pings());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < localPlugins.length; i++) {
|
for (var i = 0; i < localPlugins.length; i++) {
|
||||||
localPlugins[i](planet);
|
localPlugins[i](planet);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -74,7 +68,7 @@
|
|||||||
var check = function() {
|
var check = function() {
|
||||||
if (completed >= hooks.onInit.length) doDrawLoop(planet, canvas, hooks);
|
if (completed >= hooks.onInit.length) doDrawLoop(planet, canvas, hooks);
|
||||||
else doNext(check);
|
else doNext(check);
|
||||||
};
|
}
|
||||||
doNext(check);
|
doNext(check);
|
||||||
} else {
|
} else {
|
||||||
doDrawLoop(planet, canvas, hooks);
|
doDrawLoop(planet, canvas, hooks);
|
||||||
@ -82,14 +76,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
var startDraw = function(planet, canvas, localPlugins, hooks) {
|
var startDraw = function(planet, canvas, localPlugins, hooks) {
|
||||||
|
initPlugins(planet, localPlugins);
|
||||||
|
|
||||||
planet.canvas = canvas;
|
planet.canvas = canvas;
|
||||||
planet.context = canvas.getContext('2d');
|
planet.context = canvas.getContext('2d');
|
||||||
|
|
||||||
if (planet.stopped !== true) {
|
|
||||||
initPlugins(planet, localPlugins);
|
|
||||||
}
|
|
||||||
|
|
||||||
planet.stopped = false;
|
|
||||||
runOnInitHooks(planet, canvas, hooks);
|
runOnInitHooks(planet, canvas, hooks);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -109,8 +100,7 @@
|
|||||||
var localPlugins = [];
|
var localPlugins = [];
|
||||||
var hooks = {
|
var hooks = {
|
||||||
onInit: [],
|
onInit: [],
|
||||||
onDraw: [],
|
onDraw: []
|
||||||
onStop: []
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var planet = {
|
var planet = {
|
||||||
@ -128,24 +118,13 @@
|
|||||||
hooks.onDraw.push(fn);
|
hooks.onDraw.push(fn);
|
||||||
},
|
},
|
||||||
|
|
||||||
onStop: function(fn) {
|
|
||||||
hooks.onStop.push(fn);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadPlugin: function(plugin) {
|
loadPlugin: function(plugin) {
|
||||||
localPlugins.push(plugin);
|
localPlugins.push(plugin);
|
||||||
},
|
},
|
||||||
|
|
||||||
stop: function() {
|
|
||||||
planet.stopped = true;
|
|
||||||
for (var i = 0; i < hooks.onStop.length; i++) {
|
|
||||||
hooks.onStop[i](planet);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
withSavedContext: function(fn) {
|
withSavedContext: function(fn) {
|
||||||
if (!this.context) {
|
if (!this.context) {
|
||||||
throw new Error("No canvas to fetch context for");
|
throw new Error("No canvas to fetch context for")
|
||||||
}
|
}
|
||||||
|
|
||||||
this.context.save();
|
this.context.save();
|
||||||
@ -155,7 +134,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
planet.projection = d3.geo.orthographic()
|
planet.projection = d3.geo.orthographic()
|
||||||
.clipAngle(90);
|
.clipAngle(90)
|
||||||
|
.precision(0);
|
||||||
planet.path = d3.geo.path().projection(planet.projection);
|
planet.path = d3.geo.path().projection(planet.projection);
|
||||||
|
|
||||||
return planet;
|
return planet;
|
||||||
@ -171,7 +151,7 @@
|
|||||||
planet.plugins.topojson.world = config.world;
|
planet.plugins.topojson.world = config.world;
|
||||||
setTimeout(done, 0);
|
setTimeout(done, 0);
|
||||||
} else {
|
} else {
|
||||||
var file = config.file || 'world-110m.json';
|
var file = config.file || 'world-110m.json'
|
||||||
d3.json(file, function(err, world) {
|
d3.json(file, function(err, world) {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw new Error("Could not load JSON " + file);
|
throw new Error("Could not load JSON " + file);
|
||||||
@ -205,14 +185,14 @@
|
|||||||
planet.onInit(function() {
|
planet.onInit(function() {
|
||||||
var world = planet.plugins.topojson.world;
|
var world = planet.plugins.topojson.world;
|
||||||
land = topojson.feature(world, world.objects.land);
|
land = topojson.feature(world, world.objects.land);
|
||||||
});
|
})
|
||||||
|
|
||||||
planet.onDraw(function() {
|
planet.onDraw(function() {
|
||||||
planet.withSavedContext(function(context) {
|
planet.withSavedContext(function(context) {
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
planet.path.context(context)(land);
|
planet.path.context(context)(land);
|
||||||
|
|
||||||
if (config.fill !== false) {
|
if (config.fill != false) {
|
||||||
context.fillStyle = config.fill || 'white';
|
context.fillStyle = config.fill || 'white';
|
||||||
context.fill();
|
context.fill();
|
||||||
}
|
}
|
||||||
@ -262,7 +242,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
planetaryjs.plugins.earth = function(config) {
|
planetaryjs.plugins.earth = function(config) {
|
||||||
config = config || {};
|
var config = config || {};
|
||||||
var topojsonOptions = config.topojson || {};
|
var topojsonOptions = config.topojson || {};
|
||||||
var oceanOptions = config.oceans || {};
|
var oceanOptions = config.oceans || {};
|
||||||
var landOptions = config.land || {};
|
var landOptions = config.land || {};
|
||||||
@ -278,22 +258,13 @@
|
|||||||
|
|
||||||
planetaryjs.plugins.pings = function(config) {
|
planetaryjs.plugins.pings = function(config) {
|
||||||
var pings = [];
|
var pings = [];
|
||||||
config = config || {};
|
|
||||||
|
|
||||||
var addPing = function(lng, lat, options) {
|
var addPing = function(lat, lng, options) {
|
||||||
options = options || {};
|
var options = options || {};
|
||||||
options.color = options.color || config.color || 'white';
|
options.color = options.color || config.color || 'white';
|
||||||
options.angle = options.angle || config.angle || 5;
|
|
||||||
options.ttl = options.ttl || config.ttl || 2000;
|
options.ttl = options.ttl || config.ttl || 2000;
|
||||||
var ping = { time: new Date(), options: options };
|
options.angle = options.angle || config.angle || 5;
|
||||||
if (config.latitudeFirst) {
|
pings.push({ lat: lat, lng: lng, time: new Date(), options: options });
|
||||||
ping.lat = lng;
|
|
||||||
ping.lng = lat;
|
|
||||||
} else {
|
|
||||||
ping.lng = lng;
|
|
||||||
ping.lat = lat;
|
|
||||||
}
|
|
||||||
pings.push(ping);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var drawPings = function(planet, context, now) {
|
var drawPings = function(planet, context, now) {
|
||||||
@ -336,12 +307,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
planetaryjs.plugins.zoom = function (options) {
|
planetaryjs.plugins.zoom = function (options) {
|
||||||
options = options || {};
|
var options = options || {};
|
||||||
var noop = function() {};
|
var noop = function() {};
|
||||||
var onZoomStart = options.onZoomStart || noop;
|
var onZoomStart = options.onZoomStart || noop;
|
||||||
var onZoomEnd = options.onZoomEnd || noop;
|
var onZoomEnd = options.onZoomEnd || noop;
|
||||||
var onZoom = options.onZoom || noop;
|
var onZoom = options.onZoom || noop;
|
||||||
var afterZoom = options.afterZoom || noop;
|
|
||||||
var startScale = options.initialScale;
|
var startScale = options.initialScale;
|
||||||
var scaleExtent = options.scaleExtent || [50, 2000];
|
var scaleExtent = options.scaleExtent || [50, 2000];
|
||||||
|
|
||||||
@ -349,20 +319,17 @@
|
|||||||
planet.onInit(function() {
|
planet.onInit(function() {
|
||||||
var zoom = d3.behavior.zoom()
|
var zoom = d3.behavior.zoom()
|
||||||
.scaleExtent(scaleExtent);
|
.scaleExtent(scaleExtent);
|
||||||
|
if (startScale) {
|
||||||
if (startScale !== null && startScale !== undefined) {
|
|
||||||
zoom.scale(startScale);
|
zoom.scale(startScale);
|
||||||
} else {
|
} else {
|
||||||
zoom.scale(planet.projection.scale());
|
zoom.scale(planet.projection.scale());
|
||||||
}
|
}
|
||||||
|
|
||||||
zoom
|
zoom
|
||||||
.on('zoomstart', onZoomStart.bind(planet))
|
.on('zoomstart', onZoomStart)
|
||||||
.on('zoomend', onZoomEnd.bind(planet))
|
.on('zoomend', onZoomEnd)
|
||||||
.on('zoom', function() {
|
.on('zoom', function() {
|
||||||
onZoom.call(planet);
|
onZoom();
|
||||||
planet.projection.scale(d3.event.scale);
|
planet.projection.scale(d3.event.scale);
|
||||||
afterZoom.call(planet);
|
|
||||||
});
|
});
|
||||||
d3.select(planet.canvas).call(zoom);
|
d3.select(planet.canvas).call(zoom);
|
||||||
});
|
});
|
||||||
@ -370,20 +337,19 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
planetaryjs.plugins.drag = function(options) {
|
planetaryjs.plugins.drag = function(options) {
|
||||||
options = options || {};
|
var options = options || {};
|
||||||
var noop = function() {};
|
var noop = function() {};
|
||||||
var onDragStart = options.onDragStart || noop;
|
var onDragStart = options.onDragStart || noop;
|
||||||
var onDragEnd = options.onDragEnd || noop;
|
var onDragEnd = options.onDragEnd || noop;
|
||||||
var onDrag = options.onDrag || noop;
|
var onDrag = options.onDrag || noop;
|
||||||
var afterDrag = options.afterDrag || noop;
|
|
||||||
|
|
||||||
return function(planet) {
|
return function(planet) {
|
||||||
planet.onInit(function() {
|
planet.onInit(function() {
|
||||||
var drag = d3.behavior.drag()
|
var drag = d3.behavior.drag()
|
||||||
.on('dragstart', onDragStart.bind(planet))
|
.on('dragstart', onDragStart)
|
||||||
.on('dragend', onDragEnd.bind(planet))
|
.on('dragend', onDragEnd)
|
||||||
.on('drag', function() {
|
.on('drag', function() {
|
||||||
onDrag.call(planet);
|
onDrag();
|
||||||
var dx = d3.event.dx;
|
var dx = d3.event.dx;
|
||||||
var dy = d3.event.dy;
|
var dy = d3.event.dy;
|
||||||
var rotation = planet.projection.rotate();
|
var rotation = planet.projection.rotate();
|
||||||
@ -399,7 +365,6 @@
|
|||||||
if (rotation[1] < -90) rotation[1] = -90;
|
if (rotation[1] < -90) rotation[1] = -90;
|
||||||
if (rotation[0] >= 180) rotation[0] -= 360;
|
if (rotation[0] >= 180) rotation[0] -= 360;
|
||||||
planet.projection.rotate(rotation);
|
planet.projection.rotate(rotation);
|
||||||
afterDrag.call(planet);
|
|
||||||
});
|
});
|
||||||
d3.select(planet.canvas).call(drag);
|
d3.select(planet.canvas).call(drag);
|
||||||
});
|
});
|
||||||
|
|||||||
4
dist/planetaryjs.min.js
vendored
4
dist/planetaryjs.min.js
vendored
@ -1,2 +1,2 @@
|
|||||||
/*! Planetary.js 1.1.3 | (c) 2013 Michelle Tilley | Released under MIT License */
|
/*! Planetary.js 0.2.1 | (c) 2013 Brandon Tilley | Released under MIT License */
|
||||||
!function(n,t){"function"==typeof define&&define.amd?define(["d3","topojson"],function(o,e){return n.planetaryjs=t(o,e,n)}):"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(){if(t.stopped)return!0;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=i.length-1;o>=0;o--)t.unshift(i[o]);for(0===t.length&&(c.plugins.earth&&n.loadPlugin(c.plugins.earth()),c.plugins.pings&&n.loadPlugin(c.plugins.pings())),o=0;o<t.length;o++)t[o](n)},a=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)},u=function(n,t,o,e){n.canvas=t,n.context=t.getContext("2d"),n.stopped!==!0&&l(n,o),n.stopped=!1,a(n,t,e)},c={plugins:{},noConflict:function(){return o.planetaryjs=e,c},loadPlugin:function(n){i.push(n)},planet:function(){var t=[],o={onInit:[],onDraw:[],onStop:[]},e={plugins:{},draw:function(n){u(e,n,t,o)},onInit:function(n){o.onInit.push(n)},onDraw:function(n){o.onDraw.push(n)},onStop:function(n){o.onStop.push(n)},loadPlugin:function(n){t.push(n)},stop:function(){e.stopped=!0;for(var n=0;n<o.onStop.length;n++)o.onStop[n](e)},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),e.path=n.geo.path().projection(e.projection),e}};return c.plugins.topojson=function(t){return function(o){o.plugins.topojson={},o.onInit(function(e){if(t.world)o.plugins.topojson.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.plugins.topojson.world=t,e()})}})}},c.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()})})}},c.plugins.land=function(n){return function(o){var e=null;o.onInit(function(){var n=o.plugins.topojson.world;e=t.feature(n,n.objects.land)}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(e),n.fill!==!1&&(t.fillStyle=n.fill||"white",t.fill()),n.stroke&&(n.lineWidth&&(t.lineWidth=n.lineWidth),t.strokeStyle=n.stroke,t.stroke())})})}},c.plugins.borders=function(n){return function(o){var e=null,i={internal:function(n,t){return n.id!==t.id},external:function(n,t){return n.id===t.id},both:function(){return!0}};o.onInit(function(){var r=o.plugins.topojson.world,l=r.objects.countries,a=n.type||"internal";e=t.mesh(r,l,i[a])}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(e),t.strokeStyle=n.stroke||"gray",n.lineWidth&&(t.lineWidth=n.lineWidth),t.stroke()})})}},c.plugins.earth=function(n){n=n||{};var t=n.topojson||{},o=n.oceans||{},e=n.land||{},i=n.borders||{};return function(n){c.plugins.topojson(t)(n),c.plugins.oceans(o)(n),c.plugins.land(e)(n),c.plugins.borders(i)(n)}},c.plugins.pings=function(t){var o=[];t=t||{};var e=function(n,e,i){i=i||{},i.color=i.color||t.color||"white",i.angle=i.angle||t.angle||5,i.ttl=i.ttl||t.ttl||2e3;var r={time:new Date,options:i};t.latitudeFirst?(r.lat=n,r.lng=e):(r.lng=n,r.lat=e),o.push(r)},i=function(n,t,e){for(var i=[],l=0;l<o.length;l++){var a=o[l],u=e-a.time;u<a.options.ttl&&(i.push(a),r(n,t,e,u,a))}o=i},r=function(t,o,e,i,r){var l=1-i/r.options.ttl,a=n.rgb(r.options.color);a="rgba("+a.r+","+a.g+","+a.b+","+l+")",o.strokeStyle=a;var u=n.geo.circle().origin([r.lng,r.lat]).angle(i/r.options.ttl*r.options.angle)();o.beginPath(),t.path.context(o)(u),o.stroke()};return function(n){n.plugins.pings={add:e},n.onDraw(function(){var t=new Date;n.withSavedContext(function(o){i(n,o,t)})})}},c.plugins.zoom=function(t){t=t||{};var o=function(){},e=t.onZoomStart||o,i=t.onZoomEnd||o,r=t.onZoom||o,l=t.afterZoom||o,a=t.initialScale,u=t.scaleExtent||[50,2e3];return function(t){t.onInit(function(){var o=n.behavior.zoom().scaleExtent(u);null!==a&&void 0!==a?o.scale(a):o.scale(t.projection.scale()),o.on("zoomstart",e.bind(t)).on("zoomend",i.bind(t)).on("zoom",function(){r.call(t),t.projection.scale(n.event.scale),l.call(t)}),n.select(t.canvas).call(o)})}},c.plugins.drag=function(t){t=t||{};var o=function(){},e=t.onDragStart||o,i=t.onDragEnd||o,r=t.onDrag||o,l=t.afterDrag||o;return function(t){t.onInit(function(){var o=n.behavior.drag().on("dragstart",e.bind(t)).on("dragend",i.bind(t)).on("drag",function(){r.call(t);var o=n.event.dx,e=n.event.dy,i=t.projection.rotate(),a=t.projection.scale(),u=n.scale.linear().domain([-1*a,a]).range([-90,90]),c=u(o),s=u(e);i[0]+=c,i[1]-=s,i[1]>90&&(i[1]=90),i[1]<-90&&(i[1]=-90),i[0]>=180&&(i[0]-=360),t.projection.rotate(i),l.call(t)});n.select(t.canvas).call(o)})}},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 i=null;o&&(i=o.planetaryjs);var e=[],r=function(t,o,i){n.timer(function(){t.context.clearRect(0,0,o.width,o.height);for(var n=0;n<i.onDraw.length;n++)i.onDraw[n]()})},l=function(n,t){for(var o=0;o<e.length;o++)t.unshift(e[o]);0==t.length&&(c.plugins.earth&&n.loadPlugin(c.plugins.earth()),c.plugins.pings&&n.loadPlugin(c.plugins.pings()));for(var o=0;o<t.length;o++)t[o](n)},a=function(n,t,o){if(o.onInit.length){var i=0,e=function(n){var t=o.onInit[i];t.length?t(function(){i++,n()}):(t(),i++,setTimeout(n,0))},l=function(){i>=o.onInit.length?r(n,t,o):e(l)};e(l)}else r(n,t,o)},u=function(n,t,o,i){l(n,o),n.canvas=t,n.context=t.getContext("2d"),a(n,t,i)},c={plugins:{},noConflict:function(){return o.planetaryjs=i,c},loadPlugin:function(n){e.push(n)},planet:function(){var t=[],o={onInit:[],onDraw:[]},i={plugins:{},draw:function(n){u(i,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 i.projection=n.geo.orthographic().clipAngle(90).precision(0),i.path=n.geo.path().projection(i.projection),i}};return c.plugins.topojson=function(t){return function(o){o.plugins.topojson={},o.onInit(function(i){if(t.world)o.plugins.topojson.world=t.world,setTimeout(i,0);else{var e=t.file||"world-110m.json";n.json(e,function(n,t){if(n)throw new Error("Could not load JSON "+e);o.plugins.topojson.world=t,i()})}})}},c.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()})})}},c.plugins.land=function(n){return function(o){var i=null;o.onInit(function(){var n=o.plugins.topojson.world;i=t.feature(n,n.objects.land)}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(i),0!=n.fill&&(t.fillStyle=n.fill||"white",t.fill()),n.stroke&&(n.lineWidth&&(t.lineWidth=n.lineWidth),t.strokeStyle=n.stroke,t.stroke())})})}},c.plugins.borders=function(n){return function(o){var i=null,e={internal:function(n,t){return n.id!==t.id},external:function(n,t){return n.id===t.id},both:function(){return!0}};o.onInit(function(){var r=o.plugins.topojson.world,l=r.objects.countries,a=n.type||"internal";i=t.mesh(r,l,e[a])}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(i),t.strokeStyle=n.stroke||"gray",n.lineWidth&&(t.lineWidth=n.lineWidth),t.stroke()})})}},c.plugins.earth=function(n){var n=n||{},t=n.topojson||{},o=n.oceans||{},i=n.land||{},e=n.borders||{};return function(n){c.plugins.topojson(t)(n),c.plugins.oceans(o)(n),c.plugins.land(i)(n),c.plugins.borders(e)(n)}},c.plugins.pings=function(t){var o=[],i=function(n,i,e){var e=e||{};e.color=e.color||t.color||"white",e.ttl=e.ttl||t.ttl||2e3,e.angle=e.angle||t.angle||5,o.push({lat:n,lng:i,time:new Date,options:e})},e=function(n,t,i){for(var e=[],l=0;l<o.length;l++){var a=o[l],u=i-a.time;u<a.options.ttl&&(e.push(a),r(n,t,i,u,a))}o=e},r=function(t,o,i,e,r){var l=1-e/r.options.ttl,a=n.rgb(r.options.color);a="rgba("+a.r+","+a.g+","+a.b+","+l+")",o.strokeStyle=a;var u=n.geo.circle().origin([r.lng,r.lat]).angle(e/r.options.ttl*r.options.angle)();o.beginPath(),t.path.context(o)(u),o.stroke()};return function(n){n.plugins.pings={add:i},n.onDraw(function(){var t=new Date;n.withSavedContext(function(o){e(n,o,t)})})}},c.plugins.zoom=function(t){var t=t||{},o=function(){},i=t.onZoomStart||o,e=t.onZoomEnd||o,r=t.onZoom||o,l=t.initialScale,a=t.scaleExtent||[50,2e3];return function(t){t.onInit(function(){var o=n.behavior.zoom().scaleExtent(a);l?o.scale(l):o.scale(t.projection.scale()),o.on("zoomstart",i).on("zoomend",e).on("zoom",function(){r(),t.projection.scale(n.event.scale)}),n.select(t.canvas).call(o)})}},c.plugins.drag=function(t){var t=t||{},o=function(){},i=t.onDragStart||o,e=t.onDragEnd||o,r=t.onDrag||o;return function(t){t.onInit(function(){var o=n.behavior.drag().on("dragstart",i).on("dragend",e).on("drag",function(){r();var o=n.event.dx,i=n.event.dy,e=t.projection.rotate(),l=t.projection.scale(),a=n.scale.linear().domain([-1*l,l]).range([-90,90]),u=a(o),c=a(i);e[0]+=u,e[1]-=c,e[1]>90&&(e[1]=90),e[1]<-90&&(e[1]=-90),e[0]>=180&&(e[0]-=360),t.projection.rotate(e)});n.select(t.canvas).call(o)})}},c});
|
||||||
2
dist/world-110m.json
vendored
2
dist/world-110m.json
vendored
File diff suppressed because one or more lines are too long
25
gulpfile.js
25
gulpfile.js
@ -3,19 +3,16 @@ var uglify = require('gulp-uglify');
|
|||||||
var concat = require('gulp-concat');
|
var concat = require('gulp-concat');
|
||||||
var rename = require('gulp-rename');
|
var rename = require('gulp-rename');
|
||||||
var header = require('gulp-header');
|
var header = require('gulp-header');
|
||||||
var jshint = require('gulp-jshint');
|
|
||||||
var replace = require('gulp-replace');
|
|
||||||
var metadata = require('./package.json');
|
var metadata = require('./package.json');
|
||||||
|
|
||||||
var shortHeader = "/*! Planetary.js <%= version %> | (c) 2013 Michelle Tilley | Released under MIT License */\n"
|
var shortHeader = "/*! Planetary.js {{version}} | (c) 2013 Brandon Tilley | Released under MIT License */"
|
||||||
var fullHeader = [
|
var fullHeader = [
|
||||||
"/*! Planetary.js v<%= version %>",
|
"/*! Planetary.js v{{version}}",
|
||||||
" * Copyright (c) 2013 Michelle Tilley",
|
" * Copyright (c) 2013 Brandon Tilley",
|
||||||
" *",
|
" *",
|
||||||
" * Released under the MIT license",
|
" * Released under the MIT license",
|
||||||
" * Date: <%= new Date().toISOString() %>",
|
" * Date: {{now}}",
|
||||||
" */",
|
" */"
|
||||||
""
|
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
var fullSource = gulp.src(['./src/_umd_header.js', './src/body.js', './src/plugins.js', './src/_umd_footer.js']);
|
var fullSource = gulp.src(['./src/_umd_header.js', './src/body.js', './src/plugins.js', './src/_umd_footer.js']);
|
||||||
@ -25,15 +22,9 @@ function build(source, name, headerText, minify) {
|
|||||||
var js = source.pipe(concat(name));
|
var js = source.pipe(concat(name));
|
||||||
if (minify) { js = js.pipe(uglify()); }
|
if (minify) { js = js.pipe(uglify()); }
|
||||||
js = js.pipe(header(headerText, { version: metadata.version }));
|
js = js.pipe(header(headerText, { version: metadata.version }));
|
||||||
js.pipe(replace("\r\n", "\n")).pipe(gulp.dest('./dist'));
|
js.pipe(gulp.dest('./dist'));
|
||||||
}
|
}
|
||||||
|
|
||||||
gulp.task('jshint', function() {
|
|
||||||
gulp.src(['./src/body.js', './src/plugins.js'])
|
|
||||||
.pipe(jshint())
|
|
||||||
.pipe(jshint.reporter('default'));
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('build', function() {
|
gulp.task('build', function() {
|
||||||
build(fullSource, 'planetaryjs.js', fullHeader, false);
|
build(fullSource, 'planetaryjs.js', fullHeader, false);
|
||||||
build(fullSource, 'planetaryjs.min.js', shortHeader, true);
|
build(fullSource, 'planetaryjs.min.js', shortHeader, true);
|
||||||
@ -43,4 +34,6 @@ gulp.task('build', function() {
|
|||||||
gulp.src('./src/world-110m.json').pipe(gulp.dest('./dist'));
|
gulp.src('./src/world-110m.json').pipe(gulp.dest('./dist'));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('default', ['jshint', 'build']);
|
gulp.task('default', function() {
|
||||||
|
gulp.run('build');
|
||||||
|
});
|
||||||
|
|||||||
4222
package-lock.json
generated
4222
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
22
package.json
22
package.json
@ -1,35 +1,27 @@
|
|||||||
{
|
{
|
||||||
"name": "planetary.js",
|
"name": "planetary.js",
|
||||||
"version": "1.1.3",
|
"version": "0.2.1",
|
||||||
"description": "Awesome interactive globes for the web",
|
"description": "Awesome interactive globes for the web",
|
||||||
"main": "dist/planetaryjs",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rm -r dist/ ; gulp && cp dist/planetaryjs.min.js site/public/js/lib",
|
"build": "rm -r dist/ ; gulp && cp dist/planetaryjs.min.js site/public/js/lib",
|
||||||
"jshint": "gulp jshint",
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git://github.com/BinaryMuse/planetary.js.git"
|
"url": "git://github.com/BinaryMuse/planetary.js.git"
|
||||||
},
|
},
|
||||||
"author": "Michelle Tilley <michelle@michelletilley.net>",
|
"author": "Brandon Tilley <brandon@brandontilley.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/BinaryMuse/planetary.js/issues"
|
"url": "https://github.com/BinaryMuse/planetary.js/issues"
|
||||||
},
|
},
|
||||||
"homepage": "http://planetaryjs.com",
|
"homepage": "http://planetaryjs.com",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"gulp": "~3.6.2",
|
"gulp": "~3.2.0",
|
||||||
"gulp-concat": "BinaryMuse/gulp-concat",
|
"gulp-concat": "BinaryMuse/gulp-concat",
|
||||||
"gulp-header": "~1.0.2",
|
"gulp-header": "~0.4.0",
|
||||||
"gulp-uglify": "~0.3.0",
|
"gulp-uglify": "~0.1.0",
|
||||||
"gulp-rename": "~1.2.0",
|
"gulp-rename": "~0.2.1",
|
||||||
"bower": "~1.2.8",
|
"bower": "~1.2.8"
|
||||||
"gulp-jshint": "~1.6.1",
|
|
||||||
"gulp-replace": "~0.3.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"topojson": "^1.4.6",
|
|
||||||
"d3": "^3.3.13"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,39 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
var fs = require('fs');
|
|
||||||
var spawn = require('child_process').spawn;
|
|
||||||
|
|
||||||
var type = process.argv[2];
|
|
||||||
var version = process.argv[3];
|
|
||||||
|
|
||||||
if ("stable" !== type && "unstable" !== type) {
|
|
||||||
console.log("You must specify 'stable' or 'unstable' version type.");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!version) {
|
|
||||||
console.log("You must specify a version.");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version[0] === 'v') {
|
|
||||||
version = version.replace(/^v/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
var package = require("../package.json");
|
|
||||||
var bower = require("../bower.json");
|
|
||||||
var site = require("../site/public/download/_data.json");
|
|
||||||
|
|
||||||
package.version = version;
|
|
||||||
bower.version = version;
|
|
||||||
|
|
||||||
site[type].latest = site[type].latest || {};
|
|
||||||
site[type].latest.version = "v" + version;
|
|
||||||
|
|
||||||
fs.writeFileSync('package.json', JSON.stringify(package, null, ' ') + "\n");
|
|
||||||
fs.writeFileSync('bower.json', JSON.stringify(bower, null, ' ') + "\n");
|
|
||||||
fs.writeFileSync('site/public/download/_data.json', JSON.stringify(site, null, ' ') + "\n");
|
|
||||||
|
|
||||||
spawn('npm', ['run', 'build']);
|
|
||||||
|
|
||||||
console.log("Tasks:\n\n - Update CHANGELOG.md\n - Regenerate site\n - Create release on GH");
|
|
||||||
@ -9,7 +9,7 @@
|
|||||||
"start": "harp server",
|
"start": "harp server",
|
||||||
"compile": "harp compile"
|
"compile": "harp compile"
|
||||||
},
|
},
|
||||||
"author": "Michelle Tilley <michelle@michelletilley.net>",
|
"author": "Brandon Tilley <brandon@brandontilley.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
<script>
|
|
||||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
||||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
||||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
||||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
|
||||||
|
|
||||||
ga('create', 'UA-46705270-1', 'planetaryjs.com');
|
|
||||||
ga('send', 'pageview');
|
|
||||||
</script>
|
|
||||||
@ -3,8 +3,6 @@
|
|||||||
<link type="text/css" rel="stylesheet" href="/semantic/css/semantic.min.css">
|
<link type="text/css" rel="stylesheet" href="/semantic/css/semantic.min.css">
|
||||||
<link type="text/css" rel="stylesheet" href="/css/planetaryjs.css">
|
<link type="text/css" rel="stylesheet" href="/css/planetaryjs.css">
|
||||||
|
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
|
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
|
||||||
<meta property="og:image" content="http://planetaryjs.com/images/ex-rotating.png">
|
|
||||||
<meta property="og:site_name" content="Planetary.js">
|
|
||||||
|
|||||||
@ -12,6 +12,5 @@
|
|||||||
|
|
||||||
<%- partial("_scripts") %>
|
<%- partial("_scripts") %>
|
||||||
<script type="text/javascript" src="js/homepage.js"></script>
|
<script type="text/javascript" src="js/homepage.js"></script>
|
||||||
<%- partial("_ga") %>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
<div class='ui fixed inverted large menu main-menu'>
|
<div class='ui fixed inverted large menu main-menu'>
|
||||||
<div class='items'>
|
<div class='items'>
|
||||||
<a class='item title' href='/'>
|
<a class='item title' href='/index.html'>
|
||||||
<i class='globe icon'></i>Planetary.js
|
<i class='globe icon'></i>Planetary.js
|
||||||
</a>
|
</a>
|
||||||
<span class='spacer hide-on-mobile'></span>
|
<span class='spacer hide-on-mobile'></span>
|
||||||
<a class='item minor <%- current.path[0] == 'download' ? 'active' : '' %>' href='/download/'>
|
<a class='item minor' href='https://github.com/BinaryMuse/planetary.js/releases'>
|
||||||
<i class='download icon'></i><span class='hide-on-mobile'>Download</span>
|
<i class='download icon'></i><span class='hide-on-mobile'>Download</span>
|
||||||
</a>
|
</a>
|
||||||
<a class='item minor <%- current.path[0] == 'examples' ? 'active' : '' %>' href='/examples/'>
|
<a class='item minor <%- current.path[0] == 'examples' ? 'active' : '' %>' href='/examples/'>
|
||||||
@ -13,8 +13,7 @@
|
|||||||
<a class='item minor <%- current.path[0] == 'documentation' ? 'active' : '' %>' href='/documentation/'>
|
<a class='item minor <%- current.path[0] == 'documentation' ? 'active' : '' %>' href='/documentation/'>
|
||||||
<i class='book icon'></i><span class='hide-on-mobile'>Documentation</span>
|
<i class='book icon'></i><span class='hide-on-mobile'>Documentation</span>
|
||||||
</a>
|
</a>
|
||||||
<a class='item minor' href='https://github.com/BinaryMuse/planetary.js'
|
<a class='item minor' href='https://github.com/BinaryMuse/planetary.js'>
|
||||||
onclick="_gaq.push(['_trackPageview', '/redirect-to-github-project-page']);">
|
|
||||||
<i class='github alternate icon'></i><span class='hide-on-mobile'>Fork on GitHub</span>
|
<i class='github alternate icon'></i><span class='hide-on-mobile'>Fork on GitHub</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Planetary.js AMD Test</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<canvas id='globe' width='500' height='500'></canavs>
|
|
||||||
<script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.9/require.min.js"
|
|
||||||
data-main="/amd/test.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
requirejs.config({
|
|
||||||
baseUrl: '/js/lib',
|
|
||||||
shim: {
|
|
||||||
d3: { exports: 'd3' },
|
|
||||||
topojson: { exports: 'topojson' }
|
|
||||||
},
|
|
||||||
paths: {
|
|
||||||
"d3": 'd3.v3.min',
|
|
||||||
"topojson": 'topojson.v1.min'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
requirejs(['planetaryjs.min'], function(planetaryjs) {
|
|
||||||
var planet = planetaryjs.planet();
|
|
||||||
// You can remove this statement if `world-110m.json`
|
|
||||||
// is in the same path as the HTML page:
|
|
||||||
planet.loadPlugin(planetaryjs.plugins.earth({
|
|
||||||
topojson: { file: '/world-110m.json' }
|
|
||||||
}));
|
|
||||||
// Make the planet fit well in its canvas
|
|
||||||
planet.projection.scale(250).translate([250, 250]);
|
|
||||||
var canvas = document.getElementById('globe');
|
|
||||||
planet.draw(canvas);
|
|
||||||
});
|
|
||||||
@ -35,7 +35,7 @@ h1.title-header, h2.title-header {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.feature-list, .download-list {
|
.feature-list {
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
@ -43,10 +43,6 @@ h1.title-header, h2.title-header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.label.bower {
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.ui.icon.header {
|
a.ui.icon.header {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: black;
|
color: black;
|
||||||
@ -56,10 +52,6 @@ a.ui.icon.header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-description {
|
|
||||||
min-height: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.divider {
|
.divider {
|
||||||
.icon.huge {
|
.icon.huge {
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
@ -133,7 +125,6 @@ canvas#homepage-globe-canvas {
|
|||||||
|
|
||||||
.ui.dark.blue.label {
|
.ui.dark.blue.label {
|
||||||
background-color: #000080 !important;
|
background-color: #000080 !important;
|
||||||
margin-top: 5px;
|
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
background-color: #000080 !important;
|
background-color: #000080 !important;
|
||||||
@ -144,22 +135,8 @@ canvas#homepage-globe-canvas {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.example-segment {
|
.ui.menu .item.with-subitems {
|
||||||
.horizontal.label {
|
// padding-bottom: 0.2em;
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 200px;
|
|
||||||
height: 200px;
|
|
||||||
float: left;
|
|
||||||
margin-right: 20px;
|
|
||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
|
||||||
display: block;
|
|
||||||
float: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.menu .item.contains-subitems {
|
.ui.menu .item.contains-subitems {
|
||||||
|
|||||||
@ -29,13 +29,13 @@ pre[class*="language-"] {
|
|||||||
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
|
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
|
||||||
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
|
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
background: #b3d4fc;
|
/* background: #b3d4fc; */
|
||||||
}
|
}
|
||||||
|
|
||||||
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
|
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
|
||||||
code[class*="language-"]::selection, code[class*="language-"] ::selection {
|
code[class*="language-"]::selection, code[class*="language-"] ::selection {
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
background: #b3d4fc;
|
/* background: #b3d4fc; */
|
||||||
}
|
}
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
|
|||||||
@ -15,10 +15,6 @@
|
|||||||
Introduction
|
Introduction
|
||||||
<i class='icon home'></i>
|
<i class='icon home'></i>
|
||||||
</a>
|
</a>
|
||||||
<a class='purple item <%- current.source == 'installation' ? 'active' : '' %>' href='/documentation/installation.html'>
|
|
||||||
Installation
|
|
||||||
<i class='icon download'></i>
|
|
||||||
</a>
|
|
||||||
<a class='blue item <%- current.source == 'core' ? 'active' : '' %>' href='/documentation/core.html'>
|
<a class='blue item <%- current.source == 'core' ? 'active' : '' %>' href='/documentation/core.html'>
|
||||||
Core API
|
Core API
|
||||||
<i class='icon setting'></i>
|
<i class='icon setting'></i>
|
||||||
@ -47,13 +43,9 @@
|
|||||||
<a class='item <%- current.source == 'builtin_drag' ? 'active' : '' %>' href='/documentation/builtin_drag.html'>Drag</a>
|
<a class='item <%- current.source == 'builtin_drag' ? 'active' : '' %>' href='/documentation/builtin_drag.html'>Drag</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a class='red item <%- current.source == 'faq' ? 'active' : '' %>' href='/documentation/faq.html'>
|
|
||||||
FAQ
|
|
||||||
<i class='icon help'></i>
|
|
||||||
</a>
|
|
||||||
<a class='green item <%- current.source == 'help' ? 'active' : '' %>' href='/documentation/help.html'>
|
<a class='green item <%- current.source == 'help' ? 'active' : '' %>' href='/documentation/help.html'>
|
||||||
Getting Help
|
Getting Help
|
||||||
<i class='icon phone'></i>
|
<i class='icon help'></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -64,6 +56,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type='text/javascript' src='/js/prism.js'></script>
|
<script type='text/javascript' src='/js/prism.js'></script>
|
||||||
<%- partial("../_ga") %>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -5,13 +5,13 @@ Planetary.js comes with several built-in plugins that provide a base set of func
|
|||||||
|
|
||||||
* [Earth](/documentation/builtin_earth.html) - a combination of the `topojson`, `oceans`, `land`, and `borders` plugins.
|
* [Earth](/documentation/builtin_earth.html) - a combination of the `topojson`, `oceans`, `land`, and `borders` plugins.
|
||||||
* [TopoJSON](/documentation/builtin_topojson.html) - loads TopoJSON data via Ajax (or via configuration) and makes it available for use by other plugins
|
* [TopoJSON](/documentation/builtin_topojson.html) - loads TopoJSON data via Ajax (or via configuration) and makes it available for use by other plugins
|
||||||
* [Oceans](/documentation/builtin_oceans.html) - fills in the globe with a solid color
|
* [Oceans](/documentation/builtin_oceans.html) - fills in the globe with a solid color (and an optional stroke)
|
||||||
* [Land](/documentation/builtin_land.html) - uses data from the `topojson` plugin to draw Earth's land masses
|
* [Land](/documentation/builtin_land.html) - uses data from the `topojson` plugin to draw Earth's land masses
|
||||||
* [Borders](/documentation/builtin_borders.html) - uses data from the `topojson` plugin to draw borders between Earth's countries
|
* [Borders](/documentation/builtin_borders.html) - uses data from the `topojson` plugin to draw borders between Earth's countries
|
||||||
* [Pings](/documentation/builtin_pings.html) - draws animated, circular pings on the globe
|
* [Pings](/documentation/builtin_pings.html) - draws animated, circular pings on the globe
|
||||||
* [Zoom](/documentation/builtin_zoom.html) - enables mouse-based zooming of the globe via the mousewheel
|
* [Zoom](/documentation/builtin_zoom.html) - enables mouse-based zooming of the globe via the mousewheel
|
||||||
* [Drag](/documentation/builtin_drag.html) - enables mouse-based rotation of the globe via dragging
|
* [Drag](/documentation/builtin_drag.html) - enables mouse-based rotation of the globe via dragging
|
||||||
|
|
||||||
Built-in plugins are exposed as properties on `planetaryjs.plugins`.
|
Built-in plugins exposed as properties on `planetaryjs.plugins`.
|
||||||
|
|
||||||
If you do not specify any plugins (globally or per-instance), Planetary.js will use the `earth` and `pings` plugins with their default settings.
|
If you do not specify any plugins (globally or per-instance), Planetary.js will use the `earth` and `pings` plugins with their default settings.
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
Borders Plugin
|
Borders Plugin
|
||||||
==============
|
==============
|
||||||
|
|
||||||
The `borders` plugin renders the borders around (and between) countries. It uses TopoJSON data published to `planet.plugins.topojson.world` by the [TopoJSON plugin](/documentation/builtin_topojson.html). It uses the feature at `objects.countries` in the TopoJSON object to calculate the borders.
|
The `borders` plugin renders the borders around (and between) countries. It uses TopoJSON data published to `planet.plugins.topojson.world` by the [TopoJSON plugin](/documentation/builtin_topojson.html).
|
||||||
|
|
||||||
API
|
API
|
||||||
---
|
---
|
||||||
@ -14,7 +14,7 @@ Valid keys for `config` are:
|
|||||||
* `lineWidth` the `lineWidth` to set on the context; defaults to no value, and the context's `lineWidth` is not modified
|
* `lineWidth` the `lineWidth` to set on the context; defaults to no value, and the context's `lineWidth` is not modified
|
||||||
* `type`: valid options are `"internal"`, `"external"`, or `"both"`. `"internal"` draws borders between countries but not coastlines; `"external"` does the opposite. `"both"`, unsurprisingly, draws both. Defaults to `"internal"`.
|
* `type`: valid options are `"internal"`, `"external"`, or `"both"`. `"internal"` draws borders between countries but not coastlines; `"external"` does the opposite. `"both"`, unsurprisingly, draws both. Defaults to `"internal"`.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -26,5 +26,4 @@ planetaryjs.plugins.borders({
|
|||||||
|
|
||||||
See also:
|
See also:
|
||||||
|
|
||||||
* [Earth Plugin](/documentation/builtin_earth.html)
|
|
||||||
* [TopoJSON Plugin](/documentation/builtin_topojson.html)
|
* [TopoJSON Plugin](/documentation/builtin_topojson.html)
|
||||||
|
|||||||
@ -10,15 +10,15 @@ API
|
|||||||
|
|
||||||
Valid keys for `config` are:
|
Valid keys for `config` are:
|
||||||
|
|
||||||
* `onDragStart`, `onDragEnd`, `onDrag`, `afterDrag`: hooks to the `d3.behavior.drag` object's `dragstart`, `dragend`, and `drag` events; each defaults to a no-op. `onDrag` fires at the start of the `drag` event, `afterDrag` at the end. The planet instance is available as `this` inside the each of the functions.
|
* `onDrag`, `onDragStart`, `onDragEnd`: hooks to the `d3.behavior.drag` object's `drag`, `dragstart`, and `dragend` events; each defaults to a no-op
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
planetaryjs.plugins.drag({
|
planetaryjs.plugins.drag({
|
||||||
onDrag: function() {
|
onDrag: function() {
|
||||||
console.log("The planet was dragged!", this, d3.event);
|
console.log("The planet was dragged!", d3.event);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|||||||
@ -15,7 +15,7 @@ Valid keys for `config` are:
|
|||||||
* `land`: options to pass to the `land` plugin
|
* `land`: options to pass to the `land` plugin
|
||||||
* `borders`: options to pass to the `borders` plugin
|
* `borders`: options to pass to the `borders` plugin
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
Land Plugin
|
Land Plugin
|
||||||
===========
|
===========
|
||||||
|
|
||||||
The `land` plugin renders Earth's landmasses. It uses TopoJSON data published to `planet.plugins.topojson.world` by the [TopoJSON plugin](/documentation/builtin_topojson.html). It uses the feature at `objects.land` in the TopoJSON object.
|
The `land` plugin renders Earth's landmasses. It uses TopoJSON data published to `planet.plugins.topojson.world` by the [TopoJSON plugin](/documentation/builtin_topojson.html).
|
||||||
|
|
||||||
API
|
API
|
||||||
---
|
---
|
||||||
@ -14,7 +14,7 @@ Valid keys for `config` are:
|
|||||||
* `stroke`: the `strokeStyle` to use for the context; defaults to no value, resulting in no stroke around the landmasses
|
* `stroke`: the `strokeStyle` to use for the context; defaults to no value, resulting in no stroke around the landmasses
|
||||||
* `lineWidth` the `lineWidth` to set on the context; only effective if `stroke` is set. Defaults to no value, resulting in no change to the context's `lineWidth`
|
* `lineWidth` the `lineWidth` to set on the context; only effective if `stroke` is set. Defaults to no value, resulting in no change to the context's `lineWidth`
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -26,5 +26,4 @@ planetaryjs.plugins.land({
|
|||||||
|
|
||||||
See also:
|
See also:
|
||||||
|
|
||||||
* [Earth Plugin](/documentation/builtin_earth.html)
|
|
||||||
* [TopoJSON Plugin](/documentation/builtin_topojson.html)
|
* [TopoJSON Plugin](/documentation/builtin_topojson.html)
|
||||||
|
|||||||
@ -12,7 +12,7 @@ Valid keys for `config` are:
|
|||||||
|
|
||||||
* `fill`: the `fillStyle` to use for the globe; defaults to `"black"`
|
* `fill`: the `fillStyle` to use for the globe; defaults to `"black"`
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -21,7 +21,3 @@ planetaryjs.plugins.oceans({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
See also:
|
|
||||||
|
|
||||||
* [Earth Plugin](/documentation/builtin_earth.html)
|
|
||||||
|
|||||||
@ -13,9 +13,8 @@ Valid keys for `config` are:
|
|||||||
* `color`: the default color for pings; defaults to `"white"`
|
* `color`: the default color for pings; defaults to `"white"`
|
||||||
* `ttl`: the default TTL for pings in milliseconds (how long they take to fade out); defaults to 2000
|
* `ttl`: the default TTL for pings in milliseconds (how long they take to fade out); defaults to 2000
|
||||||
* `angle`: the maximum angle for the ping (it will grow to this size over the course of its TTL); defaults to `5`
|
* `angle`: the maximum angle for the ping (it will grow to this size over the course of its TTL); defaults to `5`
|
||||||
* `latitudeFirst`: reverse the order of the latitudinal and longitudinal coordinates passed to the `add` function (so that the latitudinal coordinate comes first); defaults to false. See the note on `add`, below, for more information.
|
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -25,21 +24,11 @@ planetaryjs.plugins.pings({
|
|||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
**`planet.plugins.pings.add(lng, lat, [config])`**
|
**`planet.plugins.pings.add(lat, lng, [config])`**
|
||||||
|
|
||||||
Add a new ping to the globe at the longitudinal and latitudinal coordinates specified by `lng` and `lat`. Valid keys for `config` are:
|
Add a new ping to the globe at the latitudinal and longitudinal coordinates specified by `lat` and `lng`. `config` may take all the same keys as the configuration option for the plugin itself; any values will overwrite values from that object, if any were set.
|
||||||
|
|
||||||
* `color`: the default color for pings; defaults to `"white"`
|
<div class='ui raise segment'>
|
||||||
* `ttl`: the default TTL for pings in milliseconds (how long they take to fade out); defaults to 2000
|
|
||||||
* `angle`: the maximum angle for the ping (it will grow to this size over the course of its TTL); defaults to `5`
|
|
||||||
|
|
||||||
Any values not set by `config` will default to the values specified in the plugin's configuration, if any were set.
|
|
||||||
|
|
||||||
<div class='ui red raised segment'>
|
|
||||||
<i class='red icon warning'></i> **Note that the longitudinal coordinate comes first, followed by the latitudinal coordinate, unless you pass `latitudeFirst` as an option to the plugin configuration function.** This corresponds to the conventions used by D3 (which Planetary.js is based on); for more information on the problem of axis ordering in software, see [this article at the GeoTools web site](http://docs.geotools.org/latest/userguide/library/referencing/order.html).
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -49,7 +38,7 @@ setInterval(function() {
|
|||||||
var lng = Math.random() * 360 - 180;
|
var lng = Math.random() * 360 - 180;
|
||||||
var color = colors[Math.floor(Math.random() * colors.length)];
|
var color = colors[Math.floor(Math.random() * colors.length)];
|
||||||
var angle = Math.random() * 10;
|
var angle = Math.random() * 10;
|
||||||
planet.plugins.pings.add(lng, lat, { color: color, ttl: 2000, angle: angle });
|
planet.plugins.pings.add(lat, lng, { color: color, ttl: 2000, angle: angle });
|
||||||
}, 250);
|
}, 250);
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -12,12 +12,12 @@ API
|
|||||||
|
|
||||||
Valid keys for `config` are:
|
Valid keys for `config` are:
|
||||||
|
|
||||||
* `world`: a JavaScript object representing TopoJSON data (not a JSON string); defaults to no value, which will cause the plugin to load data from the `file` configuration option
|
* `world`: a JavaScript object representing TopoJSON data (not JSON data); defaults to no value, which will cause the plugin to load data from the `file` configuration option
|
||||||
* `file`: the path to a TopoJSON data file to be loaded via Ajax; defaults to `"world-110m.json"`, which can be downloaded with the Planetary.js library from the [download page](/download/).
|
* `file`: the path to a TopoJSON data file to be loaded via Ajax; defaults to `"world-110m.json"`, which can be downloaded with the Planetary.js library from the [download page](https://github.com/BinaryMuse/planetary.js/releases).
|
||||||
|
|
||||||
If you plan on creating more than one planet from the same TopoJSON data, you can load the data once before loading the plugin and pass the parsed data to the plugin via the `world` property rather than letting the plugin load the data via Ajax each time a new planet is created.
|
If you plan on creating more than one planet from the same TopoJSON data, you can load the data once before loading the plugin and pass the parsed data to the plugin via the `world` property rather than letting the plugin load the data via Ajax each time a new planet is created.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -27,7 +27,7 @@ planetaryjs.plugins.topojson({
|
|||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -40,10 +40,5 @@ d3.json('/data/world-110m.json', function(err, data) {
|
|||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
**`planet.plugins.topojson.world`**
|
|
||||||
|
|
||||||
The plugin will publish the TopoJSON data to this key once it has been initialized by the plugin.
|
|
||||||
|
|
||||||
* [Earth Plugin](/documentation/builtin_earth.html)
|
|
||||||
* [Land Plugin](/documentation/builtin_land.html)
|
* [Land Plugin](/documentation/builtin_land.html)
|
||||||
* [Borders Plugin](/documentation/builtin_borders.html)
|
* [Borders Plugin](/documentation/builtin_borders.html)
|
||||||
|
|||||||
@ -12,16 +12,16 @@ Valid keys for `config` are:
|
|||||||
|
|
||||||
* `initialScale`: the value to initialize the [`d3.behavior.zoom`](https://github.com/mbostock/d3/wiki/Zoom-Behavior) object's scale to; defaults to the scale of the planet's projection at the time the planet is initialized
|
* `initialScale`: the value to initialize the [`d3.behavior.zoom`](https://github.com/mbostock/d3/wiki/Zoom-Behavior) object's scale to; defaults to the scale of the planet's projection at the time the planet is initialized
|
||||||
* `scaleExtent`: the value to use for the `d3.behavior.zoom` object's `scaleExtent` property, which defines how far in and out the planet can be zoomed; defaults to `[50, 2000]`
|
* `scaleExtent`: the value to use for the `d3.behavior.zoom` object's `scaleExtent` property, which defines how far in and out the planet can be zoomed; defaults to `[50, 2000]`
|
||||||
* `onZoomStart`, `onZoomEnd`, `onZoom`, `afterZoom`: hooks to the `d3.behavior.zoom` object's `zoomstart`, `zoomend`, and `zoom` events; each defaults to a no-op. `onZoom` fires at the start of the `zoom` event, `afterZoom` at the end. The planet instance is available as `this` inside the each of the functions.
|
* `onZoom`, `onZoomStart`, `onZoomEnd`: hooks to the `d3.behavior.zoom` object's `zoom`, `zoomstart`, and `zoomend` events; each defaults to a no-op
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
planetaryjs.plugins.zoom({
|
planetaryjs.plugins.zoom({
|
||||||
scaleExtent: [200, 1000],
|
scaleExtent: [200, 1000],
|
||||||
onZoom: function() {
|
onZoom: function() {
|
||||||
console.log("The planet was zoomed!", this, d3.event);
|
console.log("The planet was zoomed!", d3.event);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|||||||
@ -1,6 +1,28 @@
|
|||||||
Core API
|
Core API
|
||||||
========
|
========
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
Once you've [downloaded Planetary.js](https://github.com/BinaryMuse/planetary.js/releases), you can include it via a `script` tag on your page *after* the inclusion of D3 and TopoJSON. This example uses the CDN URLs for those libraries:
|
||||||
|
|
||||||
|
<div class='ui raised segment'>
|
||||||
|
<div class='ui blue ribbon label'>HTML</div>
|
||||||
|
|
||||||
|
```html
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script type='text/javascript' src='http://d3js.org/d3.v3.min.js'></script>
|
||||||
|
<script type='text/javascript' src='http://d3js.org/topojson.v1.min.js'></script>
|
||||||
|
<script type='text/javascript' src='path/to/planetaryjs.min.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
...
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
If you use the default `topojson` plugin (most people will), you'll also need to make sure `world-110m.json` (or some other TopoJSON data file) is available on your server. This file is also available from [the download page](https://github.com/BinaryMuse/planetary.js/releases). See the [TopoJSON Plugin](/documentation/builtin_topojson.html) documentation for more information.
|
||||||
|
|
||||||
Core API
|
Core API
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@ -20,7 +42,7 @@ var planetary = planetaryjs.noConflict();
|
|||||||
|
|
||||||
Planetary.js uses a plugin architecture for all its functionality. Calling `planetaryjs.loadPlugin` will cause that plugin to be loaded in *all* planets created from this library. If you only want to use a plugin in some of your planets, use the `planet.loadPlugin` method (from the [Planet API](/documentation/planet.html)) instead.
|
Planetary.js uses a plugin architecture for all its functionality. Calling `planetaryjs.loadPlugin` will cause that plugin to be loaded in *all* planets created from this library. If you only want to use a plugin in some of your planets, use the `planet.loadPlugin` method (from the [Planet API](/documentation/planet.html)) instead.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -29,13 +51,13 @@ planetaryjs.loadPlugin(somePluginGenerator());
|
|||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
For more information on the plugin system and API, please see the [Plugins documentation](/documentation/plugins.html).
|
For more information on the plugin system and API, please see the [Plugins](/documentation/plugins.html) documentation.
|
||||||
|
|
||||||
**`planetaryjs.planet()`**
|
**`planetaryjs.planet()`**
|
||||||
|
|
||||||
The `planet` API call returns a new planet instance, which represents a single globe. It will be created with all the plugins registered with `planetaryjs.loadPlugin` active. It has various methods for manipulating the globe and drawing it to a canvas. The [Planet API](/documentation/planet.html) covers these methods in considerably more detail.
|
The `planet` API call returns a new planet instance, which represents a single globe. It will be created with all the plugins registered with `planetaryjs.loadPlugin()` active. It has various methods for manipulating the globe and drawing it to a canvas. The [Planet API](/documentation/planet.html) covers these methods in considerably more detail.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|||||||
@ -1,47 +0,0 @@
|
|||||||
FAQ
|
|
||||||
===
|
|
||||||
|
|
||||||
**Q:** Why are the pings I add from the [Pings plugin](/documentation/builtin_pings.html) in the wrong place?
|
|
||||||
|
|
||||||
**A:** Like D3 on which it is based, Planetary.js accepts coordinates with the longitudinal coordinate first. You can set the `latitudeFirst` option in the plugin configuration to change this. There is some additional discussion on the subject in the [Pings plugin documentation](/documentation/builtin_pings.html).
|
|
||||||
|
|
||||||
<div class="ui horizontal icon divider">
|
|
||||||
<i class="globe icon"></i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
**Q:** Why can't I access my DOM element?
|
|
||||||
|
|
||||||
**A:** Planetary.js provides no methods for DOM access or for waiting for the DOM ready event; you'll need to handle this on your own or use a third-party library.
|
|
||||||
|
|
||||||
<div class="ui horizontal icon divider">
|
|
||||||
<i class="globe icon"></i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
**Q:** Why doesn't my `canvas` element work with Planetary.js?
|
|
||||||
|
|
||||||
**A:** Planetary.js asks for raw DOM elements; if you have an element wrapped with jQuery, D3, or a similar library, you'll need to unwrap it to pass to your
|
|
||||||
planet's `draw` method.
|
|
||||||
|
|
||||||
<div class="ui horizontal icon divider">
|
|
||||||
<i class="globe icon"></i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
**Q:** Why can't I load the `world-110m.json` file with the TopoJSON plugin?
|
|
||||||
|
|
||||||
**A:** After checking to make sure you've specified the correct path to the file in the plugin's configuration options, ensure that you're viewing your page over HTTP. Your browser won't be able to make the necessary Ajax request to load the file if you're just viewing the page from your filesystem.
|
|
||||||
|
|
||||||
<div class="ui horizontal icon divider">
|
|
||||||
<i class="globe icon"></i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
**Q:** How do I manipulate my globe?
|
|
||||||
|
|
||||||
**A:** The planet object has methods and properties for manipulating the globe; most notable is the `projection` property. See the [Planet API](/documentation/planet.html) for more information.
|
|
||||||
|
|
||||||
<div class="ui horizontal icon divider">
|
|
||||||
<i class="globe icon"></i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
**Q:** I'm getting "Cannot read property 'geo' of undefined" or "Cannot call method 'feature' of undefined."
|
|
||||||
|
|
||||||
**A:** Ensure you're requiring the [D3](http://d3js.org/) and [TopoJSON](https://github.com/mbostock/topojson) libraries before Planetary.js.
|
|
||||||
@ -1,27 +1,23 @@
|
|||||||
Introduction
|
Introduction
|
||||||
============
|
============
|
||||||
|
|
||||||
Planetary.js is a JavaScript library for building awesome interactive globes. It uses [D3](http://d3js.org/) and [TopoJSON](https://github.com/mbostock/topojson) to parse and render geographic data. Planetary.js uses a plugin-based architecture; even the default functionality is implemented as plugins! This makes Planetary.js extremely flexible.
|
Planetary.js is a JavaScript library for building awesome interactive globes. It uses [D3](http://d3js.org/) and [TopoJSON](https://github.com/mbostock/topojson) to parse and render geographic data. Planetary.js is a plugin-based system; even the default functionality is implemented as plugins! This makes Planetary.js extremely flexible.
|
||||||
|
|
||||||
The documentation is split up into several sections:
|
The documentation is split up into several sections:
|
||||||
|
|
||||||
* [Core API](/documentation/core.html) describes the top-level Planetary.js API, including installing and configuring the library and creating new planet instances.
|
* [Core API](/documentation/core.html) describes the top-level Planetary.js API, including installing and configuring the library and creating new instances of planets.
|
||||||
* [Planet API](/documentation/planet.html) describes the API associated with a planet instance, including modifying its properties and accessing a special canvas context that allows you to draw on the globe.
|
* [Planet API](/documentation/planet.html) describes the API associated with a planet instance, including modifying its properties and accessing a special canvas context that allows you to draw on the globe.
|
||||||
* [Plugins](/documentation/plugins.html) describes the plugin architecture of Planetary.js and shows how you can easily build your own plugins to modify the behavior of Planetary.js.
|
* [Plugins](/documentation/plugins.html) describes the plugin architecture of Planetary.js and shows how you can easily build your own plugins to modify the behavior of Planetary.js
|
||||||
* [Built-In Plugins](/documentation/builtin.html) describes each of the built-in plugins in turn, including their public API and how to use them in a project.
|
* [Built-In Plugins](/documentation/builtin.html) describes each of the built-in plugins in turn, including their public API and how to use them in a project.
|
||||||
* [FAQ](/documentation/faq.html) answers some common question and addresses a few easy-to-miss gotchas.
|
|
||||||
* [Getting Help](/documentation/help.html) describes what to do if you still need help after reading this documentation.
|
|
||||||
|
|
||||||
Quick Start
|
Quick Start
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
If you want to get up-and-running quickly, or like to experiment and figure things out, you can use this HTML and JavaScript to get a very simple globe up and running (once you've [installed Planetary.js](/documentation/installation.html)).
|
If you want to get up-and-running quickly, or like to experiment and figure things out, you can use this HTML and JavaScript to get a quick, simple globe working quickly.
|
||||||
|
|
||||||
Note that you'll need to run this page from a web server of some kind so that Planetary.js can load the TopoJSON data via Ajax (Ajax requests don't work when viewing a page directly from the filesystem).
|
Note that you'll need to run this page from a web server of some kind so that Planetary.js can load the TopoJSON data via Ajax (Ajax requests don't work when viewing a page directly from the filesystem).
|
||||||
|
|
||||||
Be sure to check out [the examples](/examples/) as well!
|
<div class='ui raise segment'>
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
|
||||||
<div class='ui blue ribbon label'>HTML</div>
|
<div class='ui blue ribbon label'>HTML</div>
|
||||||
|
|
||||||
```html
|
```html
|
||||||
|
|||||||
@ -1,97 +0,0 @@
|
|||||||
Installation
|
|
||||||
============
|
|
||||||
|
|
||||||
Once you've [downloaded Planetary.js](/download/), you can include it via a `script` tag on your page *after* the inclusion of D3 and TopoJSON. This example uses the CDN URLs for those libraries:
|
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
|
||||||
<div class='ui blue ribbon label'>HTML</div>
|
|
||||||
|
|
||||||
```html
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<script type='text/javascript' src='http://d3js.org/d3.v3.min.js'></script>
|
|
||||||
<script type='text/javascript' src='http://d3js.org/topojson.v1.min.js'></script>
|
|
||||||
<script type='text/javascript' src='path/to/planetaryjs.min.js'></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
...
|
|
||||||
```
|
|
||||||
</div>
|
|
||||||
|
|
||||||
If you use the default `topojson` plugin (most people will), you'll also need to make sure `world-110m.json` (or some other TopoJSON data file) is available on your server. This file is also available from [the download page](/download/). See the [TopoJSON Plugin documentation](/documentation/builtin_topojson.html) for more information.
|
|
||||||
|
|
||||||
Planetary.js also supports installation via AMD and CommonJS loaders.
|
|
||||||
|
|
||||||
AMD
|
|
||||||
---
|
|
||||||
|
|
||||||
This example uses [RequireJS](http://requirejs.org/). Since neither D3 nor TopoJSON support AMD, we will use RequireJS's [shim configuration](http://requirejs.org/docs/api.html#config-shim).
|
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
|
||||||
<div class='ui blue ribbon label'>HTML</div>
|
|
||||||
|
|
||||||
```html
|
|
||||||
<body>
|
|
||||||
<canvas id='globe' width='500' height='500'></canavs>
|
|
||||||
<script src='//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.9/require.min.js'
|
|
||||||
data-main='/app.js'></script>
|
|
||||||
</body>
|
|
||||||
```
|
|
||||||
|
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
requirejs.config({
|
|
||||||
// Tell RequireJS to use `window.d3` and `window.topojson`
|
|
||||||
// for those libraries, respectively
|
|
||||||
shim: {
|
|
||||||
d3: { exports: 'd3' },
|
|
||||||
topojson: { exports: 'topojson' }
|
|
||||||
},
|
|
||||||
paths: {
|
|
||||||
'd3': 'path/to/d3.v3.min',
|
|
||||||
'topojson': 'path/to/topojson.v1.min'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
requirejs(['planetaryjs'], function(planetaryjs) {
|
|
||||||
// Use Planetary.js here
|
|
||||||
});
|
|
||||||
|
|
||||||
```
|
|
||||||
</div>
|
|
||||||
|
|
||||||
CommonJS
|
|
||||||
--------
|
|
||||||
|
|
||||||
First, install `browserify` from npm (as well as `planetary.js` v1.0.2+, if you haven't already). Then, create your application (here referred to as `app.js`) and bundle it with browserify.
|
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var planetaryjs = require('planetary.js');
|
|
||||||
|
|
||||||
var planet = planetaryjs.planet();
|
|
||||||
var canvas = document.getElementById('canvas');
|
|
||||||
planet.draw(canvas);
|
|
||||||
```
|
|
||||||
|
|
||||||
<div class='ui purple ribbon label'>Shell</div>
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ npm install browserify
|
|
||||||
$ ./node_modules/.bin/browserify app.js > bundle.js
|
|
||||||
```
|
|
||||||
</div>
|
|
||||||
|
|
||||||
`bundle.js` is now ready to use! You may need to set the `charset` option on your script tag:
|
|
||||||
|
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
|
||||||
<div class='ui blue ribbon label'>HTML</div>
|
|
||||||
|
|
||||||
```html
|
|
||||||
<script type='text/javascript' src='bundle.js' charset='utf-8'></script>
|
|
||||||
```
|
|
||||||
</div>
|
|
||||||
@ -1,13 +1,13 @@
|
|||||||
Planet API
|
Planet API
|
||||||
==========
|
==========
|
||||||
|
|
||||||
A "planet" represents a single globe and its rendering instructions. It is created from the `planetaryjs.planet` method; see the [Core API documentation](/documentation/core.html) for more details.
|
A "planet" represents a single globe and its rendering instructions. It is created from the `planetaryjs.planet()` method; see the [Core API](/documentation/core.html) documentation for more details.
|
||||||
|
|
||||||
**`planet.loadPlugin(plugin)`**
|
**`planet.loadPlugin(plugin)`**
|
||||||
|
|
||||||
Planetary.js uses a plugin architecture for all its functionality. While you can load plugins at the global library level, Planetary.js also allows you to load plugins for specific planets. **If a planet is drawn and no plugins have been loaded globally and no plugins have been loaded for the specific planet instance, it will use the default `earth` and `pings` plugins.**
|
Planetary.js uses a plugin architecture for all its functionality. While you can load plugins at the global library level, Planetary.js also allows you to load plugins for specific planets. **If a planet is drawn and no plugins have been loaded globally and no plugins have been loaded for the specific planet instance, it will use the default `earth` and `pings` plugins.**
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -16,28 +16,27 @@ planet.loadPlugin(somePluginGenerator());
|
|||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
For more information on the plugin system and API, please see the [Plugins documentation](/documentation/plugins.html).
|
For more information on the plugin system and API, please see the [Plugins](/documentation/plugins.html) documentation.
|
||||||
|
|
||||||
**`planet.projection`**
|
**`planet.projection`**
|
||||||
|
|
||||||
The core of a planet's data model is an [`d3.geo.projection`](https://github.com/mbostock/d3/wiki/Geo-Projections) (specifically, an orthographic projection), which is exposed by a planet by `planet.projection`. You can use this object to control various aspects of the planet. The D3 documentation covers the methods in considerable detail, so [be sure to check it out](https://github.com/mbostock/d3/wiki/Geo-Projections); many of the examples on this site also use the projection object to operate.
|
The core of a planet's data model is an [`d3.geo.projection`](https://github.com/mbostock/d3/wiki/Geo-Projections) (specifically, an orthographic projection), which is exposed by a planet by `planet.projection`. You can use this object to control various aspects of the planet. The D3 documentation covers the methods in considerable detail, so [be sure to check it out](https://github.com/mbostock/d3/wiki/Geo-Projections); many of the examples on this site also use the projection object to operate.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
planet.projection
|
planet.projection
|
||||||
.scale(width / 2)
|
.scale(width / 2)
|
||||||
.translate([width / 2, height / 2])
|
|
||||||
.rotate([60, -10, 0]);
|
.rotate([60, -10, 0]);
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
**`planet.path`**
|
**`planet.path`**
|
||||||
|
|
||||||
`planet.path` is a [`d3.geo.path`](https://github.com/mbostock/d3/wiki/Geo-Paths) which uses the planet's internal projection to generate path data for geographical features. Its `context` method is commonly used by internal plugins to take a canvas context and return a path generator that can be used to draw on the globe.
|
`planet.path` is a [`d3.geo.path`](https://github.com/mbostock/d3/wiki/Geo-Paths) which uses the planet's internal projection to generate path data for geographical features. Its `context` method is commonly used by interal plugins to take a canvas context and return a path generator that can be used to draw on the globe.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -57,11 +56,11 @@ Once you call `draw` on a planet instance, Planetary.js will set the `canvas` an
|
|||||||
|
|
||||||
**`planet.onInit( function([done]){} )`**
|
**`planet.onInit( function([done]){} )`**
|
||||||
|
|
||||||
Registers a function to be called when the planet is initialized (which happens after a call to `draw` and after any registered plugins have been loaded). This is mostly used by plugins to initialize themselves when the planet "boots."
|
Registers a function to be called when the planet is initialized (which happens after a call to `draw` and after any loaded plugins have been initialized). This is mostly used by plugins to initialize themselves when the planet "boots."
|
||||||
|
|
||||||
If the provided callback function takes any parameters, it will be a "done" function that must be called once the initialization function finishes any asynchronous work before the planet will continue to initialize.
|
If the provided callback function takes any parameters, it will be a "done" function that must be called once the initialization function finishes any asynchronous work before the planet will continue to initialize.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -81,7 +80,7 @@ planet.onInit(function(done) {
|
|||||||
|
|
||||||
Registers a function to be called each time the globe redraws itself. This is mostly used by plugins to draw plugin-specific data or otherwise animate the globe.
|
Registers a function to be called each time the globe redraws itself. This is mostly used by plugins to draw plugin-specific data or otherwise animate the globe.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -94,29 +93,11 @@ planet.onDraw(function() {
|
|||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
**`planet.onStop( function(){} )`**
|
|
||||||
|
|
||||||
Registers a function to be called when the planet is stopped with the `stop` method. This can be used to clean up timers and remove references to internal planet properties and plugins, if necessary, so that it can be property garbage collected.
|
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var interval = setInterval(function() {
|
|
||||||
addRandomPing(planet); // uses `planet.plugins.pings`
|
|
||||||
}, 150);
|
|
||||||
|
|
||||||
planet.onStop(function() {
|
|
||||||
clearInterval(interval);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
</div>
|
|
||||||
|
|
||||||
**`planet.withSavedContext( function(context){} )`**
|
**`planet.withSavedContext( function(context){} )`**
|
||||||
|
|
||||||
Calls the function with the current canvas context as a parameter, wrapping the function call in `context.save()` and `context.restore()`. Use this function any time you're going to modify the context to ensure it gets put back to the way it was.
|
Calls the function with the current canvas context as a paremter, wrapping the function call in `context.save()` and `context.restore()`. Use this function any time you're going to modify the context to ensure it gets put back to the way it was.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -137,12 +118,12 @@ Begins drawing the globe onto the given canvas. `canvas` should be a raw DOM ele
|
|||||||
|
|
||||||
Calling `draw` will perform the following operations:
|
Calling `draw` will perform the following operations:
|
||||||
|
|
||||||
1. Initialize each loaded plugin by calling the plugin function (note: this only happens the first time you call `draw`).
|
1. Initialize each loaded plugin by calling the plugin function.
|
||||||
2. Set `planet.canvas` and `planet.context` to the canvas and the canvas' context, respectively.
|
2. Set `planet.canvas` and `planet.context` to the canvas and the canvas' context, respectively.
|
||||||
3. Run each registered `onInit` hook in the order it was registered (note that `onInit` calls made by plugins will not be made until step 1, after `draw` has been called).
|
3. Run each registered `onInit` hook in the order it was registered (note that `onInit` calls made by plugins will not be made until step 1, after `draw` has been called).
|
||||||
4. Start the animation loop, each tick clearing the canvas and calling any registered `onDraw` hooks in order.
|
4. Start the animation loop, each tick clearing the canvas and calling any registered `onDraw` hooks in order.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui blue ribbon label'>HTML</div>
|
<div class='ui blue ribbon label'>HTML</div>
|
||||||
|
|
||||||
```html
|
```html
|
||||||
@ -156,21 +137,3 @@ var canvas = document.getElementById('myCanvas');
|
|||||||
planet.draw(canvas);
|
planet.draw(canvas);
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Once you've called `draw()` on a planet, you should not call it again unless you first call `stop()`.
|
|
||||||
|
|
||||||
**`planet.stop()`**
|
|
||||||
|
|
||||||
Stop drawing the planet to the canvas. This disables the internal draw loop. You can register functions to call when the planet is stopped using the `onStop` method; if you don't plan on reusing the planet, be sure to clean up timers and references to internal properties, if necessary, so that it can be garbage collected.
|
|
||||||
|
|
||||||
You can draw the planet to a new (or the same) canvas using the `draw` method as normal. All your plugins' `onInit` functions will fire, although the plugin function itself will not be called again.
|
|
||||||
|
|
||||||
Keep in mind that, since the internal draw loop is stopped, your plugins' `onDraw` functions are not being called. If you have timers or other mechanisms that continually push data into a data structure that an `onDraw` method cleans up, you should disable or pause it.
|
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
planet.stop();
|
|
||||||
```
|
|
||||||
</div>
|
|
||||||
|
|||||||
@ -11,11 +11,11 @@ Plugins are loaded either globally by `planetaryjs.loadPlugin` or for a specific
|
|||||||
Anatomy of a Plugin
|
Anatomy of a Plugin
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
A plugin is simply a JavaScript function that takes a planet instance as a parameter and performs some operation on it. **The best plugins do one tiny thing.** If you want a plugin to do a lot of things at once, you should build a plugin that wraps other, smaller plugins; in fact, this is exactly how the `earth` plugin is built. See the [Earth Plugin documentation](/documentation/builtin_earth.html) for more details.
|
A plugin is simply a JavaScript function that takes a planet instance as a parameter and performs some predefined operation. **The best plugins do one tiny thing.** If you want a plugin to do a lot of things at once, you should build a plugin that wraps other, smaller plugins; in fact, this is exactly how the `earth` plugin is built. See the [Earth Plugin](/documentation/builtin_earth.html) documentation for more details.
|
||||||
|
|
||||||
Most of the time, a plugin will implement its behavior by registering callbacks into a planet's lifecycle hooks. For example, the following simple plugin increments the planet's projection's rotation by one degree every tick (this would make for a very fast spinning globe, but demonstrates the idea nicely enough):
|
Most of the time, a plugin will implement its behavior by registering callbacks into the planet's lifecycle hooks. For example, the following simple plugin increments the planet's projection's rotation by one degree every tick (this would make for a very fast spinning globe, but demonstrates the idea nicely enough):
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -32,12 +32,12 @@ planet.loadPlugin(autorotate);
|
|||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Configurable Plugins
|
Plugin Generators
|
||||||
--------------------
|
-----------------
|
||||||
|
|
||||||
Often, you'll want your plugin to be configurable with some user-defined values. In this case, you can create a higher-order function, which takes your configuration data and then *returns* the plugin function. You can then call this function to generate the plugin for use by `loadPlugin`.
|
Often, you'll want your plugin to be configurable with some user-defined values. You can create a function generator, which is a function that takes your configuration data and then *returns* the plugin function. You can then call this generator to generate the plugin function for use by `loadPlugin`.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -61,7 +61,7 @@ Setting Yourself Up
|
|||||||
|
|
||||||
If you need to do some work before your plugin is ready to be used, you can add a hook to a planet's `onInit` hook to do the necessary setup.
|
If you need to do some work before your plugin is ready to be used, you can add a hook to a planet's `onInit` hook to do the necessary setup.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -73,9 +73,9 @@ var somePlugin = function(planet) {
|
|||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
If you need to do some asynchronous setup--such as fetching data with an Ajax request--before your plugin is ready, you can accept an argument to your `onInit` function. This argument is a function that tells Planetary.js when you're done setting up; simply call this function after your asynchronous operations are complete and Planetary.js will continue to initialize the planet. **If you accept the parameter but don't call it, the initialization process will stop** (and your planet will not work).
|
If you need to do some asynchronous setup--such as fetching data with an Ajax request--before your plugin is ready, you can accept an argument to your `onInit` function. When you're done setting up, call this function and Planetary.js will continue to initialize the planet. **If you accept the parameter but don't call it, the initialization process will stop** (and your planet will not work).
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -94,7 +94,7 @@ Drawing on the Canvas
|
|||||||
|
|
||||||
Many plugins will want to draw onto the globe's canvas; you can do so by registering a function to a planet's `onDraw` hook.
|
Many plugins will want to draw onto the globe's canvas; you can do so by registering a function to a planet's `onDraw` hook.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -111,15 +111,15 @@ var somePlugin = function(planet) {
|
|||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
The planet exposes properties and methods, such as `context`, `path`, and `withSavedContext` to assist with drawing to the canvas. The [Planet API documentation](/documentation/planet.html) goes into more detail on individual properties.
|
The planet exposes properties and methods, such as `context`, `path`, and `withSavedContext` to assist with drawing to the canvas. The [Planet API](/documentation/planet.html) documentation goes into more detail on individual properties.
|
||||||
|
|
||||||
### Drawing Geo Paths
|
### Drawing Geo Paths
|
||||||
|
|
||||||
As explained in the `planet.path` documentation on the [Planet API page](/documentation/planet.html), `planet.path` is a [`d3.geo.path`](https://github.com/mbostock/d3/wiki/Geo-Paths) object that can be used to draw geographical geometry onto the canvas. The path will take care of transforming the coordinates to be projected onto the orthographic view of the globe.
|
As explained in the `planet.path` documentation on the [Planet API](/documentation/planet.html) page, `planet.path` is a [`d3.geo.path`](https://github.com/mbostock/d3/wiki/Geo-Paths) object that can be used to draw geographical geometry onto the canvas. The path will take care of transforming the coordinates to be projected onto the orthographic view of the globe.
|
||||||
|
|
||||||
As a demonstration of this technique, the following is a plugin that will take the land data from a TopoJSON data source (stored on `planet.plugins.topojson.world`), convert it to a GeoJSON feature, and draw it on the planet. This code is similar to (but slightly simplified from) the [Land plugin's](/documentation/builtin_land.html) implementation.
|
As a demonstration of this technique, the following is a plugin that will take the land data from a TopoJSON data source (stored on `planet.plugins.topojson.world`), convert it to a GeoJSON feature, and draw it on the planet. This code is similar to (but slightly simplified from) how the [Land plugin](/documentation/builtin_land.html) works.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -142,9 +142,9 @@ var drawLand = function(planet) {
|
|||||||
Exposing Data and Methods
|
Exposing Data and Methods
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
Obviously, you can use private internal variables to keep track of any data your plugin needs in order to operate. However, if you want to expose a public API to users of your plugin, you should avoid attaching them directly to the planet and instead attach them to the planet's `plugins` namespace. You should use a name specific to your plugin, and this name should be well documented in your plugin's documentation.
|
Obviously, you can use private internal variables to keep track of any data your plugin needs to operate. However, if you want to expose a public API to users of your plugin, you should avoid attaching them directly to the planet and instead attach them to the planet's `plugins` namespace. You should use a name specific to your plugin, and this name should be well documented in your plugin's documentation.
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -152,8 +152,6 @@ var autorotate = function(degreesPerTick) {
|
|||||||
return function(planet) {
|
return function(planet) {
|
||||||
var paused = false;
|
var paused = false;
|
||||||
|
|
||||||
// Attach our public API to `planet.plugins`
|
|
||||||
// on the `autorotate` namespace.
|
|
||||||
planet.plugins.autorotate = {
|
planet.plugins.autorotate = {
|
||||||
pause: function() { paused = true; },
|
pause: function() { paused = true; },
|
||||||
resume: function() { paused = false; }
|
resume: function() { paused = false; }
|
||||||
@ -184,6 +182,6 @@ Best Practices
|
|||||||
There are a few things you can do to make your plugin all it can be:
|
There are a few things you can do to make your plugin all it can be:
|
||||||
|
|
||||||
1. Make your plugin very small; ideally, it should do only *one thing* very well. Be extremely liberal with splitting plugins into smaller plugins, which makes them easier to understand, test, and compose. It's easy to say "this plugin renders the Earth," but it really renders oceans, land masses, and borders.
|
1. Make your plugin very small; ideally, it should do only *one thing* very well. Be extremely liberal with splitting plugins into smaller plugins, which makes them easier to understand, test, and compose. It's easy to say "this plugin renders the Earth," but it really renders oceans, land masses, and borders.
|
||||||
2. Use higher-order functions to generate your plugin (as described above in "Plugin Generators") instead of passing function references to `loadPlugin` directly, even if your plugin doesn't take any configuration options. It makes for a more consistent API, and allows you to more easily add the ability to specify configuration options in the future.
|
2. Use function generators to generate your plugin (as described above in "Plugin Generators"), even if it doesn't take any configuration options. It makes for a more consistent API, and allows you to add the ability to specify configuration options in the future without changing the base API.
|
||||||
3. Make configuration optional if at all possible. Write your plugin so that it checks for missing values and uses sensible defaults.
|
3. Make configuration optional if at all possible. Write your plugin so that it checks for missing values and uses sensible defaults.
|
||||||
4. Only publish public data and API methods to `planet.plugins.pluginName`, where `pluginName` is the name of your plugin.
|
4. Only publish public data and API methods to `planet.plugins.pluginName`, where `pluginName` is the name of your plugin.
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"stable": {
|
|
||||||
"latest": {
|
|
||||||
"version": "v1.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"unstable": {
|
|
||||||
"latest": {
|
|
||||||
"version": "v1.0.0-rc.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<%- partial("../_header") %>
|
|
||||||
<link href="/css/prism.css" rel="stylesheet">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%- partial("../_menu") %>
|
|
||||||
|
|
||||||
<div class='content container'>
|
|
||||||
<div class='page ui slim stackable grid'>
|
|
||||||
<div class='sixteen wide column'>
|
|
||||||
<%- yield %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<%- partial("../_ga") %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,99 +0,0 @@
|
|||||||
<% data = public.download._data %>
|
|
||||||
<% dl = function(version, file) { %>
|
|
||||||
<% return "https://github.com/BinaryMuse/planetary.js/releases/download/" + version + "/" + file; %>
|
|
||||||
<% } %>
|
|
||||||
|
|
||||||
<h1><i class='icon download disk'></i> Download Planetary.js</h1>
|
|
||||||
|
|
||||||
<p>Download the core Planetary.js library and supporting files here.</p>
|
|
||||||
|
|
||||||
<p>Up-to-the-minute releases, archived versions, and full release notes can be found <a href='https://github.com/BinaryMuse/planetary.js/releases'>on the GitHub releases page</a>.</p>
|
|
||||||
|
|
||||||
<% if (data.stable.latest) { %>
|
|
||||||
<h2>Latest Stable Build: <%= data.stable.latest.version %></h2>
|
|
||||||
<p><a href="https://github.com/BinaryMuse/planetary.js/releases/tag/<%= data.stable.latest.version %>">Release notes</a>
|
|
||||||
|
|
|
||||||
<a href="https://github.com/BinaryMuse/planetary.js/tree/<%= data.stable.latest.version %>">GitHub tag</a></p>
|
|
||||||
|
|
||||||
<div class='ui list download-list'>
|
|
||||||
<div class='item'>
|
|
||||||
<i class='icon download'></i>
|
|
||||||
Core library: [
|
|
||||||
<a href='<%= dl(data.stable.latest.version, 'planetaryjs.min.js') %>'>minified</a>
|
|
||||||
|
|
|
||||||
<a href='<%= dl(data.stable.latest.version, 'planetaryjs.js') %>'>unminified</a>
|
|
||||||
]
|
|
||||||
</div>
|
|
||||||
<div class='item'>
|
|
||||||
<i class='icon download'></i>
|
|
||||||
Core library (no plugins): [
|
|
||||||
<a href='<%= dl(data.stable.latest.version, 'planetaryjs-noplugins.min.js') %>'>minified</a>
|
|
||||||
|
|
|
||||||
<a href='<%= dl(data.stable.latest.version, 'planetaryjs-noplugins.js') %>'>unminified</a>
|
|
||||||
]
|
|
||||||
</div>
|
|
||||||
<div class='item'>
|
|
||||||
<i class='icon globe'></i>
|
|
||||||
Earth TopoJSON data ("land" and "countries" objects): [
|
|
||||||
<a href='<%= dl(data.stable.latest.version, 'world-110m.json') %>'>download</a>
|
|
||||||
]
|
|
||||||
</div>
|
|
||||||
<div class='item'>
|
|
||||||
<i class='icon code'></i>
|
|
||||||
Source code [
|
|
||||||
<a href='https://github.com/BinaryMuse/planetary.js/archive/<%= data.stable.latest.version %>.zip'>.zip</a>
|
|
||||||
|
|
|
||||||
<a href='https://github.com/BinaryMuse/planetary.js/archive/<%= data.stable.latest.version %>.tar.gz'>.tar.gz</a>
|
|
||||||
]
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<% } else { %>
|
|
||||||
<h2>No stable builds yet</h2>
|
|
||||||
<% } %>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<% if (data.unstable.latest) { %>
|
|
||||||
<h2>Latest Unstable Build: <%= data.unstable.latest.version %></h2>
|
|
||||||
<p><a href="https://github.com/BinaryMuse/planetary.js/releases/tag/<%= data.unstable.latest.version %>">Release notes</a>
|
|
||||||
|
|
|
||||||
<a href="https://github.com/BinaryMuse/planetary.js/tree/<%= data.unstable.latest.version %>">GitHub tag</a></p>
|
|
||||||
|
|
||||||
<div class='ui list download-list'>
|
|
||||||
<div class='item'>
|
|
||||||
<i class='icon download'></i>
|
|
||||||
Core library: [
|
|
||||||
<a href='<%= dl(data.unstable.latest.version, 'planetaryjs.min.js') %>'>minified</a>
|
|
||||||
|
|
|
||||||
<a href='<%= dl(data.unstable.latest.version, 'planetaryjs.js') %>'>unminified</a>
|
|
||||||
]
|
|
||||||
</div>
|
|
||||||
<div class='item'>
|
|
||||||
<i class='icon download'></i>
|
|
||||||
Core library (no plugins): [
|
|
||||||
<a href='<%= dl(data.unstable.latest.version, 'planetaryjs-noplugins.min.js') %>'>minified</a>
|
|
||||||
|
|
|
||||||
<a href='<%= dl(data.unstable.latest.version, 'planetaryjs-noplugins.js') %>'>unminified</a>
|
|
||||||
]
|
|
||||||
</div>
|
|
||||||
<div class='item'>
|
|
||||||
<i class='icon globe'></i>
|
|
||||||
Earth TopoJSON data ("land" and "countries" objects): [
|
|
||||||
<a href='<%= dl(data.unstable.latest.version, 'world-110m.json') %>'>download</a>
|
|
||||||
]
|
|
||||||
</div>
|
|
||||||
<div class='item'>
|
|
||||||
<i class='icon code'></i>
|
|
||||||
Source code [
|
|
||||||
<a href='https://github.com/BinaryMuse/planetary.js/archive/<%= data.unstable.latest.version %>.zip'>.zip</a>
|
|
||||||
|
|
|
||||||
<a href='https://github.com/BinaryMuse/planetary.js/archive/<%= data.unstable.latest.version %>.tar.gz'>.tar.gz</a>
|
|
||||||
]
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<% } else { %>
|
|
||||||
<h2>No unstable builds yet</h2>
|
|
||||||
<% } %>
|
|
||||||
@ -15,6 +15,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type='text/javascript' src='/js/prism.js'></script>
|
<script type='text/javascript' src='/js/prism.js'></script>
|
||||||
<%- partial("../_ga") %>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -1,2 +0,0 @@
|
|||||||
<%- partial('../_scripts') %>
|
|
||||||
<script type='text/javascript' src='/examples/basic.js'></script>
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
<%- partial('../_scripts') %>
|
|
||||||
<script type='text/javascript' src='/examples/rotating.js'></script>
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
<div class="ui breadcrumb">
|
|
||||||
<a href='/examples/' class="section">Examples</a>
|
|
||||||
<i class="right arrow icon divider"></i>
|
|
||||||
<div class="active section">Basic Globe</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h1>Basic Globe</h1>
|
|
||||||
|
|
||||||
<p>This example shows the minimum code you need to render a basic representation of the planet Earth.</p>
|
|
||||||
|
|
||||||
<div style='text-align: center;'>
|
|
||||||
<canvas id='basicGlobe' width='400' height='400'></canvas>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
|
||||||
<div class='ui blue ribbon label'>HTML</div>
|
|
||||||
<pre class='line-numbers'><code class='language-html'><canvas id='basicGlobe' width='400' height='400'></canvas></code></pre>
|
|
||||||
|
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
|
||||||
<pre class='line-numbers'><code class='language-javascript'>(function() {
|
|
||||||
var canvas = document.getElementById('basicGlobe');
|
|
||||||
var planet = planetaryjs.planet();
|
|
||||||
// Loading this plugin technically happens automatically,
|
|
||||||
// but we need to specify the path to the `world-110m.json` file.
|
|
||||||
planet.loadPlugin(planetaryjs.plugins.earth({
|
|
||||||
topojson: { file: '/world-110m.json' }
|
|
||||||
}));
|
|
||||||
// Scale the planet's radius to half the canvas' size
|
|
||||||
// and move it to the center of the canvas.
|
|
||||||
planet.projection
|
|
||||||
.scale(canvas.width / 2)
|
|
||||||
.translate([canvas.width / 2, canvas.height / 2]);
|
|
||||||
planet.draw(canvas);
|
|
||||||
})();</code></pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%- partial('_scripts_basic') %>
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
(function() {
|
|
||||||
var canvas = document.getElementById('basicGlobe');
|
|
||||||
var planet = planetaryjs.planet();
|
|
||||||
// Loading this plugin technically happens automatically,
|
|
||||||
// but we need to specify the path to the `world-110m.json` file.
|
|
||||||
planet.loadPlugin(planetaryjs.plugins.earth({
|
|
||||||
topojson: { file: '/world-110m.json' }
|
|
||||||
}));
|
|
||||||
// Scale the planet's radius to half the canvas' size
|
|
||||||
// and move it to the center of the canvas.
|
|
||||||
planet.projection
|
|
||||||
.scale(canvas.width / 2)
|
|
||||||
.translate([canvas.width / 2, canvas.height / 2]);
|
|
||||||
planet.draw(canvas);
|
|
||||||
})();
|
|
||||||
@ -2,34 +2,34 @@
|
|||||||
|
|
||||||
<p>Sometimes you just need to see some code to get an idea started; here are a few examples of what you can build with Planetary.js.</p>
|
<p>Sometimes you just need to see some code to get an idea started; here are a few examples of what you can build with Planetary.js.</p>
|
||||||
|
|
||||||
<div class='ui top attached segment example-segment'>
|
<div class='ui three connected items examples'>
|
||||||
<div>
|
<div class='row'>
|
||||||
<a href='/examples/basic.html'><img src='/images/ex-basic.png'></a>
|
<a class='item' href='/examples/basic.html'>
|
||||||
<a href='/examples/basic.html'><h2><i class='icon black globe'></i>Basic Globe</h2></a>
|
<div class='content'>
|
||||||
<p>It doesn't get any simpler than this: just a static globe, built using built-in plugins with nothing up our sleeves!</p>
|
<div class='name'>Basic Globe</div>
|
||||||
<span class='ui red horizontal label'>plugins: earth</span>
|
<p class='description'>It doesn't get any simpler than this:
|
||||||
<span class='ui purple horizontal label'>d3: projections</span>
|
just a static globe using built-in plugins and nothing
|
||||||
</div>
|
up our sleeves!</p>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
<div class='ui attached segment example-segment'>
|
<a class='item' href='/examples/rotating.html'>
|
||||||
<div>
|
<div class='content'>
|
||||||
<a href='/examples/rotating.html'><img src='/images/ex-rotating.png'></a>
|
<div class='name'>Rotating Globe</div>
|
||||||
<a href='/examples/rotating.html'><h2><i class='icon black basic desk globe'></i>Rotating Globe with Pings</h2></a>
|
<p class='description'>If there's one thing that's better than
|
||||||
<p>If there's one thing that's better than a globe, it's a globe that rotates. This is the demo from the homepage of Planetaryjs.com, and so includes a custom auto-rotation plugin and zoom/drag integration.</p>
|
a globe, it's a globe that rotates. This is the demo from the
|
||||||
<span class='ui red horizontal label'>plugins: earth, pings, drag, zoom</span>
|
homepage of Planetaryjs.com, and so includes a custom
|
||||||
<span class='ui teal horizontal label'>custom plugins</span>
|
auto-rotation plugin and zoom/drag integration.</p>
|
||||||
<span class='ui purple horizontal label'>d3: projections</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
<div class='ui bottom attached segment example-segment'>
|
<a class='item' href='/examples/quake.html'>
|
||||||
<div>
|
<div class='content'>
|
||||||
<a href='/examples/quake.html'><img src='/images/ex-quake.png'></a>
|
<div class='name'>Earthquake Data</div>
|
||||||
<a href='/examples/quake.html'><h2><i class='icon black bullseye'></i>2013 Seismic Activity Visualization</h2></a>
|
<p class='description'>A visualization of 2013 seismic activity.
|
||||||
<p>A visualization of 2013 seismic activity. This demo shows the use of multiple custom plugins, D3 scales, fetching third party data, and DOM updates via D3.</p>
|
This demo shows the use of multiple custom plugins, D3
|
||||||
<span class='ui red horizontal label'>plugins: earth, pings, drag, zoom</span>
|
scales, fetching third party data, and DOM updates via D3.</p>
|
||||||
<span class='ui teal horizontal label'>custom plugins</span>
|
</div>
|
||||||
<span class='ui purple horizontal label'>d3: projections, scales, selections, events, external data</span>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,25 +1,18 @@
|
|||||||
<div class="ui breadcrumb">
|
<h1>2013 Earthquake Data</h1>
|
||||||
<a href='/examples/' class="section">Examples</a>
|
|
||||||
<i class="right arrow icon divider"></i>
|
|
||||||
<div class="active section">2013 Seismic Activity Visualization</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h1>2013 Seismic Activity Visualization</h1>
|
<p>This is a more advanced example of what can be built with Planetary.js. The demo sets up a globe with some custom plugins (defined at the bottom of the JavaScript), and also demonstrates some non-Planetary.js-specific techniques, like D3 scales, DOM manipulation, and loading external data.</p>
|
||||||
|
|
||||||
<p>This is a more advanced example of what you can build with Planetary.js. The demo sets up a globe with some custom plugins (defined at the bottom of the JavaScript), and also demonstrates some non-Planetary.js-specific techniques, like the use of <a href='http://momentjs.com/'>Moment.js</a>, D3 scales, DOM manipulation, and loading external data.</p>
|
<p><a href="/examples/quake/index.html">View the demo</a></p>
|
||||||
|
|
||||||
<h2><a href="/examples/quake/index.html"><i class='black icon play circle' style='text-decoration: none;'></i>View the demo</a></h2>
|
<div class='ui raise segment'>
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
|
||||||
<div class='ui blue ribbon label'>HTML</div>
|
<div class='ui blue ribbon label'>HTML</div>
|
||||||
<pre class='line-numbers'><code class='language-html'><h1>Earthquakes: 2013</h1>
|
<pre><code class='language-html'><canvas id='quakeCanvas'></canvas>
|
||||||
<ul id='magnitudes'></ul>
|
<h1>Earthquakes: 2013</h1>
|
||||||
|
<ul id='magnitues'></ul>
|
||||||
<canvas id='quakeCanvas'></canvas>
|
|
||||||
|
|
||||||
<div id='controls'>
|
<div id='controls'>
|
||||||
<div>
|
<div>
|
||||||
<input id='slider' type='range' min='0' max='100' step='0.1' value='0'>
|
<input id='slider' type='range' min='0' max='100' value='0'>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span id='date'></span>&nbsp;
|
<span id='date'></span>&nbsp;
|
||||||
@ -28,7 +21,7 @@
|
|||||||
|
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
<pre class='line-numbers'><code class='language-javascript'>(function() {
|
<pre><code class='language-javascript'>(function() {
|
||||||
var canvas = document.getElementById('quakeCanvas');
|
var canvas = document.getElementById('quakeCanvas');
|
||||||
|
|
||||||
// Create our Planetary.js planet and set some initial values;
|
// Create our Planetary.js planet and set some initial values;
|
||||||
@ -42,16 +35,14 @@
|
|||||||
land: { fill: '#06304e' },
|
land: { fill: '#06304e' },
|
||||||
borders: { stroke: '#001320' }
|
borders: { stroke: '#001320' }
|
||||||
}));
|
}));
|
||||||
planet.loadPlugin(planetaryjs.plugins.pings());
|
planet.loadPlugin(planetaryjs.plugins.pings({}));
|
||||||
planet.loadPlugin(planetaryjs.plugins.zoom({
|
planet.loadPlugin(zoom());
|
||||||
scaleExtent: [50, 5000]
|
planet.loadPlugin(drag({
|
||||||
}));
|
|
||||||
planet.loadPlugin(planetaryjs.plugins.drag({
|
|
||||||
onDragStart: function() {
|
onDragStart: function() {
|
||||||
this.plugins.autorotate.pause();
|
planet.plugins.autorotate.pause();
|
||||||
},
|
},
|
||||||
onDragEnd: function() {
|
onDragEnd: function() {
|
||||||
this.plugins.autorotate.resume();
|
planet.plugins.autorotate.resume();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
planet.loadPlugin(autorotate(5));
|
planet.loadPlugin(autorotate(5));
|
||||||
@ -60,24 +51,21 @@
|
|||||||
|
|
||||||
|
|
||||||
// Create a color scale for the various earthquake magnitudes; the
|
// Create a color scale for the various earthquake magnitudes; the
|
||||||
// minimum magnitude in our data set is 2.5.
|
// mininum magnitude in our data set is 2.5.
|
||||||
var colors = d3.scale.pow()
|
var colors = d3.scale.pow()
|
||||||
.exponent(3)
|
.exponent(2)
|
||||||
.domain([2, 4, 6, 8, 10])
|
.domain([2, 6,10])
|
||||||
.range(['white', 'yellow', 'orange', 'red', 'purple']);
|
.range(['rgb(255,255,204)', 'rgb(253,141,60)','rgb(128,0,38)'])
|
||||||
// Also create a scale for mapping magnitudes to ping angle sizes
|
.clamp(true);
|
||||||
|
// Also create a scale for mapping magnitues to ping angle sizes
|
||||||
var angles = d3.scale.pow()
|
var angles = d3.scale.pow()
|
||||||
.exponent(3)
|
.exponent(2)
|
||||||
.domain([2.5, 10])
|
.domain([2.5, 10])
|
||||||
.range([0.5, 15]);
|
.range([0.5, 15])
|
||||||
// And finally, a scale for mapping magnitudes to ping TTLs
|
.clamp(true);
|
||||||
var ttls = d3.scale.pow()
|
|
||||||
.exponent(3)
|
|
||||||
.domain([2.5, 10])
|
|
||||||
.range([2000, 5000]);
|
|
||||||
|
|
||||||
// Create a key to show the magnitudes and their colors
|
// Create a key to show the magnitues and their colors
|
||||||
d3.select('#magnitudes').selectAll('li')
|
d3.select('#magnitues').selectAll('li')
|
||||||
.data(colors.ticks(9))
|
.data(colors.ticks(9))
|
||||||
.enter()
|
.enter()
|
||||||
.append('li')
|
.append('li')
|
||||||
@ -107,10 +95,6 @@
|
|||||||
var currentTime = start;
|
var currentTime = start;
|
||||||
var lastTick = new Date().getTime();
|
var lastTick = new Date().getTime();
|
||||||
|
|
||||||
var updateDate = function() {
|
|
||||||
d3.select('#date').text(moment(currentTime).utc().format("MMM DD YYYY HH:mm UTC"));
|
|
||||||
};
|
|
||||||
|
|
||||||
// A scale that maps a percentage of playback to a time
|
// A scale that maps a percentage of playback to a time
|
||||||
// from the data; for example, `50` would map to the halfway
|
// from the data; for example, `50` would map to the halfway
|
||||||
// mark between the first and last items in our data array.
|
// mark between the first and last items in our data array.
|
||||||
@ -132,7 +116,7 @@
|
|||||||
d3.select('#slider')
|
d3.select('#slider')
|
||||||
.on('change', function(d) {
|
.on('change', function(d) {
|
||||||
currentTime = percentToDate(d3.event.target.value);
|
currentTime = percentToDate(d3.event.target.value);
|
||||||
updateDate();
|
d3.select('#date').text(new Date(currentTime));
|
||||||
})
|
})
|
||||||
.call(d3.behavior.drag()
|
.call(d3.behavior.drag()
|
||||||
.on('dragstart', function() {
|
.on('dragstart', function() {
|
||||||
@ -169,18 +153,17 @@
|
|||||||
|
|
||||||
for (var i = 0; i < toPing.length; i++) {
|
for (var i = 0; i < toPing.length; i++) {
|
||||||
var ping = toPing[i];
|
var ping = toPing[i];
|
||||||
planet.plugins.pings.add(ping.lng, ping.lat, {
|
planet.plugins.pings.add(ping.lat, ping.lng, {
|
||||||
// Here we use the `angles` and `colors` scales we built earlier
|
// Here we use the `angles` and `colors` scales we built earlier
|
||||||
// to convert magnitudes to appropriate angles and colors.
|
// to convert magnitudes to appropriate angles and colors.
|
||||||
angle: angles(ping.mag),
|
angle: angles(ping.mag),
|
||||||
color: colors(ping.mag),
|
color: colors(ping.mag)
|
||||||
ttl: ttls(ping.mag)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
currentTime += dataDelta;
|
currentTime += dataDelta;
|
||||||
if (currentTime > end) currentTime = start;
|
if (currentTime > end) currentTime = start;
|
||||||
updateDate();
|
d3.select('#date').text(new Date(currentTime));
|
||||||
d3.select('#slider').property('value', percentToDate.invert(currentTime));
|
d3.select('#slider').property('value', percentToDate.invert(currentTime));
|
||||||
lastTick = now;
|
lastTick = now;
|
||||||
});
|
});
|
||||||
@ -191,20 +174,16 @@
|
|||||||
// Plugin to resize the canvas to fill the window and to
|
// Plugin to resize the canvas to fill the window and to
|
||||||
// automatically center the planet when the window size changes
|
// automatically center the planet when the window size changes
|
||||||
function autocenter(options) {
|
function autocenter(options) {
|
||||||
options = options || {};
|
|
||||||
var needsCentering = false;
|
var needsCentering = false;
|
||||||
var globe = null;
|
|
||||||
|
|
||||||
var resize = function() {
|
var resize = function() {
|
||||||
var width = window.innerWidth + (options.extraWidth || 0);
|
var width = window.innerWidth + (options.extraWidth || 0);
|
||||||
var height = window.innerHeight + (options.extraHeight || 0);
|
var height = window.innerHeight + (options.extraHeight || 0);
|
||||||
globe.canvas.width = width;
|
planet.canvas.width = width;
|
||||||
globe.canvas.height = height;
|
planet.canvas.height = height;
|
||||||
globe.projection.translate([width / 2, height / 2]);
|
planet.projection.translate([width / 2, height / 2]);
|
||||||
};
|
};
|
||||||
|
|
||||||
return function(planet) {
|
return function(planet) {
|
||||||
globe = planet;
|
|
||||||
planet.onInit(function() {
|
planet.onInit(function() {
|
||||||
needsCentering = true;
|
needsCentering = true;
|
||||||
d3.select(window).on('resize', function() {
|
d3.select(window).on('resize', function() {
|
||||||
@ -221,7 +200,6 @@
|
|||||||
// Plugin to automatically scale the planet's projection based
|
// Plugin to automatically scale the planet's projection based
|
||||||
// on the window size when the planet is initialized
|
// on the window size when the planet is initialized
|
||||||
function autoscale(options) {
|
function autoscale(options) {
|
||||||
options = options || {};
|
|
||||||
return function(planet) {
|
return function(planet) {
|
||||||
planet.onInit(function() {
|
planet.onInit(function() {
|
||||||
var width = window.innerWidth + (options.extraWidth || 0);
|
var width = window.innerWidth + (options.extraWidth || 0);
|
||||||
@ -256,5 +234,57 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Plugin to allow zooming with the mouse wheel
|
||||||
|
function zoom(options) {
|
||||||
|
return function(planet) {
|
||||||
|
planet.onInit(function() {
|
||||||
|
var zoom = d3.behavior.zoom()
|
||||||
|
.scale(planet.projection.scale())
|
||||||
|
.scaleExtent([50, 5000])
|
||||||
|
.on('zoom', function() {
|
||||||
|
planet.projection.scale(d3.event.scale);
|
||||||
|
});
|
||||||
|
d3.select(planet.canvas).call(zoom);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Plugin to allow rotating the globe by dragging with the mouse
|
||||||
|
function drag(options) {
|
||||||
|
var options = options || {};
|
||||||
|
var noop = function() {};
|
||||||
|
var onDragStart = options.onDragStart || noop;
|
||||||
|
var onDragEnd = options.onDragEnd || noop;
|
||||||
|
var onDrag = options.onDrag || noop;
|
||||||
|
return function(planet) {
|
||||||
|
planet.onInit(function() {
|
||||||
|
var drag = d3.behavior.drag()
|
||||||
|
.on('dragstart', onDragStart)
|
||||||
|
.on('dragend', onDragEnd)
|
||||||
|
.on('drag', function() {
|
||||||
|
onDrag();
|
||||||
|
var dx = d3.event.dx;
|
||||||
|
var dy = d3.event.dy;
|
||||||
|
var rotation = planet.projection.rotate();
|
||||||
|
var radius = planet.projection.scale();
|
||||||
|
// Dragging from the center of the planet to the edge
|
||||||
|
// of the planet should rotate it 90 degrees
|
||||||
|
var scale = d3.scale.linear()
|
||||||
|
.domain([-1 * radius, radius])
|
||||||
|
.range([-90, 90]);
|
||||||
|
var degX = scale(dx);
|
||||||
|
var degY = scale(dy);
|
||||||
|
rotation[0] += degX;
|
||||||
|
rotation[1] -= degY;
|
||||||
|
if (rotation[1] > 90) rotation[1] = 90;
|
||||||
|
if (rotation[1] < -90) rotation[1] = -90;
|
||||||
|
if (rotation[0] >= 180) rotation[0] -= 360;
|
||||||
|
planet.projection.rotate(rotation);
|
||||||
|
});
|
||||||
|
d3.select(planet.canvas).call(drag);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
})();</code></pre>
|
})();</code></pre>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -10,14 +10,13 @@
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul#magnitudes {
|
ul#magnitues {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 100px;
|
top: 100px;
|
||||||
left: 30px;
|
left: 30px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
z-index: 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
@ -26,7 +25,6 @@
|
|||||||
left: 5px;
|
left: 5px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
z-index: 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas {
|
canvas {
|
||||||
@ -34,7 +32,7 @@
|
|||||||
top: 60px;
|
top: 60px;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0px;
|
bottom: 0;
|
||||||
cursor: move;
|
cursor: move;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,10 +44,6 @@
|
|||||||
margin-left: -200px;
|
margin-left: -200px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=range] {
|
|
||||||
width: 400px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -58,8 +52,7 @@
|
|||||||
<%- yield %>
|
<%- yield %>
|
||||||
|
|
||||||
<%- partial("../../_scripts") %>
|
<%- partial("../../_scripts") %>
|
||||||
<script type='text/javascript' src='/js/lib/moment.min.js'></script>
|
|
||||||
<script type='text/javascript' src='/examples/quake/quake.js'></script>
|
<script type='text/javascript' src='/examples/quake/quake.js'></script>
|
||||||
<%- partial("../../_ga") %>
|
<script type='text/javascript' src='/js/prism.js'></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
<h1>Earthquakes: 2013</h1>
|
|
||||||
<ul id='magnitudes'></ul>
|
|
||||||
|
|
||||||
<canvas id='quakeCanvas'></canvas>
|
<canvas id='quakeCanvas'></canvas>
|
||||||
|
<h1>Earthquakes: 2013</h1>
|
||||||
|
<ul id='magnitues'></ul>
|
||||||
|
|
||||||
<div id='controls'>
|
<div id='controls'>
|
||||||
<div>
|
<div>
|
||||||
<input id='slider' type='range' min='0' max='100' step='0.1' value='0'>
|
<input id='slider' type='range' min='0' max='100' value='0'>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span id='date'>Loading...</span>
|
<span id='date'></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
var fs = require('fs');
|
|
||||||
|
|
||||||
var filename = process.argv[2];
|
|
||||||
|
|
||||||
if (!filename) {
|
|
||||||
console.log("Please specify a file to process");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fs.existsSync(filename)) {
|
|
||||||
console.log("#{filename} not found.");
|
|
||||||
process.exit(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = fs.readFileSync(filename, 'utf8');
|
|
||||||
var json = JSON.parse(data);
|
|
||||||
|
|
||||||
var quakeData = json.features.map(function(feature) {
|
|
||||||
return {
|
|
||||||
time: feature.properties.time,
|
|
||||||
lat: feature.geometry.coordinates[1],
|
|
||||||
lng: feature.geometry.coordinates[0],
|
|
||||||
mag: feature.properties.mag
|
|
||||||
};
|
|
||||||
}).sort(function(a, b) { return a.time - b.time});
|
|
||||||
|
|
||||||
console.log(JSON.stringify(quakeData));
|
|
||||||
@ -12,16 +12,16 @@
|
|||||||
land: { fill: '#06304e' },
|
land: { fill: '#06304e' },
|
||||||
borders: { stroke: '#001320' }
|
borders: { stroke: '#001320' }
|
||||||
}));
|
}));
|
||||||
planet.loadPlugin(planetaryjs.plugins.pings());
|
planet.loadPlugin(planetaryjs.plugins.pings({}));
|
||||||
planet.loadPlugin(planetaryjs.plugins.zoom({
|
planet.loadPlugin(planetaryjs.plugins.zoom({
|
||||||
scaleExtent: [50, 5000]
|
scaleExtent: [50, 5000]
|
||||||
}));
|
}));
|
||||||
planet.loadPlugin(planetaryjs.plugins.drag({
|
planet.loadPlugin(planetaryjs.plugins.drag({
|
||||||
onDragStart: function() {
|
onDragStart: function() {
|
||||||
this.plugins.autorotate.pause();
|
planet.plugins.autorotate.pause();
|
||||||
},
|
},
|
||||||
onDragEnd: function() {
|
onDragEnd: function() {
|
||||||
this.plugins.autorotate.resume();
|
planet.plugins.autorotate.resume();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
planet.loadPlugin(autorotate(5));
|
planet.loadPlugin(autorotate(5));
|
||||||
@ -30,24 +30,21 @@
|
|||||||
|
|
||||||
|
|
||||||
// Create a color scale for the various earthquake magnitudes; the
|
// Create a color scale for the various earthquake magnitudes; the
|
||||||
// minimum magnitude in our data set is 2.5.
|
// mininum magnitude in our data set is 2.5.
|
||||||
var colors = d3.scale.pow()
|
var colors = d3.scale.pow()
|
||||||
.exponent(3)
|
.exponent(2)
|
||||||
.domain([2, 4, 6, 8, 10])
|
.domain([2, 6,10])
|
||||||
.range(['white', 'yellow', 'orange', 'red', 'purple']);
|
.range(['rgb(255,255,204)', 'rgb(253,141,60)','rgb(128,0,38)'])
|
||||||
// Also create a scale for mapping magnitudes to ping angle sizes
|
.clamp(true);
|
||||||
|
// Also create a scale for mapping magnitues to ping angle sizes
|
||||||
var angles = d3.scale.pow()
|
var angles = d3.scale.pow()
|
||||||
.exponent(3)
|
.exponent(2)
|
||||||
.domain([2.5, 10])
|
.domain([2.5, 10])
|
||||||
.range([0.5, 15]);
|
.range([0.5, 15])
|
||||||
// And finally, a scale for mapping magnitudes to ping TTLs
|
.clamp(true);
|
||||||
var ttls = d3.scale.pow()
|
|
||||||
.exponent(3)
|
|
||||||
.domain([2.5, 10])
|
|
||||||
.range([2000, 5000]);
|
|
||||||
|
|
||||||
// Create a key to show the magnitudes and their colors
|
// Create a key to show the magnitues and their colors
|
||||||
d3.select('#magnitudes').selectAll('li')
|
d3.select('#magnitues').selectAll('li')
|
||||||
.data(colors.ticks(9))
|
.data(colors.ticks(9))
|
||||||
.enter()
|
.enter()
|
||||||
.append('li')
|
.append('li')
|
||||||
@ -77,10 +74,6 @@
|
|||||||
var currentTime = start;
|
var currentTime = start;
|
||||||
var lastTick = new Date().getTime();
|
var lastTick = new Date().getTime();
|
||||||
|
|
||||||
var updateDate = function() {
|
|
||||||
d3.select('#date').text(moment(currentTime).utc().format("MMM DD YYYY HH:mm UTC"));
|
|
||||||
};
|
|
||||||
|
|
||||||
// A scale that maps a percentage of playback to a time
|
// A scale that maps a percentage of playback to a time
|
||||||
// from the data; for example, `50` would map to the halfway
|
// from the data; for example, `50` would map to the halfway
|
||||||
// mark between the first and last items in our data array.
|
// mark between the first and last items in our data array.
|
||||||
@ -102,7 +95,7 @@
|
|||||||
d3.select('#slider')
|
d3.select('#slider')
|
||||||
.on('change', function(d) {
|
.on('change', function(d) {
|
||||||
currentTime = percentToDate(d3.event.target.value);
|
currentTime = percentToDate(d3.event.target.value);
|
||||||
updateDate();
|
d3.select('#date').text(new Date(currentTime));
|
||||||
})
|
})
|
||||||
.call(d3.behavior.drag()
|
.call(d3.behavior.drag()
|
||||||
.on('dragstart', function() {
|
.on('dragstart', function() {
|
||||||
@ -139,18 +132,17 @@
|
|||||||
|
|
||||||
for (var i = 0; i < toPing.length; i++) {
|
for (var i = 0; i < toPing.length; i++) {
|
||||||
var ping = toPing[i];
|
var ping = toPing[i];
|
||||||
planet.plugins.pings.add(ping.lng, ping.lat, {
|
planet.plugins.pings.add(ping.lat, ping.lng, {
|
||||||
// Here we use the `angles` and `colors` scales we built earlier
|
// Here we use the `angles` and `colors` scales we built earlier
|
||||||
// to convert magnitudes to appropriate angles and colors.
|
// to convert magnitudes to appropriate angles and colors.
|
||||||
angle: angles(ping.mag),
|
angle: angles(ping.mag),
|
||||||
color: colors(ping.mag),
|
color: colors(ping.mag)
|
||||||
ttl: ttls(ping.mag)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
currentTime += dataDelta;
|
currentTime += dataDelta;
|
||||||
if (currentTime > end) currentTime = start;
|
if (currentTime > end) currentTime = start;
|
||||||
updateDate();
|
d3.select('#date').text(new Date(currentTime));
|
||||||
d3.select('#slider').property('value', percentToDate.invert(currentTime));
|
d3.select('#slider').property('value', percentToDate.invert(currentTime));
|
||||||
lastTick = now;
|
lastTick = now;
|
||||||
});
|
});
|
||||||
@ -161,20 +153,16 @@
|
|||||||
// Plugin to resize the canvas to fill the window and to
|
// Plugin to resize the canvas to fill the window and to
|
||||||
// automatically center the planet when the window size changes
|
// automatically center the planet when the window size changes
|
||||||
function autocenter(options) {
|
function autocenter(options) {
|
||||||
options = options || {};
|
|
||||||
var needsCentering = false;
|
var needsCentering = false;
|
||||||
var globe = null;
|
|
||||||
|
|
||||||
var resize = function() {
|
var resize = function() {
|
||||||
var width = window.innerWidth + (options.extraWidth || 0);
|
var width = window.innerWidth + (options.extraWidth || 0);
|
||||||
var height = window.innerHeight + (options.extraHeight || 0);
|
var height = window.innerHeight + (options.extraHeight || 0);
|
||||||
globe.canvas.width = width;
|
planet.canvas.width = width;
|
||||||
globe.canvas.height = height;
|
planet.canvas.height = height;
|
||||||
globe.projection.translate([width / 2, height / 2]);
|
planet.projection.translate([width / 2, height / 2]);
|
||||||
};
|
};
|
||||||
|
|
||||||
return function(planet) {
|
return function(planet) {
|
||||||
globe = planet;
|
|
||||||
planet.onInit(function() {
|
planet.onInit(function() {
|
||||||
needsCentering = true;
|
needsCentering = true;
|
||||||
d3.select(window).on('resize', function() {
|
d3.select(window).on('resize', function() {
|
||||||
@ -191,7 +179,6 @@
|
|||||||
// Plugin to automatically scale the planet's projection based
|
// Plugin to automatically scale the planet's projection based
|
||||||
// on the window size when the planet is initialized
|
// on the window size when the planet is initialized
|
||||||
function autoscale(options) {
|
function autoscale(options) {
|
||||||
options = options || {};
|
|
||||||
return function(planet) {
|
return function(planet) {
|
||||||
planet.onInit(function() {
|
planet.onInit(function() {
|
||||||
var width = window.innerWidth + (options.extraWidth || 0);
|
var width = window.innerWidth + (options.extraWidth || 0);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -1,145 +0,0 @@
|
|||||||
<div class="ui breadcrumb">
|
|
||||||
<a href='/examples/' class="section">Examples</a>
|
|
||||||
<i class="right arrow icon divider"></i>
|
|
||||||
<div class="active section">Rotating Globe with Pings</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h1>Rotating Globe with Pings</h1>
|
|
||||||
|
|
||||||
<p>This code shows the example from the homepage, which rotates, shows randomly positioned, colored, and sized pings on the globe, and supports mouse-based dragging and zooming. It also shows the creation and use of a plugin, which powers the automatic rotation and exposes a public API.</p>
|
|
||||||
|
|
||||||
<p>We're using a specially-made TopoJSON file that includes lake data so that we can draw lakes on the globe with a custom plugin, which you can find at the bottom of the JavaScript. The custom TopoJSON was made using the <a href='https://github.com/mbostock/topojson/wiki/Command-Line-Reference'>TopoJSON command-line tool</a> and data from <a href='http://www.naturalearthdata.com/features/'>Natural Earth</a>; you can also <a href='/world-110m-withlakes.json'>download the JSON file</a> for your own use.</p>
|
|
||||||
|
|
||||||
<p>The demo also shows how you can keep your globe from looking pixelated on high density displays by changing the canvas' width and height but keeping its <em>displayed</em> width and height the same via CSS styling.</p>
|
|
||||||
|
|
||||||
<div style='text-align: center;'>
|
|
||||||
<canvas id='rotatingGlobe' width='400' height='400'
|
|
||||||
style="width: 400px; height: 400px; cursor: move;"></canvas>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class='ui raised segment'>
|
|
||||||
<div class='ui blue ribbon label'>HTML</div>
|
|
||||||
<pre class='line-numbers'><code class='language-html'><canvas id='rotatingGlobe' width='400' height='400'
|
|
||||||
style='width: 400px; height: 400px; cursor: move;'></canvas></code></pre>
|
|
||||||
|
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
|
||||||
<pre class='line-numbers'><code class='language-javascript'>(function() {
|
|
||||||
var globe = planetaryjs.planet();
|
|
||||||
// Load our custom `autorotate` plugin; see below.
|
|
||||||
globe.loadPlugin(autorotate(10));
|
|
||||||
// The `earth` plugin draws the oceans and the land; it's actually
|
|
||||||
// a combination of several separate built-in plugins.
|
|
||||||
//
|
|
||||||
// Note that we're loading a special TopoJSON file
|
|
||||||
// (world-110m-withlakes.json) so we can render lakes.
|
|
||||||
globe.loadPlugin(planetaryjs.plugins.earth({
|
|
||||||
topojson: { file: '/world-110m-withlakes.json' },
|
|
||||||
oceans: { fill: '#000080' },
|
|
||||||
land: { fill: '#339966' },
|
|
||||||
borders: { stroke: '#008000' }
|
|
||||||
}));
|
|
||||||
// Load our custom `lakes` plugin to draw lakes; see below.
|
|
||||||
globe.loadPlugin(lakes({
|
|
||||||
fill: '#000080'
|
|
||||||
}));
|
|
||||||
// The `pings` plugin draws animated pings on the globe.
|
|
||||||
globe.loadPlugin(planetaryjs.plugins.pings());
|
|
||||||
// The `zoom` and `drag` plugins enable
|
|
||||||
// manipulating the globe with the mouse.
|
|
||||||
globe.loadPlugin(planetaryjs.plugins.zoom({
|
|
||||||
scaleExtent: [100, 300]
|
|
||||||
}));
|
|
||||||
globe.loadPlugin(planetaryjs.plugins.drag({
|
|
||||||
// Dragging the globe should pause the
|
|
||||||
// automatic rotation until we release the mouse.
|
|
||||||
onDragStart: function() {
|
|
||||||
this.plugins.autorotate.pause();
|
|
||||||
},
|
|
||||||
onDragEnd: function() {
|
|
||||||
this.plugins.autorotate.resume();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
// Set up the globe's initial scale, offset, and rotation.
|
|
||||||
globe.projection.scale(175).translate([175, 175]).rotate([0, -10, 0]);
|
|
||||||
|
|
||||||
// Every few hundred milliseconds, we'll draw another random ping.
|
|
||||||
var colors = ['red', 'yellow', 'white', 'orange', 'green', 'cyan', 'pink'];
|
|
||||||
setInterval(function() {
|
|
||||||
var lat = Math.random() * 170 - 85;
|
|
||||||
var lng = Math.random() * 360 - 180;
|
|
||||||
var color = colors[Math.floor(Math.random() * colors.length)];
|
|
||||||
globe.plugins.pings.add(lng, lat, { color: color, ttl: 2000, angle: Math.random() * 10 });
|
|
||||||
}, 150);
|
|
||||||
|
|
||||||
var canvas = document.getElementById('rotatingGlobe');
|
|
||||||
// Special code to handle high-density displays (e.g. retina, some phones)
|
|
||||||
// In the future, Planetary.js will handle this by itself (or via a plugin).
|
|
||||||
if (window.devicePixelRatio == 2) {
|
|
||||||
canvas.width = 800;
|
|
||||||
canvas.height = 800;
|
|
||||||
context = canvas.getContext('2d');
|
|
||||||
context.scale(2, 2);
|
|
||||||
}
|
|
||||||
// Draw that globe!
|
|
||||||
globe.draw(canvas);
|
|
||||||
|
|
||||||
// This plugin will automatically rotate the globe around its vertical
|
|
||||||
// axis a configured number of degrees every second.
|
|
||||||
function autorotate(degPerSec) {
|
|
||||||
// Planetary.js plugins are functions that take a `planet` instance
|
|
||||||
// as an argument...
|
|
||||||
return function(planet) {
|
|
||||||
var lastTick = null;
|
|
||||||
var paused = false;
|
|
||||||
planet.plugins.autorotate = {
|
|
||||||
pause: function() { paused = true; },
|
|
||||||
resume: function() { paused = false; }
|
|
||||||
};
|
|
||||||
// ...and configure hooks into certain pieces of its lifecycle.
|
|
||||||
planet.onDraw(function() {
|
|
||||||
if (paused || !lastTick) {
|
|
||||||
lastTick = new Date();
|
|
||||||
} else {
|
|
||||||
var now = new Date();
|
|
||||||
var delta = now - lastTick;
|
|
||||||
// This plugin uses the built-in projection (provided by D3)
|
|
||||||
// to rotate the globe each time we draw it.
|
|
||||||
var rotation = planet.projection.rotate();
|
|
||||||
rotation[0] += degPerSec * delta / 1000;
|
|
||||||
if (rotation[0] >= 180) rotation[0] -= 360;
|
|
||||||
planet.projection.rotate(rotation);
|
|
||||||
lastTick = now;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// This plugin takes lake data from the special
|
|
||||||
// TopoJSON we're loading and draws them on the map.
|
|
||||||
function lakes(options) {
|
|
||||||
options = options || {};
|
|
||||||
var lakes = null;
|
|
||||||
|
|
||||||
return function(planet) {
|
|
||||||
planet.onInit(function() {
|
|
||||||
// We can access the data loaded from the TopoJSON plugin
|
|
||||||
// on its namespace on `planet.plugins`. We're loading a custom
|
|
||||||
// TopoJSON file with an object called "ne_110m_lakes".
|
|
||||||
var world = planet.plugins.topojson.world;
|
|
||||||
lakes = topojson.feature(world, world.objects.ne_110m_lakes);
|
|
||||||
});
|
|
||||||
|
|
||||||
planet.onDraw(function() {
|
|
||||||
planet.withSavedContext(function(context) {
|
|
||||||
context.beginPath();
|
|
||||||
planet.path.context(context)(lakes);
|
|
||||||
context.fillStyle = options.fill || 'black';
|
|
||||||
context.fill();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})();</code></pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%- partial('_scripts_rotating') %>
|
|
||||||
@ -1,117 +0,0 @@
|
|||||||
(function() {
|
|
||||||
var globe = planetaryjs.planet();
|
|
||||||
// Load our custom `autorotate` plugin; see below.
|
|
||||||
globe.loadPlugin(autorotate(10));
|
|
||||||
// The `earth` plugin draws the oceans and the land; it's actually
|
|
||||||
// a combination of several separate built-in plugins.
|
|
||||||
//
|
|
||||||
// Note that we're loading a special TopoJSON file
|
|
||||||
// (world-110m-withlakes.json) so we can render lakes.
|
|
||||||
globe.loadPlugin(planetaryjs.plugins.earth({
|
|
||||||
topojson: { file: '/world-110m-withlakes.json' },
|
|
||||||
oceans: { fill: '#000080' },
|
|
||||||
land: { fill: '#339966' },
|
|
||||||
borders: { stroke: '#008000' }
|
|
||||||
}));
|
|
||||||
// Load our custom `lakes` plugin to draw lakes; see below.
|
|
||||||
globe.loadPlugin(lakes({
|
|
||||||
fill: '#000080'
|
|
||||||
}));
|
|
||||||
// The `pings` plugin draws animated pings on the globe.
|
|
||||||
globe.loadPlugin(planetaryjs.plugins.pings());
|
|
||||||
// The `zoom` and `drag` plugins enable
|
|
||||||
// manipulating the globe with the mouse.
|
|
||||||
globe.loadPlugin(planetaryjs.plugins.zoom({
|
|
||||||
scaleExtent: [100, 300]
|
|
||||||
}));
|
|
||||||
globe.loadPlugin(planetaryjs.plugins.drag({
|
|
||||||
// Dragging the globe should pause the
|
|
||||||
// automatic rotation until we release the mouse.
|
|
||||||
onDragStart: function() {
|
|
||||||
this.plugins.autorotate.pause();
|
|
||||||
},
|
|
||||||
onDragEnd: function() {
|
|
||||||
this.plugins.autorotate.resume();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
// Set up the globe's initial scale, offset, and rotation.
|
|
||||||
globe.projection.scale(175).translate([175, 175]).rotate([0, -10, 0]);
|
|
||||||
|
|
||||||
// Every few hundred milliseconds, we'll draw another random ping.
|
|
||||||
var colors = ['red', 'yellow', 'white', 'orange', 'green', 'cyan', 'pink'];
|
|
||||||
setInterval(function() {
|
|
||||||
var lat = Math.random() * 170 - 85;
|
|
||||||
var lng = Math.random() * 360 - 180;
|
|
||||||
var color = colors[Math.floor(Math.random() * colors.length)];
|
|
||||||
globe.plugins.pings.add(lng, lat, { color: color, ttl: 2000, angle: Math.random() * 10 });
|
|
||||||
}, 150);
|
|
||||||
|
|
||||||
var canvas = document.getElementById('rotatingGlobe');
|
|
||||||
// Special code to handle high-density displays (e.g. retina, some phones)
|
|
||||||
// In the future, Planetary.js will handle this by itself (or via a plugin).
|
|
||||||
if (window.devicePixelRatio == 2) {
|
|
||||||
canvas.width = 800;
|
|
||||||
canvas.height = 800;
|
|
||||||
context = canvas.getContext('2d');
|
|
||||||
context.scale(2, 2);
|
|
||||||
}
|
|
||||||
// Draw that globe!
|
|
||||||
globe.draw(canvas);
|
|
||||||
|
|
||||||
// This plugin will automatically rotate the globe around its vertical
|
|
||||||
// axis a configured number of degrees every second.
|
|
||||||
function autorotate(degPerSec) {
|
|
||||||
// Planetary.js plugins are functions that take a `planet` instance
|
|
||||||
// as an argument...
|
|
||||||
return function(planet) {
|
|
||||||
var lastTick = null;
|
|
||||||
var paused = false;
|
|
||||||
planet.plugins.autorotate = {
|
|
||||||
pause: function() { paused = true; },
|
|
||||||
resume: function() { paused = false; }
|
|
||||||
};
|
|
||||||
// ...and configure hooks into certain pieces of its lifecycle.
|
|
||||||
planet.onDraw(function() {
|
|
||||||
if (paused || !lastTick) {
|
|
||||||
lastTick = new Date();
|
|
||||||
} else {
|
|
||||||
var now = new Date();
|
|
||||||
var delta = now - lastTick;
|
|
||||||
// This plugin uses the built-in projection (provided by D3)
|
|
||||||
// to rotate the globe each time we draw it.
|
|
||||||
var rotation = planet.projection.rotate();
|
|
||||||
rotation[0] += degPerSec * delta / 1000;
|
|
||||||
if (rotation[0] >= 180) rotation[0] -= 360;
|
|
||||||
planet.projection.rotate(rotation);
|
|
||||||
lastTick = now;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// This plugin takes lake data from the special
|
|
||||||
// TopoJSON we're loading and draws them on the map.
|
|
||||||
function lakes(options) {
|
|
||||||
options = options || {};
|
|
||||||
var lakes = null;
|
|
||||||
|
|
||||||
return function(planet) {
|
|
||||||
planet.onInit(function() {
|
|
||||||
// We can access the data loaded from the TopoJSON plugin
|
|
||||||
// on its namespace on `planet.plugins`. We're loading a custom
|
|
||||||
// TopoJSON file with an object called "ne_110m_lakes".
|
|
||||||
var world = planet.plugins.topojson.world;
|
|
||||||
lakes = topojson.feature(world, world.objects.ne_110m_lakes);
|
|
||||||
});
|
|
||||||
|
|
||||||
planet.onDraw(function() {
|
|
||||||
planet.withSavedContext(function(context) {
|
|
||||||
context.beginPath();
|
|
||||||
planet.path.context(context)(lakes);
|
|
||||||
context.fillStyle = options.fill || 'black';
|
|
||||||
context.fill();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 72 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 79 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 78 KiB |
@ -16,13 +16,9 @@
|
|||||||
<i class='move icon'></i>
|
<i class='move icon'></i>
|
||||||
<div class='content'>Mouse drag + zoom support</div>
|
<div class='content'>Mouse drag + zoom support</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class='item'>
|
<div class='item'>
|
||||||
<i class='lightbulb icon'></i>
|
<i class='lightbulb icon'></i>
|
||||||
<div class='content'><a href='angular.html'>AngularJS integration</a></div>
|
<div class='content'><a href='angular.html'>AngularJS integration</a></div>
|
||||||
</div> -->
|
|
||||||
<div class='item'>
|
|
||||||
<i class='puzzle piece icon'></i>
|
|
||||||
<div class='content'>Extremely extensible via a plugin-based architecture</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class='item'>
|
<div class='item'>
|
||||||
<i class='fork code icon'></i>
|
<i class='fork code icon'></i>
|
||||||
@ -31,24 +27,23 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='ui buttons'>
|
<div class='ui buttons'>
|
||||||
<a class='ui green labeled icon button' href='/download/'><i class='icon download'></i>Download</a>
|
<a class='ui green labeled icon button' href='https://github.com/BinaryMuse/planetary.js/releases'><i class='icon download'></i>Download</a>
|
||||||
<div class='or'></div>
|
<div class='or'></div>
|
||||||
<a class='ui labeled button' href='https://github.com/BinaryMuse/planetary.js' onclick="_gaq.push(['_trackPageview', '/redirect-to-github-project-page']);">View Source</a>
|
<a class='ui labeled button' href='https://github.com/BinaryMuse/planetary.js'>View Source</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style='padding-top: 10px;'>
|
<div style='padding-top: 10px;'>
|
||||||
Or install with <a href='http://bower.io/'>Bower</a>: <div class='ui small label bower'><i class='icon right arrow'></i> bower install planetary.js</div>
|
Or install with <a href='http://bower.io/'>Bower</a>: <div class='ui small label'><i class='icon right arrow'></i> bower install planetary.js</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='eight wide column left floated'>
|
<div class='eight wide column left floated'>
|
||||||
<div class='ui panel homepage-globe-canvas'>
|
<div class='ui panel homepage-globe-canvas'>
|
||||||
<canvas height='350' width='350' style="width: 350px; height: 350px;" id="homepage-globe-canvas"></canvas>
|
<canvas height='350' width='350' style="width: 350px; height: 350px;" id="homepage-globe-canvas"></canvas>
|
||||||
<br>
|
|
||||||
<div style="width: 350px; text-align: center; display: inline-block;">
|
<div style="width: 350px; text-align: center; display: inline-block;">
|
||||||
<div class='ui pointing dark blue label'>
|
<div class='ui pointing dark blue label'>
|
||||||
<a href='/examples/rotating.html'
|
<a href='https://github.com/BinaryMuse/planetary.js/blob/master/site/public/js/homepage.js#files'
|
||||||
class='detail no-underline'><i class='icon code'></i> See how to build this globe</a>
|
class='detail no-underline'><i class='icon code'></i> View this example's source!</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -75,7 +70,7 @@
|
|||||||
<i class='ui huge icon laptop'></i>
|
<i class='ui huge icon laptop'></i>
|
||||||
Examples
|
Examples
|
||||||
</a>
|
</a>
|
||||||
<p class='section-description'>Check out working examples and see what Planetary.js can do</p>
|
<p>Check out working examples and see what Planetary.js can do</p>
|
||||||
<p><a class='ui teal button' href='/examples/'>Explore the Examples</a></p>
|
<p><a class='ui teal button' href='/examples/'>Explore the Examples</a></p>
|
||||||
</div>
|
</div>
|
||||||
<div class='column'>
|
<div class='column'>
|
||||||
@ -83,16 +78,16 @@
|
|||||||
<i class='ui huge icon book'></i>
|
<i class='ui huge icon book'></i>
|
||||||
Documentation
|
Documentation
|
||||||
</a>
|
</a>
|
||||||
<p class='section-description'>See how to install Planetary.js and build something awesome</p>
|
<p>Download and install Planetary.js and build something awesome</p>
|
||||||
<p><a class='ui orange button' href='/documentation/'>Peruse the Documentation</a></p>
|
<p><a class='ui orange button' href='/documentation/'>Peruse the Documentation</a></p>
|
||||||
</div>
|
</div>
|
||||||
<div class='column'>
|
<div class='column'>
|
||||||
<a class='ui icon header' href='https://github.com/BinaryMuse/planetary.js' onclick="_gaq.push(['_trackPageview', '/redirect-to-github-project-page']);">
|
<a class='ui icon header' href='https://github.com/BinaryMuse/planetary.js'>
|
||||||
<i class='ui huge icon github alternate'></i>
|
<i class='ui huge icon github alternate'></i>
|
||||||
Source Code
|
Source Code
|
||||||
</a>
|
</a>
|
||||||
<p class='section-description'>Take a look at the source on GitHub and contribute to the project</p>
|
<p>Check out the source on GitHub and contribute to the project</p>
|
||||||
<p><a class='ui purple button' href='https://github.com/BinaryMuse/planetary.js' onclick="_gaq.push(['_trackPageview', '/redirect-to-github-project-page']);">Examine the Source</a></p>
|
<p><a class='ui purple button' href='https://github.com/BinaryMuse/planetary.js'>Examine the Source</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -3,14 +3,11 @@
|
|||||||
// The `earth` plugin draws the oceans and the land; it's actually
|
// The `earth` plugin draws the oceans and the land; it's actually
|
||||||
// a combination of several separate built-in plugins.
|
// a combination of several separate built-in plugins.
|
||||||
globe.loadPlugin(planetaryjs.plugins.earth({
|
globe.loadPlugin(planetaryjs.plugins.earth({
|
||||||
topojson: { file: 'world-110m-withlakes.json' },
|
topojson: { file: 'world-110m.json' },
|
||||||
oceans: { fill: '#000080' },
|
oceans: { fill: '#000080' },
|
||||||
land: { fill: '#339966' },
|
land: { fill: '#339966' },
|
||||||
borders: { stroke: '#008000' }
|
borders: { stroke: '#008000' }
|
||||||
}));
|
}));
|
||||||
globe.loadPlugin(lakes({
|
|
||||||
fill: '#000080'
|
|
||||||
}));
|
|
||||||
// The `pings` plugin draws animated pings on the globe.
|
// The `pings` plugin draws animated pings on the globe.
|
||||||
globe.loadPlugin(planetaryjs.plugins.pings());
|
globe.loadPlugin(planetaryjs.plugins.pings());
|
||||||
// Load our custom `autorotate` plugin; see below.
|
// Load our custom `autorotate` plugin; see below.
|
||||||
@ -21,13 +18,13 @@
|
|||||||
scaleExtent: [100, 300]
|
scaleExtent: [100, 300]
|
||||||
}));
|
}));
|
||||||
globe.loadPlugin(planetaryjs.plugins.drag({
|
globe.loadPlugin(planetaryjs.plugins.drag({
|
||||||
// Dragging the globe should pause the
|
// Dragging the globe shoud pause the
|
||||||
// automatic rotation until we release the mouse.
|
// automatic rotation until we release the mouse.
|
||||||
onDragStart: function(planet) {
|
onDragStart: function() {
|
||||||
this.plugins.autorotate.pause();
|
globe.plugins.autorotate.pause();
|
||||||
},
|
},
|
||||||
onDragEnd: function(planet) {
|
onDragEnd: function() {
|
||||||
this.plugins.autorotate.resume();
|
globe.plugins.autorotate.resume();
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
// Set up the globe's initial scale, offset, and rotation.
|
// Set up the globe's initial scale, offset, and rotation.
|
||||||
@ -39,8 +36,8 @@
|
|||||||
var lat = Math.random() * 170 - 85;
|
var lat = Math.random() * 170 - 85;
|
||||||
var lng = Math.random() * 360 - 180;
|
var lng = Math.random() * 360 - 180;
|
||||||
var color = colors[Math.floor(Math.random() * colors.length)];
|
var color = colors[Math.floor(Math.random() * colors.length)];
|
||||||
globe.plugins.pings.add(lng, lat, { color: color, ttl: 2000, angle: Math.random() * 10 });
|
globe.plugins.pings.add(lat, lng, { color: color, ttl: 2000, angle: Math.random() * 10 });
|
||||||
}, 150);
|
}, 250);
|
||||||
|
|
||||||
var canvas = document.getElementById('homepage-globe-canvas');
|
var canvas = document.getElementById('homepage-globe-canvas');
|
||||||
// Special code to handle high-density displays (e.g. retina, some phones)
|
// Special code to handle high-density displays (e.g. retina, some phones)
|
||||||
@ -54,27 +51,6 @@
|
|||||||
// Draw that globe!
|
// Draw that globe!
|
||||||
globe.draw(canvas);
|
globe.draw(canvas);
|
||||||
|
|
||||||
function lakes(config) {
|
|
||||||
config = config || {};
|
|
||||||
return function(planet) {
|
|
||||||
var lakes = null;
|
|
||||||
|
|
||||||
planet.onInit(function() {
|
|
||||||
var world = planet.plugins.topojson.world;
|
|
||||||
lakes = topojson.feature(world, world.objects.ne_110m_lakes);
|
|
||||||
});
|
|
||||||
|
|
||||||
planet.onDraw(function() {
|
|
||||||
planet.withSavedContext(function(context) {
|
|
||||||
context.beginPath();
|
|
||||||
planet.path.context(context)(lakes);
|
|
||||||
context.fillStyle = config.fill || 'black';
|
|
||||||
context.fill();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// This plugin will automatically rotate the globe around its vertical
|
// This plugin will automatically rotate the globe around its vertical
|
||||||
// axis a configured number of degrees every second.
|
// axis a configured number of degrees every second.
|
||||||
function autorotate(degPerSec) {
|
function autorotate(degPerSec) {
|
||||||
|
|||||||
6
site/public/js/lib/moment.min.js
vendored
6
site/public/js/lib/moment.min.js
vendored
File diff suppressed because one or more lines are too long
4
site/public/js/lib/planetaryjs.min.js
vendored
4
site/public/js/lib/planetaryjs.min.js
vendored
@ -1,2 +1,2 @@
|
|||||||
/*! Planetary.js 1.1.2 | (c) 2013 Michelle Tilley | Released under MIT License */
|
/*! Planetary.js 0.2.1 | (c) 2013 Brandon Tilley | Released under MIT License */
|
||||||
!function(n,t){"function"==typeof define&&define.amd?define(["d3","topojson"],function(o,i){return n.planetaryjs=t(o,i,n)}):"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 i=null;o&&(i=o.planetaryjs);var e=[],r=function(t,o,i){n.timer(function(){if(t.stopped)return!0;t.context.clearRect(0,0,o.width,o.height);for(var n=0;n<i.onDraw.length;n++)i.onDraw[n]()})},l=function(n,t){for(var o=e.length-1;o>=0;o--)t.unshift(e[o]);for(0===t.length&&(c.plugins.earth&&n.loadPlugin(c.plugins.earth()),c.plugins.pings&&n.loadPlugin(c.plugins.pings())),o=0;o<t.length;o++)t[o](n)},a=function(n,t,o){if(o.onInit.length){var i=0,e=function(n){var t=o.onInit[i];t.length?t(function(){i++,n()}):(t(),i++,setTimeout(n,0))},l=function(){i>=o.onInit.length?r(n,t,o):e(l)};e(l)}else r(n,t,o)},u=function(n,t,o,i){n.canvas=t,n.context=t.getContext("2d"),n.stopped!==!0&&l(n,o),n.stopped=!1,a(n,t,i)},c={plugins:{},noConflict:function(){return o.planetaryjs=i,c},loadPlugin:function(n){e.push(n)},planet:function(){var t=[],o={onInit:[],onDraw:[],onStop:[]},i={plugins:{},draw:function(n){u(i,n,t,o)},onInit:function(n){o.onInit.push(n)},onDraw:function(n){o.onDraw.push(n)},onStop:function(n){o.onStop.push(n)},loadPlugin:function(n){t.push(n)},stop:function(){i.stopped=!0;for(var n=0;n<o.onStop.length;n++)o.onStop[n](i)},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 i.projection=n.geo.orthographic().clipAngle(90),i.path=n.geo.path().projection(i.projection),i}};return c.plugins.topojson=function(t){return function(o){o.plugins.topojson={},o.onInit(function(i){if(t.world)o.plugins.topojson.world=t.world,setTimeout(i,0);else{var e=t.file||"world-110m.json";n.json(e,function(n,t){if(n)throw new Error("Could not load JSON "+e);o.plugins.topojson.world=t,i()})}})}},c.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()})})}},c.plugins.land=function(n){return function(o){var i=null;o.onInit(function(){var n=o.plugins.topojson.world;i=t.feature(n,n.objects.land)}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(i),n.fill!==!1&&(t.fillStyle=n.fill||"white",t.fill()),n.stroke&&(n.lineWidth&&(t.lineWidth=n.lineWidth),t.strokeStyle=n.stroke,t.stroke())})})}},c.plugins.borders=function(n){return function(o){var i=null,e={internal:function(n,t){return n.id!==t.id},external:function(n,t){return n.id===t.id},both:function(){return!0}};o.onInit(function(){var r=o.plugins.topojson.world,l=r.objects.countries,a=n.type||"internal";i=t.mesh(r,l,e[a])}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(i),t.strokeStyle=n.stroke||"gray",n.lineWidth&&(t.lineWidth=n.lineWidth),t.stroke()})})}},c.plugins.earth=function(n){n=n||{};var t=n.topojson||{},o=n.oceans||{},i=n.land||{},e=n.borders||{};return function(n){c.plugins.topojson(t)(n),c.plugins.oceans(o)(n),c.plugins.land(i)(n),c.plugins.borders(e)(n)}},c.plugins.pings=function(t){var o=[];t=t||{};var i=function(n,i,e){e=e||{},e.color=e.color||t.color||"white",e.angle=e.angle||t.angle||5,e.ttl=e.ttl||t.ttl||2e3;var r={time:new Date,options:e};t.latitudeFirst?(r.lat=n,r.lng=i):(r.lng=n,r.lat=i),o.push(r)},e=function(n,t,i){for(var e=[],l=0;l<o.length;l++){var a=o[l],u=i-a.time;u<a.options.ttl&&(e.push(a),r(n,t,i,u,a))}o=e},r=function(t,o,i,e,r){var l=1-e/r.options.ttl,a=n.rgb(r.options.color);a="rgba("+a.r+","+a.g+","+a.b+","+l+")",o.strokeStyle=a;var u=n.geo.circle().origin([r.lng,r.lat]).angle(e/r.options.ttl*r.options.angle)();o.beginPath(),t.path.context(o)(u),o.stroke()};return function(n){n.plugins.pings={add:i},n.onDraw(function(){var t=new Date;n.withSavedContext(function(o){e(n,o,t)})})}},c.plugins.zoom=function(t){t=t||{};var o=function(){},i=t.onZoomStart||o,e=t.onZoomEnd||o,r=t.onZoom||o,l=t.afterZoom||o,a=t.initialScale,u=t.scaleExtent||[50,2e3];return function(t){t.onInit(function(){var o=n.behavior.zoom().scaleExtent(u);o.scale(null!==a&&void 0!==a?a:t.projection.scale()),o.on("zoomstart",i.bind(t)).on("zoomend",e.bind(t)).on("zoom",function(){r.call(t),t.projection.scale(n.event.scale),l.call(t)}),n.select(t.canvas).call(o)})}},c.plugins.drag=function(t){t=t||{};var o=function(){},i=t.onDragStart||o,e=t.onDragEnd||o,r=t.onDrag||o,l=t.afterDrag||o;return function(t){t.onInit(function(){var o=n.behavior.drag().on("dragstart",i.bind(t)).on("dragend",e.bind(t)).on("drag",function(){r.call(t);var o=n.event.dx,i=n.event.dy,e=t.projection.rotate(),a=t.projection.scale(),u=n.scale.linear().domain([-1*a,a]).range([-90,90]),c=u(o),s=u(i);e[0]+=c,e[1]-=s,e[1]>90&&(e[1]=90),e[1]<-90&&(e[1]=-90),e[0]>=180&&(e[0]-=360),t.projection.rotate(e),l.call(t)});n.select(t.canvas).call(o)})}},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 i=null;o&&(i=o.planetaryjs);var e=[],r=function(t,o,i){n.timer(function(){t.context.clearRect(0,0,o.width,o.height);for(var n=0;n<i.onDraw.length;n++)i.onDraw[n]()})},l=function(n,t){for(var o=0;o<e.length;o++)t.unshift(e[o]);0==t.length&&(c.plugins.earth&&n.loadPlugin(c.plugins.earth()),c.plugins.pings&&n.loadPlugin(c.plugins.pings()));for(var o=0;o<t.length;o++)t[o](n)},a=function(n,t,o){if(o.onInit.length){var i=0,e=function(n){var t=o.onInit[i];t.length?t(function(){i++,n()}):(t(),i++,setTimeout(n,0))},l=function(){i>=o.onInit.length?r(n,t,o):e(l)};e(l)}else r(n,t,o)},u=function(n,t,o,i){l(n,o),n.canvas=t,n.context=t.getContext("2d"),a(n,t,i)},c={plugins:{},noConflict:function(){return o.planetaryjs=i,c},loadPlugin:function(n){e.push(n)},planet:function(){var t=[],o={onInit:[],onDraw:[]},i={plugins:{},draw:function(n){u(i,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 i.projection=n.geo.orthographic().clipAngle(90).precision(0),i.path=n.geo.path().projection(i.projection),i}};return c.plugins.topojson=function(t){return function(o){o.plugins.topojson={},o.onInit(function(i){if(t.world)o.plugins.topojson.world=t.world,setTimeout(i,0);else{var e=t.file||"world-110m.json";n.json(e,function(n,t){if(n)throw new Error("Could not load JSON "+e);o.plugins.topojson.world=t,i()})}})}},c.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()})})}},c.plugins.land=function(n){return function(o){var i=null;o.onInit(function(){var n=o.plugins.topojson.world;i=t.feature(n,n.objects.land)}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(i),0!=n.fill&&(t.fillStyle=n.fill||"white",t.fill()),n.stroke&&(n.lineWidth&&(t.lineWidth=n.lineWidth),t.strokeStyle=n.stroke,t.stroke())})})}},c.plugins.borders=function(n){return function(o){var i=null,e={internal:function(n,t){return n.id!==t.id},external:function(n,t){return n.id===t.id},both:function(){return!0}};o.onInit(function(){var r=o.plugins.topojson.world,l=r.objects.countries,a=n.type||"internal";i=t.mesh(r,l,e[a])}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(i),t.strokeStyle=n.stroke||"gray",n.lineWidth&&(t.lineWidth=n.lineWidth),t.stroke()})})}},c.plugins.earth=function(n){var n=n||{},t=n.topojson||{},o=n.oceans||{},i=n.land||{},e=n.borders||{};return function(n){c.plugins.topojson(t)(n),c.plugins.oceans(o)(n),c.plugins.land(i)(n),c.plugins.borders(e)(n)}},c.plugins.pings=function(t){var o=[],i=function(n,i,e){var e=e||{};e.color=e.color||t.color||"white",e.ttl=e.ttl||t.ttl||2e3,e.angle=e.angle||t.angle||5,o.push({lat:n,lng:i,time:new Date,options:e})},e=function(n,t,i){for(var e=[],l=0;l<o.length;l++){var a=o[l],u=i-a.time;u<a.options.ttl&&(e.push(a),r(n,t,i,u,a))}o=e},r=function(t,o,i,e,r){var l=1-e/r.options.ttl,a=n.rgb(r.options.color);a="rgba("+a.r+","+a.g+","+a.b+","+l+")",o.strokeStyle=a;var u=n.geo.circle().origin([r.lng,r.lat]).angle(e/r.options.ttl*r.options.angle)();o.beginPath(),t.path.context(o)(u),o.stroke()};return function(n){n.plugins.pings={add:i},n.onDraw(function(){var t=new Date;n.withSavedContext(function(o){e(n,o,t)})})}},c.plugins.zoom=function(t){var t=t||{},o=function(){},i=t.onZoomStart||o,e=t.onZoomEnd||o,r=t.onZoom||o,l=t.initialScale,a=t.scaleExtent||[50,2e3];return function(t){t.onInit(function(){var o=n.behavior.zoom().scaleExtent(a);l?o.scale(l):o.scale(t.projection.scale()),o.on("zoomstart",i).on("zoomend",e).on("zoom",function(){r(),t.projection.scale(n.event.scale)}),n.select(t.canvas).call(o)})}},c.plugins.drag=function(t){var t=t||{},o=function(){},i=t.onDragStart||o,e=t.onDragEnd||o,r=t.onDrag||o;return function(t){t.onInit(function(){var o=n.behavior.drag().on("dragstart",i).on("dragend",e).on("drag",function(){r();var o=n.event.dx,i=n.event.dy,e=t.projection.rotate(),l=t.projection.scale(),a=n.scale.linear().domain([-1*l,l]).range([-90,90]),u=a(o),c=a(i);e[0]+=u,e[1]-=c,e[1]>90&&(e[1]=90),e[1]<-90&&(e[1]=-90),e[0]>=180&&(e[0]-=360),t.projection.rotate(e)});n.select(t.canvas).call(o)})}},c});
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,8 +1,6 @@
|
|||||||
(function (root, factory) {
|
(function (root, factory) {
|
||||||
if (typeof define === 'function' && define.amd) {
|
if (typeof define === 'function' && define.amd) {
|
||||||
define(['d3', 'topojson'], function(d3, topojson) {
|
define(['d3', 'topojson'], factory);
|
||||||
return (root.planetaryjs = factory(d3, topojson, root));
|
|
||||||
});
|
|
||||||
} else if (typeof exports === 'object') {
|
} else if (typeof exports === 'object') {
|
||||||
module.exports = factory(require('d3'), require('topojson'));
|
module.exports = factory(require('d3'), require('topojson'));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
40
src/body.js
40
src/body.js
@ -4,11 +4,7 @@
|
|||||||
|
|
||||||
var doDrawLoop = function(planet, canvas, hooks) {
|
var doDrawLoop = function(planet, canvas, hooks) {
|
||||||
d3.timer(function() {
|
d3.timer(function() {
|
||||||
if (planet.stopped) {
|
planet.context.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
planet.context.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
for (var i = 0; i < hooks.onDraw.length; i++) {
|
for (var i = 0; i < hooks.onDraw.length; i++) {
|
||||||
hooks.onDraw[i]();
|
hooks.onDraw[i]();
|
||||||
}
|
}
|
||||||
@ -17,19 +13,19 @@
|
|||||||
|
|
||||||
var initPlugins = function(planet, localPlugins) {
|
var initPlugins = function(planet, localPlugins) {
|
||||||
// Add the global plugins to the beginning of the local ones
|
// Add the global plugins to the beginning of the local ones
|
||||||
for (var i = plugins.length - 1; i >= 0; i--) {
|
for (var i = 0; i < plugins.length; i++) {
|
||||||
localPlugins.unshift(plugins[i]);
|
localPlugins.unshift(plugins[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the default plugins if none have been loaded so far
|
// Load the default plugins if none have been loaded so far
|
||||||
if (localPlugins.length === 0) {
|
if (localPlugins.length == 0) {
|
||||||
if (planetaryjs.plugins.earth)
|
if (planetaryjs.plugins.earth)
|
||||||
planet.loadPlugin(planetaryjs.plugins.earth());
|
planet.loadPlugin(planetaryjs.plugins.earth());
|
||||||
if (planetaryjs.plugins.pings)
|
if (planetaryjs.plugins.pings)
|
||||||
planet.loadPlugin(planetaryjs.plugins.pings());
|
planet.loadPlugin(planetaryjs.plugins.pings());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < localPlugins.length; i++) {
|
for (var i = 0; i < localPlugins.length; i++) {
|
||||||
localPlugins[i](planet);
|
localPlugins[i](planet);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -55,7 +51,7 @@
|
|||||||
var check = function() {
|
var check = function() {
|
||||||
if (completed >= hooks.onInit.length) doDrawLoop(planet, canvas, hooks);
|
if (completed >= hooks.onInit.length) doDrawLoop(planet, canvas, hooks);
|
||||||
else doNext(check);
|
else doNext(check);
|
||||||
};
|
}
|
||||||
doNext(check);
|
doNext(check);
|
||||||
} else {
|
} else {
|
||||||
doDrawLoop(planet, canvas, hooks);
|
doDrawLoop(planet, canvas, hooks);
|
||||||
@ -63,14 +59,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
var startDraw = function(planet, canvas, localPlugins, hooks) {
|
var startDraw = function(planet, canvas, localPlugins, hooks) {
|
||||||
|
initPlugins(planet, localPlugins);
|
||||||
|
|
||||||
planet.canvas = canvas;
|
planet.canvas = canvas;
|
||||||
planet.context = canvas.getContext('2d');
|
planet.context = canvas.getContext('2d');
|
||||||
|
|
||||||
if (planet.stopped !== true) {
|
|
||||||
initPlugins(planet, localPlugins);
|
|
||||||
}
|
|
||||||
|
|
||||||
planet.stopped = false;
|
|
||||||
runOnInitHooks(planet, canvas, hooks);
|
runOnInitHooks(planet, canvas, hooks);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,8 +83,7 @@
|
|||||||
var localPlugins = [];
|
var localPlugins = [];
|
||||||
var hooks = {
|
var hooks = {
|
||||||
onInit: [],
|
onInit: [],
|
||||||
onDraw: [],
|
onDraw: []
|
||||||
onStop: []
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var planet = {
|
var planet = {
|
||||||
@ -109,24 +101,13 @@
|
|||||||
hooks.onDraw.push(fn);
|
hooks.onDraw.push(fn);
|
||||||
},
|
},
|
||||||
|
|
||||||
onStop: function(fn) {
|
|
||||||
hooks.onStop.push(fn);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadPlugin: function(plugin) {
|
loadPlugin: function(plugin) {
|
||||||
localPlugins.push(plugin);
|
localPlugins.push(plugin);
|
||||||
},
|
},
|
||||||
|
|
||||||
stop: function() {
|
|
||||||
planet.stopped = true;
|
|
||||||
for (var i = 0; i < hooks.onStop.length; i++) {
|
|
||||||
hooks.onStop[i](planet);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
withSavedContext: function(fn) {
|
withSavedContext: function(fn) {
|
||||||
if (!this.context) {
|
if (!this.context) {
|
||||||
throw new Error("No canvas to fetch context for");
|
throw new Error("No canvas to fetch context for")
|
||||||
}
|
}
|
||||||
|
|
||||||
this.context.save();
|
this.context.save();
|
||||||
@ -136,7 +117,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
planet.projection = d3.geo.orthographic()
|
planet.projection = d3.geo.orthographic()
|
||||||
.clipAngle(90);
|
.clipAngle(90)
|
||||||
|
.precision(0);
|
||||||
planet.path = d3.geo.path().projection(planet.projection);
|
planet.path = d3.geo.path().projection(planet.projection);
|
||||||
|
|
||||||
return planet;
|
return planet;
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
planet.plugins.topojson.world = config.world;
|
planet.plugins.topojson.world = config.world;
|
||||||
setTimeout(done, 0);
|
setTimeout(done, 0);
|
||||||
} else {
|
} else {
|
||||||
var file = config.file || 'world-110m.json';
|
var file = config.file || 'world-110m.json'
|
||||||
d3.json(file, function(err, world) {
|
d3.json(file, function(err, world) {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw new Error("Could not load JSON " + file);
|
throw new Error("Could not load JSON " + file);
|
||||||
@ -41,14 +41,14 @@
|
|||||||
planet.onInit(function() {
|
planet.onInit(function() {
|
||||||
var world = planet.plugins.topojson.world;
|
var world = planet.plugins.topojson.world;
|
||||||
land = topojson.feature(world, world.objects.land);
|
land = topojson.feature(world, world.objects.land);
|
||||||
});
|
})
|
||||||
|
|
||||||
planet.onDraw(function() {
|
planet.onDraw(function() {
|
||||||
planet.withSavedContext(function(context) {
|
planet.withSavedContext(function(context) {
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
planet.path.context(context)(land);
|
planet.path.context(context)(land);
|
||||||
|
|
||||||
if (config.fill !== false) {
|
if (config.fill != false) {
|
||||||
context.fillStyle = config.fill || 'white';
|
context.fillStyle = config.fill || 'white';
|
||||||
context.fill();
|
context.fill();
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
planetaryjs.plugins.earth = function(config) {
|
planetaryjs.plugins.earth = function(config) {
|
||||||
config = config || {};
|
var config = config || {};
|
||||||
var topojsonOptions = config.topojson || {};
|
var topojsonOptions = config.topojson || {};
|
||||||
var oceanOptions = config.oceans || {};
|
var oceanOptions = config.oceans || {};
|
||||||
var landOptions = config.land || {};
|
var landOptions = config.land || {};
|
||||||
@ -114,22 +114,13 @@
|
|||||||
|
|
||||||
planetaryjs.plugins.pings = function(config) {
|
planetaryjs.plugins.pings = function(config) {
|
||||||
var pings = [];
|
var pings = [];
|
||||||
config = config || {};
|
|
||||||
|
|
||||||
var addPing = function(lng, lat, options) {
|
var addPing = function(lat, lng, options) {
|
||||||
options = options || {};
|
var options = options || {};
|
||||||
options.color = options.color || config.color || 'white';
|
options.color = options.color || config.color || 'white';
|
||||||
options.angle = options.angle || config.angle || 5;
|
|
||||||
options.ttl = options.ttl || config.ttl || 2000;
|
options.ttl = options.ttl || config.ttl || 2000;
|
||||||
var ping = { time: new Date(), options: options };
|
options.angle = options.angle || config.angle || 5;
|
||||||
if (config.latitudeFirst) {
|
pings.push({ lat: lat, lng: lng, time: new Date(), options: options });
|
||||||
ping.lat = lng;
|
|
||||||
ping.lng = lat;
|
|
||||||
} else {
|
|
||||||
ping.lng = lng;
|
|
||||||
ping.lat = lat;
|
|
||||||
}
|
|
||||||
pings.push(ping);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var drawPings = function(planet, context, now) {
|
var drawPings = function(planet, context, now) {
|
||||||
@ -172,12 +163,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
planetaryjs.plugins.zoom = function (options) {
|
planetaryjs.plugins.zoom = function (options) {
|
||||||
options = options || {};
|
var options = options || {};
|
||||||
var noop = function() {};
|
var noop = function() {};
|
||||||
var onZoomStart = options.onZoomStart || noop;
|
var onZoomStart = options.onZoomStart || noop;
|
||||||
var onZoomEnd = options.onZoomEnd || noop;
|
var onZoomEnd = options.onZoomEnd || noop;
|
||||||
var onZoom = options.onZoom || noop;
|
var onZoom = options.onZoom || noop;
|
||||||
var afterZoom = options.afterZoom || noop;
|
|
||||||
var startScale = options.initialScale;
|
var startScale = options.initialScale;
|
||||||
var scaleExtent = options.scaleExtent || [50, 2000];
|
var scaleExtent = options.scaleExtent || [50, 2000];
|
||||||
|
|
||||||
@ -185,20 +175,17 @@
|
|||||||
planet.onInit(function() {
|
planet.onInit(function() {
|
||||||
var zoom = d3.behavior.zoom()
|
var zoom = d3.behavior.zoom()
|
||||||
.scaleExtent(scaleExtent);
|
.scaleExtent(scaleExtent);
|
||||||
|
if (startScale) {
|
||||||
if (startScale !== null && startScale !== undefined) {
|
|
||||||
zoom.scale(startScale);
|
zoom.scale(startScale);
|
||||||
} else {
|
} else {
|
||||||
zoom.scale(planet.projection.scale());
|
zoom.scale(planet.projection.scale());
|
||||||
}
|
}
|
||||||
|
|
||||||
zoom
|
zoom
|
||||||
.on('zoomstart', onZoomStart.bind(planet))
|
.on('zoomstart', onZoomStart)
|
||||||
.on('zoomend', onZoomEnd.bind(planet))
|
.on('zoomend', onZoomEnd)
|
||||||
.on('zoom', function() {
|
.on('zoom', function() {
|
||||||
onZoom.call(planet);
|
onZoom();
|
||||||
planet.projection.scale(d3.event.scale);
|
planet.projection.scale(d3.event.scale);
|
||||||
afterZoom.call(planet);
|
|
||||||
});
|
});
|
||||||
d3.select(planet.canvas).call(zoom);
|
d3.select(planet.canvas).call(zoom);
|
||||||
});
|
});
|
||||||
@ -206,20 +193,19 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
planetaryjs.plugins.drag = function(options) {
|
planetaryjs.plugins.drag = function(options) {
|
||||||
options = options || {};
|
var options = options || {};
|
||||||
var noop = function() {};
|
var noop = function() {};
|
||||||
var onDragStart = options.onDragStart || noop;
|
var onDragStart = options.onDragStart || noop;
|
||||||
var onDragEnd = options.onDragEnd || noop;
|
var onDragEnd = options.onDragEnd || noop;
|
||||||
var onDrag = options.onDrag || noop;
|
var onDrag = options.onDrag || noop;
|
||||||
var afterDrag = options.afterDrag || noop;
|
|
||||||
|
|
||||||
return function(planet) {
|
return function(planet) {
|
||||||
planet.onInit(function() {
|
planet.onInit(function() {
|
||||||
var drag = d3.behavior.drag()
|
var drag = d3.behavior.drag()
|
||||||
.on('dragstart', onDragStart.bind(planet))
|
.on('dragstart', onDragStart)
|
||||||
.on('dragend', onDragEnd.bind(planet))
|
.on('dragend', onDragEnd)
|
||||||
.on('drag', function() {
|
.on('drag', function() {
|
||||||
onDrag.call(planet);
|
onDrag();
|
||||||
var dx = d3.event.dx;
|
var dx = d3.event.dx;
|
||||||
var dy = d3.event.dy;
|
var dy = d3.event.dy;
|
||||||
var rotation = planet.projection.rotate();
|
var rotation = planet.projection.rotate();
|
||||||
@ -235,7 +221,6 @@
|
|||||||
if (rotation[1] < -90) rotation[1] = -90;
|
if (rotation[1] < -90) rotation[1] = -90;
|
||||||
if (rotation[0] >= 180) rotation[0] -= 360;
|
if (rotation[0] >= 180) rotation[0] -= 360;
|
||||||
planet.projection.rotate(rotation);
|
planet.projection.rotate(rotation);
|
||||||
afterDrag.call(planet);
|
|
||||||
});
|
});
|
||||||
d3.select(planet.canvas).call(drag);
|
d3.select(planet.canvas).call(drag);
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user