JSFiddle - React, Tailwind, and code Playground

by Cavitt

HTML

<b>Latitude: </b><span id="lat"></span><br>
<b>Longitude: </b><span id="lon"></span><br>
<b>Distance: </b><span id="dis"></span> km

JavaScript

var tracker = (function() {
    var watchID;
    var watchCallback;
    var coords = [];
    var distance = 0;

    function calculateDistance(fromPos, toPos) {
        var radius = 6371;
        var toRad = function(number) {
            return number * Math.PI / 180;
        };

        var latDistance = toRad(toPos.latitude - fromPos.latitude);
        var lonDistance = toRad(toPos.longitude - fromPos.longitude);
        var a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) + 
                Math.cos(toRad(fromPos.latitude)) * Math.cos(toRad(toPos.latitude)) * 
                Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);

        return radius * (2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))); 
    }

    function displayError(error) {
        alert("Error occurred. Error code: " + error.code);
        // error.code can be:
        //   0: unknown error
        //   1: permission denied
        //   2: position unavailable (error response from locaton provider)
        //   3: timed out
    }

    function appendPosition(position) {
        // Calculate distance from last position if available
        var lastPos = coords[coords.length-1];
        if(lastPos) {
            distance += calculateDistance(lastPos, position.coords);
        }

        // Add new coordinates to array
        coords.push(position.coords);

        // Call custom callback
        if(watchCallback) {
            watchCallback(position, distance, watchID);
        }
    }

    function startWatcher(callback, options) {
        if ("geolocation" in navigator) {
            // Watch position updates
            watchCallback = callback;
            // Watch for updates
            watchID = navigator.geolocation.watchPosition(appendPosition, displayError, options);
            var registerWatchPosition = function(position) {
                appendPosition(position);
            };
        } else {
            alert('Geolocation is not supported!');
        }
    }

  ...