diff --git a/css/planetaryjs.css b/css/planetaryjs.css
index 89ab525..6dcc33b 100644
--- a/css/planetaryjs.css
+++ b/css/planetaryjs.css
@@ -1 +1 @@
-html,body{font-size:15px;font-family:"Open Sans","Helvetica Neue","Helvetica","Arial",sans-serif}body{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-family:"Source Sans Pro","Helvetica Neue","Helvetica","Arial",sans-serif}h1.subheader,h2.subheader,h3.subheader,h4.subheader,h5.subheader,h6.subheader{font-weight:300}h1.title-header,h2.title-header{margin-top:0px;margin-bottom:10px}.content.container{padding-top:50px}.content.container .slim{max-width:1108px;padding:0 20px;margin:0 auto}.centered{text-align:center}.feature-list{font-size:17px}.feature-list .icon{margin-right:5px !important}a.ui.icon.header{text-decoration:none;color:black}a.ui.icon.header:hover{color:blue}.divider .icon.huge{font-size:2em}.footer .text{text-align:center}canvas#homepage-globe-canvas{width:350px;height:350px}@media screen and (max-width:768px){.hide-on-mobile{display:none !important}.ui.grid>.wide.column{width:auto !important;min-width:100%}}.column h1:first-child{padding-top:0;margin-top:0}@media screen and (min-width:769px){.hide-on-non-mobile{display:none !important}.main-menu .items{text-align:center;max-width:900px}}@media screen and (min-width:1050px){.main-menu{padding-left:8%}}.spacer{display:inline-block;width:50px}.ui.large.menu .item.minor{font-size:14px}.homepage-globe-canvas{text-align:right}@media screen and (max-width:998px){.homepage-globe-canvas{text-align:center}}.ui.dark.blue.label{background-color:#000080 !important}.ui.dark.blue.label:before{background-color:#000080 !important}.no-underline{text-decoration:none}.ui.menu .item.contains-subitems{padding-top:0;padding-bottom:0;margin-top:0}.ui.menu .item.contains-subitems:before{width:0;height:0}pre{font-size:14px;overflow-x:auto}.ui.items.examples a.item{text-decoration:none}
\ No newline at end of file
+html,body{font-size:15px;font-family:"Open Sans","Helvetica Neue","Helvetica","Arial",sans-serif}body{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-family:"Source Sans Pro","Helvetica Neue","Helvetica","Arial",sans-serif}h1.subheader,h2.subheader,h3.subheader,h4.subheader,h5.subheader,h6.subheader{font-weight:300}h1.title-header,h2.title-header{margin-top:0px;margin-bottom:10px}.content.container{padding-top:50px}.content.container .slim{max-width:1108px;padding:0 20px;margin:0 auto}.centered{text-align:center}.feature-list{font-size:17px}.feature-list .icon{margin-right:5px !important}a.ui.icon.header{text-decoration:none;color:black}a.ui.icon.header:hover{color:blue}.divider .icon.huge{font-size:2em}.footer .text{text-align:center}canvas#homepage-globe-canvas{width:350px;height:350px;cursor:move}@media screen and (max-width:768px){.hide-on-mobile{display:none !important}.ui.grid>.wide.column{width:auto !important;min-width:100%}}.column h1:first-child{padding-top:0;margin-top:0}@media screen and (min-width:769px){.hide-on-non-mobile{display:none !important}.main-menu .items{text-align:center;max-width:900px}}@media screen and (min-width:1050px){.main-menu{padding-left:8%}}.spacer{display:inline-block;width:50px}.ui.large.menu .item.minor{font-size:14px}.homepage-globe-canvas{text-align:right}@media screen and (max-width:998px){.homepage-globe-canvas{text-align:center}}.ui.dark.blue.label{background-color:#000080 !important}.ui.dark.blue.label:before{background-color:#000080 !important}.no-underline{text-decoration:none}.ui.menu .item.contains-subitems{padding-top:0;padding-bottom:0;margin-top:0}.ui.menu .item.contains-subitems:before{width:0;height:0}pre{font-size:14px;overflow-x:auto}.ui.items.examples a.item{text-decoration:none}
\ No newline at end of file
diff --git a/documentation/builtin_drag.html b/documentation/builtin_drag.html
index 63baf59..4032686 100644
--- a/documentation/builtin_drag.html
+++ b/documentation/builtin_drag.html
@@ -80,7 +80,22 @@
Drag Plugin
-
This plugin is not yet impelemented.
+
The drag plugin allows for modifying the planet's projection's rotation with the mouse wheel. It supports dragging vertically with hard stops at the north and south poles, and dragging horizontally without restriction.
+
API
+
planetaryjs.plugins.drag([config])
+
Valid keys for config are:
+
+onDrag, onDragStart, onDragEnd: hooks to the d3.behavior.drag object's drag, dragstart, and dragend events; each defaults to a no-op
+
+
+
JavaScript
+
+
planetaryjs.plugins.drag({
+ onDrag: function() {
+ console.log("The planet was dragged!", d3.event);
+ }
+});
+
diff --git a/documentation/builtin_zoom.html b/documentation/builtin_zoom.html
index 3310c2a..bca3160 100644
--- a/documentation/builtin_zoom.html
+++ b/documentation/builtin_zoom.html
@@ -80,7 +80,25 @@
Zoom Plugin
-
This plugin is not yet impelemented.
+
The zoom plugin allows for modifying the planet's projection's scale with the mouse wheel.
+
API
+
planetaryjs.plugins.zoom([config])
+
Valid keys for config are:
+
+initialScale: the value to initialize the d3.behavior.zoom 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]
+onZoom, onZoomStart, onZoomEnd: hooks to the d3.behavior.zoom object's zoom, zoomstart, and zoomend events; each defaults to a no-op
+
+
+
JavaScript
+
+
planetaryjs.plugins.zoom({
+ scaleExtent: [200, 1000],
+ onZoom: function() {
+ console.log("The planet was zoomed!", d3.event);
+ }
+});
+
diff --git a/js/homepage.js b/js/homepage.js
index b313bf1..b0a490f 100644
--- a/js/homepage.js
+++ b/js/homepage.js
@@ -12,6 +12,21 @@
globe.loadPlugin(planetaryjs.plugins.pings());
// Load our custom `autorotate` plugin; see below.
globe.loadPlugin(autorotate(10));
+ // 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 shoud pause the
+ // automatic rotation until we release the mouse.
+ onDragStart: function() {
+ globe.plugins.autorotate.pause();
+ },
+ onDragEnd: function() {
+ globe.plugins.autorotate.resume();
+ }
+ }))
// Set up the globe's initial scale, offset, and rotation.
globe.projection.scale(175).translate([175, 175]).rotate([0, -10, 0]);
@@ -43,9 +58,14 @@
// 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 (!lastTick) {
+ if (paused || !lastTick) {
lastTick = new Date();
} else {
var now = new Date();
diff --git a/js/lib/planetaryjs.min.js b/js/lib/planetaryjs.min.js
index bbbbd47..2248ce1 100644
--- a/js/lib/planetaryjs.min.js
+++ b/js/lib/planetaryjs.min.js
@@ -1,2 +1,2 @@
/*! Planetary.js 0.2.0 | (c) 2013 Brandon Tilley | Released under MIT License */
-!function(n,t){"function"==typeof define&&define.amd?define(["d3","topojson"],t):"object"==typeof exports?module.exports=t(require("d3"),require("topojson")):n.planetaryjs=t(n.d3,n.topojson,n)}(this,function(n,t,o){"use strict";var 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=o.onInit.length?r(n,t,o):e(l)};e(l)}else r(n,t,o)},a=function(n,t,o,i){l(n,o),n.canvas=t,n.context=t.getContext("2d"),u(n,t,i)},s={plugins:{},noConflict:function(){return o.planetaryjs=i,s},loadPlugin:function(n){e.push(n)},planet:function(){var t=[],o={onInit:[],onDraw:[]},i={plugins:{},draw:function(n){a(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 s.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()})}})}},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()})})}},s.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())})})}},s.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,u=n.type||"internal";i=t.mesh(r,l,e[u])}),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()})})}},s.plugins.earth=function(n){var n=n||{},t=n.topojson||{},o=n.oceans||{},i=n.land||{},e=n.borders||{};return function(n){s.plugins.topojson(t)(n),s.plugins.oceans(o)(n),s.plugins.land(i)(n),s.plugins.borders(e)(n)}},s.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.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;l90&&(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});
\ No newline at end of file