@@ -252,6 +252,7 @@ const showButtons = computed(() => isMouseOver.value || downloadMenuOpen.value)
252252const mapReady = ref (false )
253253const mapWaypoints = ref <Waypoint []>([])
254254const reachedWaypoints = shallowRef <Record <number , L .Marker >>({})
255+ const persistentTooltipSeq = ref <number | undefined >(undefined )
255256const contextMenuRef = ref ()
256257const isDragging = ref (false )
257258const isPinching = ref (false )
@@ -394,24 +395,102 @@ const applyWaypointMarkerStyle = (seq: number): void => {
394395 })
395396 )
396397
397- // Updates the tooltip class for reached/current waypoints and visibility based on size
398- const tooltip = marker .getTooltip ()
399- if (tooltip ) {
400- if (markerSize === ' xs' || markerSize === ' sm' ) {
401- tooltip .setOpacity (0 )
398+ // Updates the tooltip for reached/current waypoints and visibility based on size
399+ const isPersistent = persistentTooltipSeq .value === seq
400+ marker .off (' mouseover' )
401+ marker .off (' mouseout' )
402+ marker .unbindTooltip ()
403+
404+ if (markerSize === ' xs' || markerSize === ' sm' ) {
405+ if (isPersistent ) {
406+ const permanentTooltip = L .tooltip ({
407+ content: seq .toString (),
408+ permanent: true ,
409+ direction: ' top' ,
410+ className: ' waypoint-hover-tooltip' ,
411+ opacity: 1 ,
412+ interactive: false ,
413+ })
414+ marker .bindTooltip (permanentTooltip )
415+ marker .openTooltip ()
402416 } else {
403- tooltip .setOpacity (1 )
417+ const hoverTooltip = L .tooltip ({
418+ content: seq .toString (),
419+ permanent: false ,
420+ direction: ' top' ,
421+ className: ' waypoint-hover-tooltip' ,
422+ interactive: false ,
423+ })
424+ marker .bindTooltip (hoverTooltip )
425+ marker .on (' mouseover' , () => {
426+ marker .openTooltip ()
427+ })
428+ marker .on (' mouseout' , () => {
429+ marker .closeTooltip ()
430+ })
404431 }
405432
406- const tooltipElement = tooltip .getElement ()
407- if (tooltipElement ) {
408- tooltipElement .classList .remove (' waypoint-tooltip--reached' , ' waypoint-tooltip--current-waypoint' )
409- if (isReached ) {
410- tooltipElement .classList .add (' waypoint-tooltip--reached' )
411- } else if (isCurrent ) {
412- tooltipElement .classList .add (' waypoint-tooltip--current-waypoint' )
433+ marker .off (' click' )
434+ marker .on (' click' , (event : L .LeafletMouseEvent ) => {
435+ L .DomEvent .stopPropagation (event )
436+ persistentTooltipSeq .value = persistentTooltipSeq .value === seq ? undefined : seq
437+ refreshReachedWaypointMarkerStyles ()
438+ if (persistentTooltipSeq .value === seq ) {
439+ nextTick (() => {
440+ const persistentMarker = reachedWaypoints .value [seq ]
441+ if (persistentMarker ) {
442+ const tip = persistentMarker .getTooltip ()
443+ if (tip ) {
444+ persistentMarker .openTooltip ()
445+ const tipEl = tip .getElement ()
446+ if (tipEl ) {
447+ tipEl .style .display = ' block'
448+ tipEl .style .opacity = ' 1'
449+ }
450+ }
451+ }
452+ })
413453 }
454+ })
455+ } else {
456+ let tooltipClass = ' waypoint-tooltip'
457+ if (isReached ) {
458+ tooltipClass = ' waypoint-tooltip waypoint-tooltip--reached'
459+ } else if (isCurrent ) {
460+ tooltipClass = ' waypoint-tooltip waypoint-tooltip--current-waypoint'
414461 }
462+
463+ const permanentTooltip = L .tooltip ({
464+ content: seq .toString (),
465+ permanent: true ,
466+ direction: ' center' ,
467+ className: tooltipClass ,
468+ opacity: 1 ,
469+ })
470+ marker .bindTooltip (permanentTooltip )
471+
472+ marker .off (' click' )
473+ marker .on (' click' , (event : L .LeafletMouseEvent ) => {
474+ L .DomEvent .stopPropagation (event )
475+ persistentTooltipSeq .value = persistentTooltipSeq .value === seq ? undefined : seq
476+ refreshReachedWaypointMarkerStyles ()
477+ if (persistentTooltipSeq .value === seq ) {
478+ nextTick (() => {
479+ const persistentMarker = reachedWaypoints .value [seq ]
480+ if (persistentMarker ) {
481+ const tip = persistentMarker .getTooltip ()
482+ if (tip ) {
483+ persistentMarker .openTooltip ()
484+ const tipEl = tip .getElement ()
485+ if (tipEl ) {
486+ tipEl .style .display = ' block'
487+ tipEl .style .opacity = ' 1'
488+ }
489+ }
490+ }
491+ })
492+ }
493+ })
415494 }
416495}
417496
@@ -631,15 +710,66 @@ onMounted(async () => {
631710
632711 map .value .on (' click' , (event : LeafletMouseEvent ) => {
633712 clickedLocation .value = [event .latlng .lat , event .latlng .lng ]
713+ if (persistentTooltipSeq .value !== undefined ) {
714+ persistentTooltipSeq .value = undefined
715+ refreshReachedWaypointMarkerStyles ()
716+ }
717+ })
718+
719+ // Keep persistent tooltips visible during map drag
720+ let tooltipReopenTimeout: ReturnType <typeof setTimeout > | undefined
721+ const keepPersistentTooltipVisible = (): void => {
722+ if (persistentTooltipSeq .value !== undefined ) {
723+ const marker = reachedWaypoints .value [persistentTooltipSeq .value ]
724+ if (marker ) {
725+ const tooltip = marker .getTooltip ()
726+ if (tooltip ) {
727+ marker .openTooltip ()
728+ const tooltipElement = tooltip .getElement ()
729+ if (tooltipElement ) {
730+ tooltipElement .style .display = ' block'
731+ tooltipElement .style .opacity = ' 1'
732+ }
733+ }
734+ }
735+ }
736+ }
737+
738+ map .value .on (' movestart' , () => {
739+ keepPersistentTooltipVisible ()
740+ })
741+
742+ map .value .on (' move' , () => {
743+ if (persistentTooltipSeq .value !== undefined ) {
744+ if (tooltipReopenTimeout ) {
745+ clearTimeout (tooltipReopenTimeout )
746+ }
747+ tooltipReopenTimeout = setTimeout (() => {
748+ keepPersistentTooltipVisible ()
749+ }, 50 )
750+ }
634751 })
635752
636753 // Update center value after panning
637754 map .value .on (' moveend' , () => {
755+ if (tooltipReopenTimeout ) {
756+ clearTimeout (tooltipReopenTimeout )
757+ tooltipReopenTimeout = undefined
758+ }
638759 if (map .value === undefined ) return
639760 let { lat, lng } = map .value .getCenter ()
640761 if (lat && lng ) {
641762 mapCenter .value = [lat , lng ]
642763 }
764+ if (persistentTooltipSeq .value !== undefined ) {
765+ const marker = reachedWaypoints .value [persistentTooltipSeq .value ]
766+ if (marker ) {
767+ const tooltip = marker .getTooltip ()
768+ if (tooltip ) {
769+ marker .openTooltip ()
770+ }
771+ }
772+ }
643773 })
644774
645775 // Builds map layers offline content controls
@@ -686,6 +816,7 @@ onMounted(async () => {
686816
687817 map .value .on (' dragstart' , () => {
688818 isDragging .value = true
819+ keepPersistentTooltipVisible ()
689820 })
690821
691822 map .value .on (' dragend' , () => {
@@ -1236,38 +1367,60 @@ watch(
12361367 reachedWaypoints .value [seq ] = marker
12371368
12381369 const markerSizeForTooltip = getMarkerSizeFromZoom (zoom .value )
1239- const markerTooltip = L .tooltip ({
1240- content: seq .toString (),
1241- permanent: true ,
1242- direction: ' center' ,
1243- className: isReached
1244- ? ' waypoint-tooltip waypoint-tooltip--reached'
1245- : isCurrent
1246- ? ' waypoint-tooltip waypoint-tooltip--current-waypoint'
1247- : ' waypoint-tooltip' ,
1248- opacity: markerSizeForTooltip === ' md' ? 1 : 0 ,
1370+
1371+ marker .off (' click' )
1372+ marker .on (' click' , (event : L .LeafletMouseEvent ) => {
1373+ L .DomEvent .stopPropagation (event )
1374+ persistentTooltipSeq .value = persistentTooltipSeq .value === seq ? undefined : seq
1375+ refreshReachedWaypointMarkerStyles ()
12491376 })
12501377
1251- marker .bindTooltip (markerTooltip )
12521378 marker .on (' contextmenu' , (e : L .LeafletMouseEvent ) => {
12531379 L .DomEvent .stopPropagation (e )
12541380 e .originalEvent .stopPropagation ()
12551381 e .originalEvent .preventDefault ()
12561382 openContextMenuAt (e .originalEvent , seq )
12571383 })
1384+
1385+ if (markerSizeForTooltip === ' xs' || markerSizeForTooltip === ' sm' ) {
1386+ const hoverTooltip = L .tooltip ({
1387+ content: seq .toString (),
1388+ permanent: false ,
1389+ direction: ' top' ,
1390+ className: ' waypoint-hover-tooltip' ,
1391+ interactive: false ,
1392+ })
1393+ marker .bindTooltip (hoverTooltip )
1394+ marker .on (' mouseover' , () => {
1395+ if (persistentTooltipSeq .value !== seq ) {
1396+ marker .openTooltip ()
1397+ }
1398+ })
1399+ marker .on (' mouseout' , () => {
1400+ if (persistentTooltipSeq .value !== seq ) {
1401+ marker .closeTooltip ()
1402+ }
1403+ })
1404+ } else {
1405+ let tooltipClass = ' waypoint-tooltip'
1406+ if (isReached ) {
1407+ tooltipClass = ' waypoint-tooltip waypoint-tooltip--reached'
1408+ } else if (isCurrent ) {
1409+ tooltipClass = ' waypoint-tooltip waypoint-tooltip--current-waypoint'
1410+ }
1411+ const permanentTooltip = L .tooltip ({
1412+ content: seq .toString (),
1413+ permanent: true ,
1414+ direction: ' center' ,
1415+ className: tooltipClass ,
1416+ opacity: 1 ,
1417+ })
1418+ marker .bindTooltip (permanentTooltip )
1419+ }
1420+
12581421 map .value ?.addLayer (marker )
12591422 } else {
12601423 marker .setLatLng (waypoint .coordinates as LatLngTuple )
1261- const markerSizeForUpdate = getMarkerSizeFromZoom (zoom .value )
1262- const tooltip = marker .getTooltip ()
1263- if (tooltip ) {
1264- if (markerSizeForUpdate === ' xs' || markerSizeForUpdate === ' sm' ) {
1265- tooltip .setOpacity (0 )
1266- } else {
1267- tooltip .setContent (seq .toString ())
1268- tooltip .setOpacity (1 )
1269- }
1270- }
12711424 applyWaypointMarkerStyle (seq )
12721425 }
12731426 })
@@ -1277,28 +1430,7 @@ watch(
12771430
12781431// Keep an eye on the current mission status and update the waypoint markers accordingly
12791432watch ([vehicleStore .currentMissionSeq , currentVehicleWpIndex , getReachedWaypointIndices , currentMapWpIndex ], () => {
1280- Object .entries (reachedWaypoints .value ).forEach (([seqStr , marker ]) => {
1281- const seq = Number (seqStr )
1282- const idx = seq - 1
1283- const isCurrent = currentMapWpIndex .value >= 0 && idx === currentMapWpIndex .value
1284- const isReached = getReachedWaypointIndices .value .has (seq )
1285-
1286- applyWaypointMarkerStyle (seq )
1287-
1288- const tooltip = marker .getTooltip ()
1289- if (tooltip ) {
1290- const tooltipElement = tooltip .getElement ()
1291- if (tooltipElement ) {
1292- tooltipElement .classList .remove (' waypoint-tooltip--reached' , ' waypoint-tooltip--current-waypoint' )
1293- if (isReached ) {
1294- tooltipElement .classList .add (' waypoint-tooltip--reached' )
1295- } else if (isCurrent ) {
1296- tooltipElement .classList .add (' waypoint-tooltip--current-waypoint' )
1297- }
1298- }
1299- tooltip .update ()
1300- }
1301- })
1433+ refreshReachedWaypointMarkerStyles ()
13021434})
13031435
13041436// Create polyline for the vehicle path
@@ -1900,6 +2032,18 @@ watch(
19002032 box-shadow : 0 0 6px rgba (255 , 255 , 255 , 0.2 );
19012033}
19022034
2035+ :deep(.waypoint-hover-tooltip ) {
2036+ background-color : #1e498f ;
2037+ color : white ;
2038+ border : 1px solid rgba (255 , 255 , 255 , 0.3 );
2039+ border-radius : 8px ;
2040+ padding : 4px 8px ;
2041+ font-size : 12px ;
2042+ font-weight : bold ;
2043+ margin-top : -12px ;
2044+ box-shadow : 0 2px 4px rgba (0 , 0 , 0 , 0.3 );
2045+ }
2046+
19032047:global(.marker-icon ) {
19042048 background-color : #1e498f ;
19052049 border : 1px solid #ffffff55 ;
0 commit comments