From 3cf133a10e41d2256a5154764ab51aca5ff61986 Mon Sep 17 00:00:00 2001 From: dpassoni Date: Thu, 2 Feb 2023 20:31:12 +0100 Subject: [PATCH] Added measure line --- client/public/stylesheets/style.css | 16 +++++++ client/src/map/map.ts | 67 ++++++++++++++++++++++++++++- client/src/units/unit.ts | 9 ++-- 3 files changed, 86 insertions(+), 6 deletions(-) diff --git a/client/public/stylesheets/style.css b/client/public/stylesheets/style.css index 1a05b38e..424efa47 100644 --- a/client/public/stylesheets/style.css +++ b/client/public/stylesheets/style.css @@ -168,3 +168,19 @@ html { display: inline-block; } +.measure-box { + position: absolute; + padding-left: 0.5em; + padding-right: 0.5em; + padding-top: 0.2em; + padding-bottom: 0.2em; + background-color: #151b20; + border-radius: 5px; + width: fit-content; + height: fit-content; + text-align: center; + color: white; + font-size: 12px; + z-index: 2000; + font-weight: 600; +} \ No newline at end of file diff --git a/client/src/map/map.ts b/client/src/map/map.ts index 536e5470..1cf85697 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -1,6 +1,7 @@ import * as L from "leaflet" import { getSelectionWheel, getSelectionScroll, getUnitsManager, getActiveCoalition, getMouseInfoPanel } from ".."; import { spawnAircraft, spawnGroundUnit, spawnSmoke } from "../dcs/dcs"; +import { bearing, distance, zeroAppend } from "../other/utils"; import { payloadNames } from "../units/payloadNames"; import { unitTypes } from "../units/unitTypes"; import { BoxSelect } from "./boxselect"; @@ -26,6 +27,9 @@ export class Map extends L.Map { #measurePoint: L.LatLng | null; #measureIcon: L.Icon; #measureMarker: L.Marker; + #measureLine: L.Polyline = new L.Polyline([], { color: '#2d3e50', weight: 3, opacity: 0.5, smoothFactor: 1, interactive: false }); + #measureLineDiv: HTMLElement; + #lastMousePosition: L.Point = new L.Point(0, 0); constructor(ID: string) { /* Init the leaflet map */ @@ -40,7 +44,12 @@ export class Map extends L.Map { this.#measurePoint = null; this.#measureIcon = new L.Icon({ iconUrl: 'images/pin.png', iconAnchor: [16, 32]}); - this.#measureMarker = new L.Marker([0, 0], {icon: this.#measureIcon}); + this.#measureMarker = new L.Marker([0, 0], {icon: this.#measureIcon, interactive: false}); + this.#measureLineDiv = document.createElement("div"); + this.#measureLineDiv.classList.add("measure-box"); + this.#measureLineDiv.style.display = 'none'; + + document.body.appendChild(this.#measureLineDiv); /* Register event handles */ this.on("click", (e: any) => this.#onClick(e)); @@ -50,6 +59,7 @@ export class Map extends L.Map { this.on('mousedown', (e: any) => this.#onMouseDown(e)); this.on('mouseup', (e: any) => this.#onMouseUp(e)); this.on('mousemove', (e: any) => this.#onMouseMove(e)); + this.on('zoom', (e: any) => this.#onZoom(e)); } setLayer(layerName: string) { @@ -235,6 +245,22 @@ export class Map extends L.Map { selectedUnitPosition = new L.LatLng(selectedUnits[0].latitude, selectedUnits[0].longitude); } getMouseInfoPanel().update(e.latlng, this.#measurePoint, selectedUnitPosition); + + this.#lastMousePosition.x = e.originalEvent.x; + this.#lastMousePosition.y = e.originalEvent.y; + + if ( this.#measurePoint) + this.#drawMeasureLine(); + else + this.#hideMeasureLine(); + } + + #onZoom(e: any) + { + if (this.#measurePoint) + this.#drawMeasureLine(); + else + this.#hideMeasureLine(); } /* Spawn from air base */ @@ -338,4 +364,43 @@ export class Map extends L.Map { spawnGroundUnit(unitType, e.latlng, getActiveCoalition()); }, true); } + + #drawMeasureLine() + { + var mouseLatLng = this.containerPointToLatLng(this.#lastMousePosition); + if (this.#measurePoint != null) + { + var points = [this.#measurePoint, mouseLatLng]; + this.#measureLine.setLatLngs(points); + var dist = distance(this.#measurePoint.lat, this.#measurePoint.lng, mouseLatLng.lat, mouseLatLng.lng); + var bear = bearing(this.#measurePoint.lat, this.#measurePoint.lng, mouseLatLng.lat, mouseLatLng.lng); + var startXY = this.latLngToContainerPoint(this.#measurePoint); + var dx = (this.#lastMousePosition.x - startXY.x); + var dy = (this.#lastMousePosition.y - startXY.y); + + var angle = Math.atan2(dy, dx); + if (angle > Math.PI / 2) + angle = angle - Math.PI; + + if (angle < -Math.PI / 2) + angle = angle + Math.PI; + + this.#measureLineDiv.innerHTML = `${zeroAppend(Math.floor(bear), 3)}° / ${zeroAppend(Math.floor(dist*0.000539957), 3)} NM` + this.#measureLineDiv.style.left = (this.#lastMousePosition.x + startXY.x) / 2 - this.#measureLineDiv.offsetWidth / 2 + "px"; + this.#measureLineDiv.style.top = (this.#lastMousePosition.y + startXY.y) / 2 - this.#measureLineDiv.offsetHeight / 2 + "px"; + this.#measureLineDiv.style.rotate = angle + "rad"; + this.#measureLineDiv.style.display = ""; + } + + if (!this.hasLayer(this.#measureLine)) + this.#measureLine.addTo(this); + } + + #hideMeasureLine() + { + this.#measureLineDiv.style.display = "none"; + + if (this.hasLayer(this.#measureLine)) + this.removeLayer(this.#measureLine) + } } diff --git a/client/src/units/unit.ts b/client/src/units/unit.ts index 19a94a2a..d27d847d 100644 --- a/client/src/units/unit.ts +++ b/client/src/units/unit.ts @@ -218,8 +218,8 @@ export class Unit { #drawPath() { if (this.activePath != null) { - var _points = []; - _points.push(new LatLng(this.latitude, this.longitude)); + var points = []; + points.push(new LatLng(this.latitude, this.longitude)); /* Add markers if missing */ while (this.#pathMarkers.length < Object.keys(this.activePath).length) { @@ -237,8 +237,8 @@ export class Unit { for (let WP in this.activePath) { var destination = this.activePath[WP]; this.#pathMarkers[parseInt(WP) - 1].setLatLng([destination.lat, destination.lng]); - _points.push(new LatLng(destination.lat, destination.lng)); - this.#pathPolyline.setLatLngs(_points); + points.push(new LatLng(destination.lat, destination.lng)); + this.#pathPolyline.setLatLngs(points); } } } @@ -251,7 +251,6 @@ export class Unit { this.#pathPolyline.setLatLngs([]); } - #drawTargets() { for (let typeIndex in this.targets)