[feat](trx-frontend-http): disable path animations above threshold; wrap axis bookmark labels

Suppress stroke-dashoffset animation and drop-shadow filter on all
contact/radio paths when decodeContactPaths.size > 20 by toggling
.map-paths-static on #aprs-map, avoiding per-frame GPU compositing
with large decode histories.

Wrap non-sideStack bookmark chip labels in
<span class="spectrum-bookmark-name"> and allow word-break on axis
chips so long names split across two lines instead of being clipped.
Axis bar switches to min-height so it grows to fit taller chips.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
This commit is contained in:
2026-03-16 23:33:26 +01:00
parent d131efae36
commit 4a12d79f92
2 changed files with 24 additions and 5 deletions
@@ -4647,6 +4647,14 @@ function clearDecodeContactPaths() {
clearDecodeContactPathRender(entry); clearDecodeContactPathRender(entry);
} }
decodeContactPaths.clear(); decodeContactPaths.clear();
updateMapPathsAnimationClass();
}
const MAP_PATHS_STATIC_THRESHOLD = 20;
function updateMapPathsAnimationClass() {
const mapEl = document.getElementById("aprs-map");
if (!mapEl) return;
mapEl.classList.toggle("map-paths-static", decodeContactPaths.size > MAP_PATHS_STATIC_THRESHOLD);
} }
function formatDecodeContactDistance(distanceKm) { function formatDecodeContactDistance(distanceKm) {
@@ -4756,6 +4764,7 @@ function syncDecodeContactPathVisibility() {
ensureDecodeContactPathRendered(entry); ensureDecodeContactPathRendered(entry);
} }
renderMapQsoSummary(); renderMapQsoSummary();
updateMapPathsAnimationClass();
} }
function setMapRadioPathTo(lat, lon, color, className = "aprs-radio-path") { function setMapRadioPathTo(lat, lon, color, className = "aprs-radio-path") {
@@ -8646,7 +8655,7 @@ function createBookmarkChip(bm, colorMap, options = {}) {
: ( : (
"<svg class='bm-icon-svg' viewBox='0 0 8 12' width='8' height='12' aria-hidden='true'>" + "<svg class='bm-icon-svg' viewBox='0 0 8 12' width='8' height='12' aria-hidden='true'>" +
"<path d='M0,0 h8 v10 l-4,2 l-4,-2 Z'/>" + "<path d='M0,0 h8 v10 l-4,2 l-4,-2 Z'/>" +
"</svg>\u00a0" + esc(bm.name) "</svg>\u00a0<span class='spectrum-bookmark-name'>" + esc(bm.name) + "</span>"
); );
span.innerHTML = span.innerHTML =
labelHtml; labelHtml;
@@ -2079,6 +2079,12 @@ body.map-fake-fullscreen-active {
.trx-receiver-marker { stroke: var(--accent-green) !important; fill: var(--accent-green) !important; } .trx-receiver-marker { stroke: var(--accent-green) !important; fill: var(--accent-green) !important; }
.receiver-popup-active { font-size: 0.75em; background: rgba(194,75,26,0.15); color: var(--accent-green); border: 1px solid rgba(194,75,26,0.3); border-radius: 3px; padding: 0 0.25rem; margin-left: 0.3rem; vertical-align: middle; } .receiver-popup-active { font-size: 0.75em; background: rgba(194,75,26,0.15); color: var(--accent-green); border: 1px solid rgba(194,75,26,0.3); border-radius: 3px; padding: 0 0.25rem; margin-left: 0.3rem; vertical-align: middle; }
@keyframes aprs-radio-path-flow { to { stroke-dashoffset: -15; } } @keyframes aprs-radio-path-flow { to { stroke-dashoffset: -15; } }
.map-paths-static .decode-contact-path,
.map-paths-static .aprs-radio-path,
.map-paths-static .locator-radio-path {
animation: none;
filter: none;
}
@keyframes trx-locator-breathe { @keyframes trx-locator-breathe {
0%, 100% { stroke-width: 2.4px; stroke-opacity: 0.78; filter: drop-shadow(0 0 2px color-mix(in srgb, var(--accent-green) 18%, transparent)); } 0%, 100% { stroke-width: 2.4px; stroke-opacity: 0.78; filter: drop-shadow(0 0 2px color-mix(in srgb, var(--accent-green) 18%, transparent)); }
50% { stroke-width: 4.2px; stroke-opacity: 1; filter: drop-shadow(0 0 10px color-mix(in srgb, var(--accent-green) 52%, transparent)); } 50% { stroke-width: 4.2px; stroke-opacity: 1; filter: drop-shadow(0 0 10px color-mix(in srgb, var(--accent-green) 52%, transparent)); }
@@ -2895,13 +2901,13 @@ button:focus-visible, input:focus-visible, select:focus-visible {
transition: height 80ms ease; transition: height 80ms ease;
} }
#spectrum-bookmark-axis.bm-axis-visible { #spectrum-bookmark-axis.bm-axis-visible {
height: 26px; min-height: 26px;
height: auto;
} }
.spectrum-bookmark-chip { .spectrum-bookmark-chip {
position: absolute; position: absolute;
transform: translateX(-50%); transform: translateX(-50%);
top: 2px; top: 2px;
white-space: nowrap;
cursor: pointer; cursor: pointer;
font-weight: 600; font-weight: 600;
font-size: 0.66rem; font-size: 0.66rem;
@@ -2912,15 +2918,19 @@ button:focus-visible, input:focus-visible, select:focus-visible {
padding: 2px 8px; padding: 2px 8px;
max-width: 130px; max-width: 130px;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis;
line-height: 1.4; line-height: 1.4;
display: inline-flex; display: inline-flex;
align-items: center; align-items: flex-start;
gap: 4px; gap: 4px;
} }
.spectrum-bookmark-chip:hover { .spectrum-bookmark-chip:hover {
filter: brightness(1.15); filter: brightness(1.15);
} }
.spectrum-bookmark-chip .spectrum-bookmark-name {
white-space: normal;
word-break: break-word;
line-height: 1.2;
}
.spectrum-bookmark-side { .spectrum-bookmark-side {
position: absolute; position: absolute;
top: calc(var(--spectrum-plot-height) / 2); top: calc(var(--spectrum-plot-height) / 2);