Skip to content

Instantly share code, notes, and snippets.

@Fil
Last active January 1, 2020 16:12
Show Gist options
  • Save Fil/f48de8e9207799017093a169031adb02 to your computer and use it in GitHub Desktop.
Save Fil/f48de8e9207799017093a169031adb02 to your computer and use it in GitHub Desktop.
Versor dragging with inertia
license: gpl-3.0

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!

<!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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment