First pass at implementation
This commit is contained in:
parent
e2b99beb4b
commit
d9e6594ac4
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/node_modules/
|
||||||
39
gulpfile.js
Normal file
39
gulpfile.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
var gulp = require('gulp');
|
||||||
|
var uglify = require('gulp-uglify');
|
||||||
|
var concat = require('gulp-concat');
|
||||||
|
var rename = require('gulp-rename');
|
||||||
|
var header = require('gulp-header');
|
||||||
|
var gzip = require("gulp-gzip");
|
||||||
|
var metadata = require('./package.json');
|
||||||
|
|
||||||
|
var shortHeader = "/*! Planetary.js {{version}} | (c) 2013 Brandon Tilley | Released under MIT License */"
|
||||||
|
var fullHeader = [
|
||||||
|
"/*! Planetary.js v{{version}}",
|
||||||
|
" * Copyright (c) 2013 Brandon Tilley",
|
||||||
|
" *",
|
||||||
|
" * Released under the MIT license",
|
||||||
|
" * Date: {{now}}",
|
||||||
|
" */"
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
var fullSource = gulp.src(['./src/_umd_header.js', './src/body.js', './src/plugins.js', './src/_umd_footer.js']);
|
||||||
|
var nonPluginSource = gulp.src(['./src/_umd_header.js', './src/body.js', './src/_umd_footer.js']);
|
||||||
|
|
||||||
|
function build(source, name, headerText, minify, gzip) {
|
||||||
|
var js = source.pipe(concat(name));
|
||||||
|
if (minify) { js = js.pipe(uglify()); }
|
||||||
|
js = js.pipe(header(headerText, { version: metadata.version }));
|
||||||
|
if (gzip) { js = js.pipe(gzip()); }
|
||||||
|
js.pipe(gulp.dest('./dist'));
|
||||||
|
}
|
||||||
|
|
||||||
|
gulp.task('build', function() {
|
||||||
|
build(fullSource, 'planetaryjs.js', fullHeader, false);
|
||||||
|
build(fullSource, 'planetaryjs.min.js', shortHeader, true);
|
||||||
|
build(nonPluginSource, 'planetaryjs-noplugins.js', fullHeader, false);
|
||||||
|
build(nonPluginSource, 'planetaryjs-noplugins.min.js', shortHeader, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('default', function() {
|
||||||
|
gulp.run('build');
|
||||||
|
});
|
||||||
26
package.json
Normal file
26
package.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "Planetary.js",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "Awesome interactive globes for the web",
|
||||||
|
"scripts": {
|
||||||
|
"build": "rm -r dist/ ; gulp",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/BinaryMuse/planetary.js.git"
|
||||||
|
},
|
||||||
|
"author": "Brandon Tilley <brandon@brandontilley.com>",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/BinaryMuse/planetary.js/issues"
|
||||||
|
},
|
||||||
|
"homepage": "http://planetaryjs.com",
|
||||||
|
"devDependencies": {
|
||||||
|
"gulp": "~3.2.0",
|
||||||
|
"gulp-concat": "BinaryMuse/gulp-concat",
|
||||||
|
"gulp-header": "~0.4.0",
|
||||||
|
"gulp-uglify": "~0.1.0",
|
||||||
|
"gulp-rename": "~0.2.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
2
src/_umd_footer.js
Normal file
2
src/_umd_footer.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
return planetaryjs;
|
||||||
|
}));
|
||||||
10
src/_umd_header.js
Normal file
10
src/_umd_header.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
(function (root, factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define(['d3', 'topojson'], factory);
|
||||||
|
} else if (typeof exports === 'object') {
|
||||||
|
module.exports = factory(require('d3'), require('topojson'));
|
||||||
|
} else {
|
||||||
|
root.planetaryjs = factory(root.d3, root.topojson, root);
|
||||||
|
}
|
||||||
|
}(this, function(d3, topojson, window) {
|
||||||
|
'use strict';
|
||||||
111
src/body.js
Normal file
111
src/body.js
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
var originalPlanetaryjs = null;
|
||||||
|
if (window) originalPlanetaryjs = window.planetaryjs;
|
||||||
|
var plugins = [];
|
||||||
|
|
||||||
|
var doDrawLoop = function(planet, canvas, hooks) {
|
||||||
|
d3.timer(function() {
|
||||||
|
planet.context.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
|
for (var i = 0; i < hooks.onDraw.length; i++) {
|
||||||
|
hooks.onDraw[i]();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var startDraw = function(planet, canvas, localPlugins, hooks) {
|
||||||
|
for (var i = 0; i < plugins.length; i++) {
|
||||||
|
localPlugins.unshift(plugins[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localPlugins.length == 0 && planetaryjs.plugins.earth) {
|
||||||
|
planet.loadPlugin(planetaryjs.plugins.earth());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < localPlugins.length; i++) {
|
||||||
|
var plugin = localPlugins[i][0];
|
||||||
|
var config = localPlugins[i][1];
|
||||||
|
plugin(planet, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
planet.canvas = canvas;
|
||||||
|
planet.context = canvas.getContext('2d');
|
||||||
|
|
||||||
|
if (hooks.onInit.length) {
|
||||||
|
var completed = 0;
|
||||||
|
var doNext = function(callback) {
|
||||||
|
var next = hooks.onInit[completed];
|
||||||
|
if (next.length) {
|
||||||
|
next(function() {
|
||||||
|
completed++;
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
completed++;
|
||||||
|
setTimeout(callback, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var check = function() {
|
||||||
|
if (completed >= hooks.onInit.length) doDrawLoop(planet, canvas, hooks);
|
||||||
|
else doNext(check);
|
||||||
|
}
|
||||||
|
doNext(check);
|
||||||
|
} else {
|
||||||
|
doDrawLoop(planet, canvas, hooks);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var planetaryjs = {
|
||||||
|
plugins: {},
|
||||||
|
|
||||||
|
noConflict: function() {
|
||||||
|
window.planetaryjs = originalPlanetaryjs;
|
||||||
|
return planetaryjs;
|
||||||
|
},
|
||||||
|
|
||||||
|
loadPlugin: function(plugin, defaultOptions) {
|
||||||
|
plugins.push([plugin, defaultOptions || {}]);
|
||||||
|
},
|
||||||
|
|
||||||
|
planet: function() {
|
||||||
|
var localPlugins = [];
|
||||||
|
var hooks = {
|
||||||
|
onInit: [],
|
||||||
|
onDraw: []
|
||||||
|
};
|
||||||
|
|
||||||
|
var planet = {
|
||||||
|
draw: function(canvas) {
|
||||||
|
startDraw(planet, canvas, localPlugins, hooks);
|
||||||
|
},
|
||||||
|
|
||||||
|
onInit: function(fn) {
|
||||||
|
hooks.onInit.push(fn);
|
||||||
|
},
|
||||||
|
|
||||||
|
onDraw: function(fn) {
|
||||||
|
hooks.onDraw.push(fn);
|
||||||
|
},
|
||||||
|
|
||||||
|
loadPlugin: function(plugin, defaultOptions) {
|
||||||
|
localPlugins.push([plugin, defaultOptions || {}]);
|
||||||
|
},
|
||||||
|
|
||||||
|
withSavedContext: function(fn) {
|
||||||
|
if (!this.context) {
|
||||||
|
throw new Error("No canvas to fetch context for")
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context.save();
|
||||||
|
fn(this.context);
|
||||||
|
this.context.restore();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
planet.projection = d3.geo.orthographic()
|
||||||
|
.clipAngle(90)
|
||||||
|
.precision(0);
|
||||||
|
planet.path = d3.geo.path().projection(planet.projection);
|
||||||
|
|
||||||
|
return planet;
|
||||||
|
}
|
||||||
|
};
|
||||||
93
src/plugins.js
Normal file
93
src/plugins.js
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
planetaryjs.plugins.topojson = function(planet, config) {
|
||||||
|
planet.onInit(function(done) {
|
||||||
|
if (config.world) {
|
||||||
|
planet.world = config.world;
|
||||||
|
setTimeout(done, 0);
|
||||||
|
} else {
|
||||||
|
var file = config.file || 'world-110m.json'
|
||||||
|
d3.json(file, function(err, world) {
|
||||||
|
if (err) {
|
||||||
|
throw new Error("Could not load JSON " + file);
|
||||||
|
}
|
||||||
|
planet.world = world;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
planetaryjs.plugins.oceans = function(planet, config) {
|
||||||
|
planet.onDraw(function() {
|
||||||
|
planet.withSavedContext(function(context) {
|
||||||
|
context.beginPath();
|
||||||
|
planet.path.context(context)({type: 'Sphere'});
|
||||||
|
|
||||||
|
context.fillStyle = config.fill || 'black';
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
if (config.stroke != false) {
|
||||||
|
context.strokeStyle = config.stroke;
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
planetaryjs.plugins.land = function(planet, config) {
|
||||||
|
var land = null;
|
||||||
|
|
||||||
|
planet.onInit(function() {
|
||||||
|
land = topojson.feature(planet.world, planet.world.objects.land);
|
||||||
|
})
|
||||||
|
|
||||||
|
planet.onDraw(function() {
|
||||||
|
planet.withSavedContext(function(context) {
|
||||||
|
context.beginPath();
|
||||||
|
planet.path.context(context)(land);
|
||||||
|
|
||||||
|
if (config.fill != false) {
|
||||||
|
context.fillStyle = config.fill || 'white';
|
||||||
|
context.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.stroke) {
|
||||||
|
context.strokeStyle = config.stroke;
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
planetaryjs.plugins.borders = function(planet, config) {
|
||||||
|
var borders = null;
|
||||||
|
planet.onInit(function() {
|
||||||
|
var countries = planet.world.objects.countries;
|
||||||
|
borders = topojson.mesh(planet.world, countries, function(a, b) {
|
||||||
|
return a.id !== b.id;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
planet.onDraw(function() {
|
||||||
|
planet.withSavedContext(function(context) {
|
||||||
|
context.beginPath();
|
||||||
|
planet.path.context(context)(borders);
|
||||||
|
context.strokeStyle = config.stroke || 'gray';
|
||||||
|
context.stroke();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
planetaryjs.plugins.earth = function(options) {
|
||||||
|
var options = options || {};
|
||||||
|
var topojsonOptions = options.topojson || {};
|
||||||
|
var oceanOptions = options.oceans || {};
|
||||||
|
var landOptions = options.land || {};
|
||||||
|
var bordersOptions = options.borders || {};
|
||||||
|
|
||||||
|
return function(planet, options) {
|
||||||
|
planetaryjs.plugins.topojson(planet, topojsonOptions);
|
||||||
|
planetaryjs.plugins.oceans(planet, oceanOptions);
|
||||||
|
planetaryjs.plugins.land(planet, landOptions);
|
||||||
|
planetaryjs.plugins.borders(planet, bordersOptions);
|
||||||
|
};
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user