Skip to content

Instantly share code, notes, and snippets.

@osoken
Last active August 8, 2016 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save osoken/0431b1fbb38768808469e9ebca647d94 to your computer and use it in GitHub Desktop.
Save osoken/0431b1fbb38768808469e9ebca647d94 to your computer and use it in GitHub Desktop.
inside-out Earth (smartphone recommended)

This sample listens deviceorientation event to change the angle of the view. Try it on devices with gyroscope.

I used Floating Landmasses as a reference for the appearance.

!(function(d3) {
var _gyro = {};
var v = {x: 0, y: 0};
_gyro.x = function() {
return v.x;
};
_gyro.y = function() {
return v.y;
}
var gyro2deg = function(a, b, g) {
var cosY = Math.cos(g);
var cosZ = Math.cos(a);
var sinX = Math.sin(b);
var sinY = Math.sin(g);
var sinZ = Math.sin(a);
return Math.atan2(-cosZ * sinY - sinZ * sinX * cosY,
-sinZ * sinY + cosZ * sinX * cosY) * 180 / Math.PI;
}
var d2r = Math.PI / 180;
var update0 = function(e) {
v.x = -gyro2deg(e.alpha * d2r,
e.beta * d2r,
e.gamma * d2r);
v.y = -(e.beta-90);
};
var update90 = function(e) {
var g = (e.gamma<0)?(-e.gamma-90):(-e.gamma+90);
if (window.orientation == 90) {
g = -g;
}
v.x = -gyro2deg(e.alpha * d2r, e.beta * d2r, e.gamma * d2r);
v.y = g;
};
var update = (window.orientation % 180 === 0) ? update0: update90;
d3.select(window).on('deviceorientation', function() {
update(d3.event);
}).on('orientationchange', function() {
update = (window.orientation % 180 === 0) ? update0: update90;
});
var scaleX = d3.scale.linear().range([0,360]).domain([0,960]);
var scaleY = d3.scale.linear().range([180, -180]).domain([0,500]);
d3.select(window).on('mousemove', function() {
v.x = scaleX(d3.event.x);
v.y = scaleY(d3.event.y);
});
this.gyro = _gyro;
}(d3));
<!DOCTYPE html>
<meta charset='utf-8'>
<script src='//d3js.org/d3.v3.min.js'></script>
<script src='//d3js.org/topojson.v1.min.js'></script>
<script src='./gyro.js'></script>
<style>
canvas {
position: absolute;
top: 0;
left: 0;
}
.blur {
-webkit-filter: blur(12px);
filter: blur(12px);
}
</style>
<body>
<script>
var width = 960,
height = 500;
var scale = 0.3;
var sphere = {type: 'Sphere'};
var projection = d3.geo.azimuthalEquidistant()
.scale(width * scale)
.translate([width / 2, height / 2])
.precision(1)
.clipAngle(120);
var graticule = d3.geo.graticule();
var canvas1 = d3.select('body').append('canvas')
.attr({width: width, height: height});
var canvas2 = d3.select('body').append('canvas').attr('class', 'blur')
.attr('width', width)
.attr('height', height);
var canvas3 = d3.select('body').append('canvas')
.attr('width', width)
.attr('height', height)
.call(d3.behavior.zoom()
.scaleExtent([1, 20.0])
.on('zoom', function() {
scale = d3.event.scale*0.3;
})
);
var context1 = canvas1.node().getContext('2d');
var context2 = canvas2.node().getContext('2d');
var context3 = canvas3.node().getContext('2d');
var path = d3.geo.path()
.projection(projection);
context1.beginPath();
path.context(context1)(sphere);
context1.lineWidth = 3;
context1.strokeStyle = '#000';
context1.stroke();
context1.beginPath();
path(sphere);
context1.fillStyle = 'rgba(70,130,180,.5)';
context1.fill();
context2.fillStyle = 'rgba(0,0,0,.4)';
context3.strokeStyle = 'rgba(0,0,0,.2)';
d3.json('/osoken/raw/f141a4f3faed8cedf8a73aaf6344cf0f/ne_110m_land.json', function(error, world) {
if (error) throw error;
var land = topojson.feature(world, world.objects.ne_110m_land),
grid = graticule();
var draw = function() {
var x = gyro.x();
var y = gyro.y();
context2.clearRect(0, 0, width, height);
context3.clearRect(0, 0, width, height);
projection.rotate([x, y]);
projection.scale(width * (scale * 1.2));
context2.beginPath();
path.context(context2)(land);
context2.fill();
context3.beginPath();
path.context(context3)(grid);
context3.lineWidth = 2.5;
context3.stroke();
projection.scale(width * scale);
context3.beginPath();
path(land);
context3.fillStyle = '#dadac4';
context3.fill();
}
setInterval(draw, 1000/30);
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment