Update site
This commit is contained in:
parent
cda093b246
commit
744b80da64
@ -90,6 +90,7 @@
|
|||||||
<body>
|
<body>
|
||||||
...</code></pre>
|
...</code></pre>
|
||||||
<p></div></p>
|
<p></div></p>
|
||||||
|
<p>If you use the default <code>topojson</code> plugin (most people will), you'll also need to make sure <code>world-110m.json</code> (or some other TopoJSON data file) is available on your server. This file is also available from <a href="https://github.com/BinaryMuse/planetary.js/releases">the download page</a>. See the <a href="/documentation/builtin_topojson.html">TopoJSON Plugin</a> documentation for more information.</p>
|
||||||
<h2>Core API</h2>
|
<h2>Core API</h2>
|
||||||
<p><strong><code>planetaryjs.noConflict()</code></strong></p>
|
<p><strong><code>planetaryjs.noConflict()</code></strong></p>
|
||||||
<p>In non-AMD and non-CommonJS environments, Planetary.js takes over the global <code>planetaryjs</code> namespace (in the browser, this means <code>window.planetaryjs</code>). If, for some reason, something else useful was there before you loaded Planetary.js, you can ask for it to be returned to that spot by calling <code>planetaryjs.noConflict()</code>. The Planetary.js library will be returned from the function, so you can continue to use the library.</p>
|
<p>In non-AMD and non-CommonJS environments, Planetary.js takes over the global <code>planetaryjs</code> namespace (in the browser, this means <code>window.planetaryjs</code>). If, for some reason, something else useful was there before you loaded Planetary.js, you can ask for it to be returned to that spot by calling <code>planetaryjs.noConflict()</code>. The Planetary.js library will be returned from the function, so you can continue to use the library.</p>
|
||||||
|
|||||||
@ -84,6 +84,36 @@
|
|||||||
<li><a href="/documentation/plugins.html">Plugins</a> describes the plugin architecture of Planetary.js and shows how you can easily build your own plugins to modify the behavior of Planetary.js</li>
|
<li><a href="/documentation/plugins.html">Plugins</a> describes the plugin architecture of Planetary.js and shows how you can easily build your own plugins to modify the behavior of Planetary.js</li>
|
||||||
<li><a href="/documentation/builtin.html">Built-In Plugins</a> describes each of the built-in plugins in turn, including their public API and how to use them in a project.</li>
|
<li><a href="/documentation/builtin.html">Built-In Plugins</a> describes each of the built-in plugins in turn, including their public API and how to use them in a project.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<h2>Quick Start</h2>
|
||||||
|
<p>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.</p>
|
||||||
|
<p>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).</p>
|
||||||
|
<div class='ui raise segment'>
|
||||||
|
<div class='ui blue ribbon label'>HTML</div>
|
||||||
|
|
||||||
|
<pre><code class="language-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='planetaryjs.min.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id='globe' width='500' height='500'></canvas>
|
||||||
|
<script type='text/javascript' src='yourApp.js'></script>
|
||||||
|
</body>
|
||||||
|
</html></code></pre>
|
||||||
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
|
<pre><code class="language-javascript">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: 'http/path/to/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);</code></pre>
|
||||||
|
<p></div></p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -80,7 +80,7 @@
|
|||||||
<h2>Loading Plugins</h2>
|
<h2>Loading Plugins</h2>
|
||||||
<p>Plugins are loaded either globally by <code>planetaryjs.loadPlugin</code> or for a specific planet instance by <code>planet.loadPlugin</code>. If you call <code>draw</code> on a planet and it has no plugins loaded at all (from either source), Planetary.js will use the default plugin stack, which consists of the <code>earth</code> and <code>pings</code> plugins.</p>
|
<p>Plugins are loaded either globally by <code>planetaryjs.loadPlugin</code> or for a specific planet instance by <code>planet.loadPlugin</code>. If you call <code>draw</code> on a planet and it has no plugins loaded at all (from either source), Planetary.js will use the default plugin stack, which consists of the <code>earth</code> and <code>pings</code> plugins.</p>
|
||||||
<h2>Anatomy of a Plugin</h2>
|
<h2>Anatomy of a Plugin</h2>
|
||||||
<p>A plugin is simply a JavaScript function that takes a planet instance as a parameter and performs some predefined operation. <strong>The best plugins do one tiny thing.</strong> 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 <code>earth</code> plugin is built. See the <a href="/documentation/builtin_earth.html">Earth</a> documentation for more details.</p>
|
<p>A plugin is simply a JavaScript function that takes a planet instance as a parameter and performs some predefined operation. <strong>The best plugins do one tiny thing.</strong> 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 <code>earth</code> plugin is built. See the <a href="/documentation/builtin_earth.html">Earth Plugin</a> documentation for more details.</p>
|
||||||
<p>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):</p>
|
<p>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):</p>
|
||||||
<div class='ui raise segment'>
|
<div class='ui raise segment'>
|
||||||
<div class='ui red ribbon label'>JavaScript</div>
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
@ -113,6 +113,97 @@ planet.loadPlugin(autorotate);</code></pre>
|
|||||||
};
|
};
|
||||||
|
|
||||||
planet.loadPlugin(autorotate(5));</code></pre>
|
planet.loadPlugin(autorotate(5));</code></pre>
|
||||||
|
<p></div></p>
|
||||||
|
<h2>Setting Yourself Up</h2>
|
||||||
|
<p>If you need to do some work before your plugin is ready to be used, you can add a hook to a planet's <code>onInit</code> hook to do the necessary setup.</p>
|
||||||
|
<div class='ui raise segment'>
|
||||||
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
|
<pre><code class="language-javascript">var somePlugin = function(planet) {
|
||||||
|
planet.onInit(function() {
|
||||||
|
doSomeSetupWork();
|
||||||
|
});
|
||||||
|
};</code></pre>
|
||||||
|
<p></div></p>
|
||||||
|
<p>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 <code>onInit</code> function. When you're done setting up, call this function and Planetary.js will continue to initialize the planet. <strong>If you accept the parameter but don't call it, the initialization process will stop</strong> (and your planet will not work).</p>
|
||||||
|
<div class='ui raise segment'>
|
||||||
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
|
<pre><code class="language-javascript">var somePlugin = function(planet) {
|
||||||
|
planet.onInit(function(done) {
|
||||||
|
doSomeAsynchronousSetupWork(function() {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};</code></pre>
|
||||||
|
<p></div></p>
|
||||||
|
<h2>Drawing on the Canvas</h2>
|
||||||
|
<p>Many plugins will want to draw onto the globe's canvas; you can do so by registering a function to a planet's <code>onDraw</code> hook.</p>
|
||||||
|
<div class='ui raise segment'>
|
||||||
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
|
<pre><code class="language-javascript">var somePlugin = function(planet) {
|
||||||
|
planet.onDraw(function() {
|
||||||
|
planet.withSavedContext(function(context) {
|
||||||
|
context.beginPath();
|
||||||
|
planet.path.context(context)({type: 'Sphere'});
|
||||||
|
context.fillStyle = 'black';
|
||||||
|
context.fill();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};</code></pre>
|
||||||
|
<p></div></p>
|
||||||
|
<p>The planet exposes properties and methods, such as <code>context</code>, <code>path</code>, and <code>withSavedContext</code> to assist with drawing to the canvas. The <a href="/documentation/planet.html">Planet API</a> documentation goes into more detail on individual properties.</p>
|
||||||
|
<h3>Drawing Geo Paths</h3>
|
||||||
|
<p>As explained in the <code>planet.path</code> documentation on the <a href="/documentation/planet.html">Planet API</a> page, <code>planet.path</code> is a <a href="https://github.com/mbostock/d3/wiki/Geo-Paths"><code>d3.geo.path</code></a> 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.</p>
|
||||||
|
<p>As a demonstration of this technique, the following is a plugin that will take the land data from a TopoJSON data source (stored on <code>planet.plugins.topojson.world</code>), convert it to a GeoJSON feature, and draw it on the planet. This code is similar to (but slightly simplified from) how the <a href="/documentation/builtin_land.html">Land plugin</a> works.</p>
|
||||||
|
<div class='ui raise segment'>
|
||||||
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
|
<pre><code class="language-javascript">var drawLand = function(planet) {
|
||||||
|
planet.onDraw(function() {
|
||||||
|
planet.withSavedContext(function(context) {
|
||||||
|
var world = planet.plugins.topojson.world;
|
||||||
|
var land = topojson.feature(world, world.objects.land);
|
||||||
|
|
||||||
|
context.beginPath();
|
||||||
|
planet.path.context(context)(land);
|
||||||
|
context.fillStyle = 'white';
|
||||||
|
context.fill();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};</code></pre>
|
||||||
|
<p></div></p>
|
||||||
|
<h2>Exposing Data and Methods</h2>
|
||||||
|
<p>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 <code>plugins</code> namespace. You should use a name specific to your plugin, and this name should be well documented in your plugin's documentation.</p>
|
||||||
|
<div class='ui raise segment'>
|
||||||
|
<div class='ui red ribbon label'>JavaScript</div>
|
||||||
|
|
||||||
|
<pre><code class="language-javascript">var autorotate = function(degreesPerTick) {
|
||||||
|
return function(planet) {
|
||||||
|
var paused = false;
|
||||||
|
|
||||||
|
planet.plugins.autorotate = {
|
||||||
|
pause: function() { paused = true; },
|
||||||
|
resume: function() { paused = false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
planet.onDraw(function() {
|
||||||
|
if (paused) return;
|
||||||
|
|
||||||
|
var rotation = planet.projection.rotate();
|
||||||
|
rotation[0] += degreesPerTick;
|
||||||
|
if (rotation[0] >= 180) rotation[0] -= 360;
|
||||||
|
planet.projection.rotate(rotation);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
planet.loadPlugin(autorotate(5));
|
||||||
|
planet.draw(canvas);
|
||||||
|
setTimeout(function() {
|
||||||
|
planet.plugins.autorotate.pause();
|
||||||
|
}, 5000);</code></pre>
|
||||||
<p></div></p>
|
<p></div></p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
4
js/lib/planetaryjs.min.js
vendored
4
js/lib/planetaryjs.min.js
vendored
@ -1,2 +1,2 @@
|
|||||||
/*! Planetary.js 0.0.0 | (c) 2013 Brandon Tilley | Released under MIT License */
|
/*! Planetary.js 0.1.1 | (c) 2013 Brandon Tilley | Released under MIT License */
|
||||||
!function(n,t){"function"==typeof define&&define.amd?define(["d3","topojson"],t):"object"==typeof exports?module.exports=t(require("d3"),require("topojson")):n.planetaryjs=t(n.d3,n.topojson,n)}(this,function(n,t,o){"use strict";var e=null;o&&(e=o.planetaryjs);var i=[],r=function(t,o,e){n.timer(function(){t.context.clearRect(0,0,o.width,o.height);for(var n=0;n<e.onDraw.length;n++)e.onDraw[n]()})},l=function(n,t){for(var o=0;o<i.length;o++)t.unshift(i[o]);0==t.length&&(s.plugins.earth&&n.loadPlugin(s.plugins.earth()),s.plugins.pings&&n.loadPlugin(s.plugins.pings()));for(var o=0;o<t.length;o++)t[o](n)},u=function(n,t,o){if(o.onInit.length){var e=0,i=function(n){var t=o.onInit[e];t.length?t(function(){e++,n()}):(t(),e++,setTimeout(n,0))},l=function(){e>=o.onInit.length?r(n,t,o):i(l)};i(l)}else r(n,t,o)},a=function(n,t,o,e){l(n,o),n.canvas=t,n.context=t.getContext("2d"),u(n,t,e)},s={plugins:{},noConflict:function(){return o.planetaryjs=e,s},loadPlugin:function(n){i.push(n)},planet:function(){var t=[],o={onInit:[],onDraw:[]},e={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.plugins.topojson=function(t){return function(o){o.onInit(function(e){if(t.world)o.world=t.world,setTimeout(e,0);else{var i=t.file||"world-110m.json";n.json(i,function(n,t){if(n)throw new Error("Could not load JSON "+i);o.world=t,e()})}})}},s.plugins.oceans=function(n){return function(t){t.onDraw(function(){t.withSavedContext(function(o){o.beginPath(),t.path.context(o)({type:"Sphere"}),o.fillStyle=n.fill||"black",o.fill(),0!=n.stroke&&(o.strokeStyle=n.stroke,o.stroke())})})}},s.plugins.land=function(n){return function(o){var e=null;o.onInit(function(){e=t.feature(o.world,o.world.objects.land)}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(e),0!=n.fill&&(t.fillStyle=n.fill||"white",t.fill()),n.stroke&&(t.strokeStyle=n.stroke,t.stroke())})})}},s.plugins.borders=function(n){return function(o){var e=null;o.onInit(function(){var n=o.world.objects.countries;e=t.mesh(o.world,n,function(n,t){return n.id!==t.id})}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(e),t.strokeStyle=n.stroke||"gray",t.stroke()})})}},s.plugins.earth=function(n){var n=n||{},t=n.topojson||{},o=n.oceans||{},e=n.land||{},i=n.borders||{};return function(n){s.plugins.topojson(t)(n),s.plugins.oceans(o)(n),s.plugins.land(e)(n),s.plugins.borders(i)(n)}},s.plugins.pings=function(){var t=[],o=function(n,o,e){var e=e||{};e.color=e.color||"white",e.ttl=e.ttl||2e3,e.angle=e.angle||5,t.push({lat:n,lng:o,time:new Date,options:e})},e=function(n,o,e){for(var r=[],l=0;l<t.length;l++){var u=t[l],a=e-u.time;a<u.options.ttl&&(r.push(u),i(n,o,e,a,u))}t=r},i=function(t,o,e,i,r){var l=1-i/r.options.ttl,u=n.rgb(r.options.color);u="rgba("+u.r+","+u.g+","+u.b+","+l+")",o.strokeStyle=u;var a=n.geo.circle().origin([r.lng,r.lat]).angle(i/r.options.ttl*r.options.angle)();o.beginPath(),t.path.context(o)(a),o.stroke()};return function(n){n.plugins.pings={add:o},n.onDraw(function(){var t=new Date;n.withSavedContext(function(o){e(n,o,t)})})}},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 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&&(a.plugins.earth&&n.loadPlugin(a.plugins.earth()),a.plugins.pings&&n.loadPlugin(a.plugins.pings()));for(var o=0;o<t.length;o++)t[o](n)},u=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)},s=function(n,t,o,i){l(n,o),n.canvas=t,n.context=t.getContext("2d"),u(n,t,i)},a={plugins:{},noConflict:function(){return o.planetaryjs=i,a},loadPlugin:function(n){e.push(n)},planet:function(){var t=[],o={onInit:[],onDraw:[]},i={plugins:{},draw:function(n){s(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 a.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()})}})}},a.plugins.oceans=function(n){return function(t){t.onDraw(function(){t.withSavedContext(function(o){o.beginPath(),t.path.context(o)({type:"Sphere"}),o.fillStyle=n.fill||"black",o.fill(),0!=n.stroke&&(o.strokeStyle=n.stroke,o.stroke())})})}},a.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&&(t.strokeStyle=n.stroke,t.stroke())})})}},a.plugins.borders=function(n){return function(o){var i=null;o.onInit(function(){var n=o.plugins.topojson.world,e=n.objects.countries;i=t.mesh(n,e,function(n,t){return n.id!==t.id})}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(i),t.strokeStyle=n.stroke||"gray",t.stroke()})})}},a.plugins.earth=function(n){var n=n||{},t=n.topojson||{},o=n.oceans||{},i=n.land||{},e=n.borders||{};return function(n){a.plugins.topojson(t)(n),a.plugins.oceans(o)(n),a.plugins.land(i)(n),a.plugins.borders(e)(n)}},a.plugins.pings=function(){var t=[],o=function(n,o,i){var i=i||{};i.color=i.color||"white",i.ttl=i.ttl||2e3,i.angle=i.angle||5,t.push({lat:n,lng:o,time:new Date,options:i})},i=function(n,o,i){for(var r=[],l=0;l<t.length;l++){var u=t[l],s=i-u.time;s<u.options.ttl&&(r.push(u),e(n,o,i,s,u))}t=r},e=function(t,o,i,e,r){var l=1-e/r.options.ttl,u=n.rgb(r.options.color);u="rgba("+u.r+","+u.g+","+u.b+","+l+")",o.strokeStyle=u;var s=n.geo.circle().origin([r.lng,r.lat]).angle(e/r.options.ttl*r.options.angle)();o.beginPath(),t.path.context(o)(s),o.stroke()};return function(n){n.plugins.pings={add:o},n.onDraw(function(){var t=new Date;n.withSavedContext(function(o){i(n,o,t)})})}},a});
|
||||||
Loading…
Reference in New Issue
Block a user