Drawing bezier polyline between two points in Google Maps.

by dzul1983

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.24/vue.min.js"></script>
<div id="map_canvas1"></div>

<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>

CSS

html,
body {
  padding: 0;
  margin: 0;
}

#map_canvas1 {
  width: 100%;
  height: 100vh;
}

JavaScript

var mapOptions = {
  zoom: 15,
  center: new google.maps.LatLng(59.65067, 6.354406)
};

// Let's draw the map
var map = new google.maps.Map(document.getElementById("map_canvas1"), mapOptions);

map.addListener('click', e => {
  new google.maps.Marker({
    map: map,
    position: e.latLng
  });

  new google.maps.Polyline({
    map: map,
    geodesic: true,
    icons: [{
      icon: {
        path: google.maps.SymbolPath.FORWARD_OPEN_ARROW
      },
      offset: '100%'
    }],
    path: curvedPath(mapOptions.center.toJSON(), e.latLng.toJSON())
  });
});

var center = new google.maps.Marker({
  position: new google.maps.LatLng(59.65067, 6.354406),
  map: map
});

function curvedPath(start, end) {
  if (start && end) {
    const ticks = 100;
    const d = 0.5;
    let path = [];

    const dlat = end.lat - start.lat;
    const dlng = end.lng - start.lng;

    const cp = {
      lat: start.lat + d * dlat + d * (dlng * (dlng <= 0 ? -1 : 1)),
      lng: start.lng - d * (dlat * (dlng <= 0 ? -1 : 1)) + d * dlng
    };

    for (let i = 0; i < ticks; i++) {
      const tick = i / ticks;

      /* Bezier curve formula */
      // Ref: https://javascript.info/bezier-curve#maths
      path.push({
        lat: Math.pow(1 - tick, 2) * start.lat + 2 * (1 - tick) * tick * cp.lat + Math.pow(tick, 2) * end.lat,
        lng: Math.pow(1 - tick, 2) * start.lng + 2 * (1 - tick) * tick * cp.lng + Math.pow(tick, 2) * end.lng
      });
    }

    return path;
  }
}