block by Fil f48de8e9207799017093a169031adb02

Versor dragging with inertia

Full Screen

Using the d3-inertia plugin.

Original research by Philippe Rivière for visionscarto.net.


Add inertia issue #27 to versor rotation of the globe.

Includes a modified versor.js, allowing the multiplication of the final rotation by a delta to the power alpha.

Moving average for velocity (exponential decay)

Trying to plug it in as cleanly as possible into d3.drag

Try it on mobile!

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="https://cdn.jsdelivr.net/npm/d3@5"></script>
<script src="https://cdn.jsdelivr.net/npm/topojson@3"></script>
<script src="https://cdn.jsdelivr.net/npm/versor@0.1"></script>
<script src="https://cdn.jsdelivr.net/npm/d3-inertia@0.1"></script>
<script>

var width = 960,
    height = 500;

var projection = d3.geoOrthographic();

var canvas = d3.select("body").append("canvas")
    .attr("width", width)
    .attr("height", height);

var context = canvas.node().getContext("2d");
 
var path = d3.geoPath()
    .projection(projection)
    .context(context); 

// rendering function to be populated when the features are loaded  
var render = function(){};

// inertia versor dragging
var inertia = d3.geoInertiaDrag(canvas, function() { render(); }, projection);

d3.json("https://cdn.jsdelivr.net/npm/world-atlas@1/world/110m.json").then(function(world) {

  var land = topojson.feature(world, world.objects.land);
  
  render = function() {
    context.clearRect(0, 0, width, height);

    context.beginPath();
    path(land);
    context.fill();

   context.strokeStyle = 'black';
    context.beginPath();
    path({type:"Sphere"});
    context.lineWidth = 2.5;
    context.stroke();

    // draw a red line showing current inertia
    if (typeof inertia == 'object') {
      context.beginPath();
      context.moveTo(
        inertia.position[0] + inertia.velocity[0] / 10,
        inertia.position[1] + inertia.velocity[1] / 10
      );
      context.lineTo(
        inertia.position[0] + inertia.velocity[0] * inertia.t / 10,
        inertia.position[1] + inertia.velocity[1] * inertia.t / 10
      );
      context.strokeStyle = "red"; 
      context.stroke(); 
    }
    
    var p = projection.rotate().map(d => Math.floor(10*d)/10);
    context.fillText(`λ = ${p[0]}, φ = ${p[1]}, γ = ${p[2]}`, 10, 10 )
  };
  
  render();
  
}); 


  
d3.select(self.frameElement).style("height", height + "px");

</script>