From c67fa39e30bb121d36b02719de0f1624dd74a3cc Mon Sep 17 00:00:00 2001 From: Smittix Date: Thu, 29 Jan 2026 09:07:47 +0000 Subject: [PATCH] feat: Add pulsating ring effect for tracked aircraft/vessels Makes it much clearer which vehicle is being tracked on the map by adding two animated concentric rings that pulse outward from the selected marker. Co-Authored-By: Claude Opus 4.5 --- static/css/adsb_dashboard.css | 49 +++++++++++++++++++++++++++++++++++ static/css/ais_dashboard.css | 49 +++++++++++++++++++++++++++++++++++ templates/adsb_dashboard.html | 4 ++- templates/ais_dashboard.html | 4 ++- 4 files changed, 104 insertions(+), 2 deletions(-) diff --git a/static/css/adsb_dashboard.css b/static/css/adsb_dashboard.css index a268aba..95c31d0 100644 --- a/static/css/adsb_dashboard.css +++ b/static/css/adsb_dashboard.css @@ -1146,6 +1146,55 @@ body { 50% { opacity: 0.5; transform: scale(0.8); } } +/* ============================================ + TRACKED AIRCRAFT PULSATING RING + ============================================ */ +.aircraft-marker.selected { + position: relative; +} + +.tracking-ring { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 40px; + height: 40px; + border: 2px solid var(--accent-cyan); + border-radius: 50%; + animation: tracking-pulse 1.5s ease-out infinite; + pointer-events: none; +} + +.tracking-ring-inner { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 28px; + height: 28px; + border: 1px solid var(--accent-cyan); + border-radius: 50%; + animation: tracking-pulse 1.5s ease-out infinite 0.3s; + pointer-events: none; +} + +@keyframes tracking-pulse { + 0% { + transform: translate(-50%, -50%) scale(0.8); + opacity: 1; + border-color: rgba(74, 158, 255, 1); + } + 50% { + opacity: 0.6; + } + 100% { + transform: translate(-50%, -50%) scale(1.8); + opacity: 0; + border-color: rgba(74, 158, 255, 0); + } +} + /* ============== MOBILE/TABLET FIXES ============== */ @media (max-width: 1023px) { /* Dashboard - allow scrolling */ diff --git a/static/css/ais_dashboard.css b/static/css/ais_dashboard.css index 87ead8d..99ff90e 100644 --- a/static/css/ais_dashboard.css +++ b/static/css/ais_dashboard.css @@ -759,6 +759,55 @@ body { filter: drop-shadow(0 0 8px rgba(255,255,255,0.8)) !important; } +/* ============================================ + TRACKED VESSEL PULSATING RING + ============================================ */ +.vessel-marker.selected { + position: relative; +} + +.tracking-ring { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 40px; + height: 40px; + border: 2px solid var(--accent-cyan); + border-radius: 50%; + animation: tracking-pulse 1.5s ease-out infinite; + pointer-events: none; +} + +.tracking-ring-inner { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 28px; + height: 28px; + border: 1px solid var(--accent-cyan); + border-radius: 50%; + animation: tracking-pulse 1.5s ease-out infinite 0.3s; + pointer-events: none; +} + +@keyframes tracking-pulse { + 0% { + transform: translate(-50%, -50%) scale(0.8); + opacity: 1; + border-color: rgba(74, 158, 255, 1); + } + 50% { + opacity: 0.6; + } + 100% { + transform: translate(-50%, -50%) scale(1.8); + opacity: 0; + border-color: rgba(74, 158, 255, 0); + } +} + /* Range rings */ .range-ring { fill: none; diff --git a/templates/adsb_dashboard.html b/templates/adsb_dashboard.html index 8b96f94..9ce5ebe 100644 --- a/templates/adsb_dashboard.html +++ b/templates/adsb_dashboard.html @@ -2970,9 +2970,11 @@ sudo make install const size = iconType === 'helicopter' ? 22 : 24; const glowColor = isSelected ? 'rgba(255,255,255,0.9)' : color; const glowSize = isSelected ? '10px' : '5px'; + const trackingRing = isSelected ? + '
' : ''; return L.divIcon({ className: `aircraft-marker aircraft-${iconType}${isSelected ? ' selected' : ''}`, - html: ` + html: `${trackingRing} `, iconSize: [size, size], diff --git a/templates/ais_dashboard.html b/templates/ais_dashboard.html index ea32c21..64c5ae3 100644 --- a/templates/ais_dashboard.html +++ b/templates/ais_dashboard.html @@ -329,10 +329,12 @@ const size = 24; const glowColor = isSelected ? 'rgba(255,255,255,0.8)' : color; const glowSize = isSelected ? '8px' : '4px'; + const trackingRing = isSelected ? + '
' : ''; return L.divIcon({ className: 'vessel-marker' + (isSelected ? ' selected' : ''), - html: ` + html: `${trackingRing} `, iconSize: [size, size],