// engine.js let socket = new WebSocket("wss://trackme.ovh/ws"); const arrows = ["↑", "↗", "→", "↘", "↓", "↙", "←", "↖"]; let togglefollowbtn; class Position { constructor(type, iconUrl, iconRetinaUrl) { this.type = type; this.iconUrl = iconUrl; this.iconRetinaUrl = iconRetinaUrl; this.text = ""; } setData(obj) { this.data = obj; } setDefaultData() { this.data = {latitude:49, longitude:0}; } static getMiddle(t, u) { const mid = {coords: [49, 0]}; if (t.coords && u.coords) { for (const i in mid.coords) { mid.coords[i] = Math.min(t.coords[i], u.coords[i]) + (Math.abs(t.coords[i] - u.coords[i])/2); } } else mid.coords = t.coords; return mid.coords; } createLocation() { const icon = new L.Icon.Default; icon.options.iconUrl = this.iconUrl; icon.options.iconRetinaUrl = this.iconRetinaUrl; try { this.point = L.marker(this.coords, { color: "red", fillColor: "#f03", fillOpacity: 0.5, radius: 50, icon: icon }).addTo(map).bindPopup(this.text); this.point.getPopup().autoPan = false; //this.point.openPopup(); } catch (err) { console.log(`unable to create point (${err})`); } } } let map; let follow = true; const tracker = new Position("tracker", "marker-icon.png", "marker-icon-2x.png"); const user = new Position("user", "marker-icon-alt.png", "marker-icon-2x-alt.png"); function userGPSsuccess(pos) { user.data = { latitude: pos.coords.latitude, longitude: pos.coords.longitude, height: pos.coords.altitude, speed: pos.coords.speed, direction: pos.coords.heading, }; user.coords = [pos.coords.latitude, pos.coords.longitude]; } function userGPSerror(err) { console.log(err); user.setDefaultData(); } function getPosition() { if (navigator.geolocation) { return new Promise((resolve, _reject) => { navigator.geolocation.getCurrentPosition(userGPSsuccess, userGPSerror); resolve("Position fetched"); }); } } function createMap(coords) { map = L.map("map", { center: coords, zoom: 10 }); L.tileLayer(`https://tile.openstreetmap.org/{z}/{x}/{y}.png`, { maxZoom: 19, attribution: `© OpenStreetMap / PaulBSD` }).addTo(map); map.zoomControl.setPosition('bottomright'); map.addEventListener("zoomlevelschange", (_event) => { update(); }); } function update() { if (tracker.data) { tracker.coords = [tracker.data.latitude, tracker.data.longitude]; tracker.data.speed = tracker.data.speed/10; tracker.section = parseInt(tracker.data.direction/45 + 0.5) % 8; tracker.text = `Tracker
time: ${tracker.data.time}
latitude: ${tracker.data.latitude}
longitude: ${tracker.data.longitude}
height: ${tracker.data.height}
speed: ${tracker.data.speed}
direction: ${arrows[tracker.section]} ${tracker.data.direction}°
serial: ${tracker.data.serial}`; } //user.text = `You
latitude: ${user.data.latitude}
longitude: ${user.data.longitude}
height: ${user.data.height}
speed: ${user.data.speed}
direction: ${arrows[user.section]} ${user.data.direction}°`; if (user.data) { user.text = `You
latitude: ${user.data.latitude}
longitude: ${user.data.longitude}`; } if (tracker.data) { const center = [tracker.data.latitude, tracker.data.longitude]; if (!map) { createMap(center); } } if (map && follow) { const coords = Position.getMiddle(tracker, user); try { map.setView(coords); map.flyTo(coords); map.fitBounds([tracker.coords, user.coords]); } catch (e) { console.log(e, coords); } } if (!tracker.point && tracker.data) { tracker.createLocation(); } else { if (tracker.coords) { tracker.point.setLatLng(tracker.coords); tracker.point.setPopupContent(tracker.text); } } if (!user.point && user.data) { user.createLocation(); } else { if (user.coords) { user.point.setLatLng(user.coords); user.point.setPopupContent(user.text); } } } function ping() { try { if (socket.readyState > 1) { throw "closed socket"; } socket.send("ping") } catch (err) { console.log(err); socket = new WebSocket("wss://trackme.ovh/ws"); } } function followButton() { if (follow) togglefollowbtn.innerHTML = "Unfollow tracker"; else togglefollowbtn.innerHTML = "Follow tracker"; } function main() { togglefollowbtn = document.querySelector("#togglefollowbtn"); follow = JSON.parse(localStorage.getItem("follow")); followButton(); togglefollowbtn.addEventListener("click", function() { follow = !follow; localStorage.setItem("follow", follow); followButton(); }); socket.addEventListener("message", (event) => { tracker.data = JSON.parse(event.data); update(); }); socket.addEventListener("open", (_event) => { ping(); }); setInterval(getPosition, 1000); setInterval(ping, 1000); setInterval(update, 1000); } main();