JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>

<head>
  <meta charset="utf-8">
  <link rel="icon" type="image/png" href="/static/favicon.png" />
  <style>
    .land {
      fill: white;
      opacity: .5;
      stroke: #4f2291;
      stroke-opacity: 1;
    }

    .countries path {
      stroke: #4f2291;
      stroke-linejoin: round;
      stroke-width: .5;
      fill: #4f2291;
      opacity: .1;
      pointer-events: none;
    }

    .lines path {
      fill: none;
      stroke: red;
      stroke-opacity: 0.3;
      stroke-dasharray: 5, 5;
    }

    circle {
      stroke: #4f2291;
    }

    .graticule {
      fill: none;
      stroke: #4f2291;
      stroke-width: .5;
      opacity: .2;
    }

    .labels {
      font: 8px sans-serif;
      fill: black;
      opacity: 1;
      cursor: pointer;
    }

    .noclicks {
      pointer-events: none;
    }

    .point {
      opacity: .6;
    }

  </style>
</head>

<body>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script src="https://d3js.org/queue.v1.min.js"></script>
  <script src="https://d3js.org/topojson.v0.min.js"></script>
  <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
  <script>
    (function(global, factory) {
      typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
        typeof define === 'function' && define.amd ? define(factory) :
        (global.versor = factory());
    }(this, (function() {
      'use strict';

      var acos = Math.acos,
        asin = Math.asin,
        atan2 = Math.atan2,
        cos = Math.cos,
        max = Math.max,
        min = Math.min,
        PI = Math.PI,
        sin = Math.sin,
        sqrt = Math.sqrt,
        radians = PI / 180,
        degrees = 180 / PI;

      // Returns the unit quaternion for the given Euler rotation angles [λ, φ, γ].
      function versor(e) {
        var l = e[0] / 2 * radians,
          sl = sin(l),
          cl...

JavaScript

var width = 960,
    height = 500;
  var proj = d3.geoOrthographic().scale(230).translate([width / 2, height / 2]).clipAngle(90);
  var path = d3.geoPath().projection(proj).pointRadius(1.5);
  var graticule = d3.geoGraticule();
  var london = [-0.118667702475932, 51.5019405883275];
  var time = Date.now();
  var rotate = [39.666666666666664, -30];
  var velocity = [.015, -0];
  var lineToLondon = function(d) {
    return path({
      "type": "LineString",
      "coordinates": [london, d.geometry.coordinates]
    });
  }

  function stripWhitespace(str) {
    if (!str) {
      return "";
    }
    return str.replace(" ", "");
  }

  var svg = d3.select("body").append("svg").attr("width", width).attr("height", height)
  svg.call(d3.drag().on("start", dragstarted).on("drag", dragged));
  queue().defer(d3.json, "https://openlayers.org/en/latest/examples/data/topojson/world-110m.json").defer(d3.json, "/static/destinations.json").await(ready);
  var places = {
    "type": "FeatureCollection",
    "features": [{
      "type": "Feature",
      "properties": {
        "name": "San Francisco"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [-122.417168773552248, 37.769195629687431]
      }
    }, {
      "type": "Feature",
      "properties": {
        "name": "Chicago"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [-87.752000832709314, 41.831936519278429]
      }
    }, {
      "type": "Feature",
      "properties": {
        "name": "Los Angeles"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [-118.243683, 34.052235]
      }
    }, {
      "type": "Feature",
      "properties": {
        "name": "Vancouver"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [-123.116226, 49.246292]
      }
    }, {
      "type": "Feature",
      "properties": {
        "name": "Calgary"
      },
      "geometry": {
        "type": "Point",
        "coordinates":...