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.
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> |