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