Rate monitor: peak-hold tick on the equalizer bars (the VU idiom)
A thin accent marker sticks at each bar's recent maximum, holds ~1.2s, then falls a few percent per update until it rests on the live fill — exactly how a hardware VU meter's peak LED behaves. A traffic burst stays readable for a few seconds after it's over instead of vanishing with the next 1s sample. Hidden while it sits on the fill so idle bars don't carry a stray line.
This commit is contained in:
parent
01ae63f0d5
commit
12ad373a83
2 changed files with 45 additions and 1 deletions
|
|
@ -236,6 +236,7 @@ function _renderEqualizerBars(grid, data) {
|
||||||
<div class="rate-eq-shimmer"></div>
|
<div class="rate-eq-shimmer"></div>
|
||||||
<div class="rate-eq-tip"></div>
|
<div class="rate-eq-tip"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="rate-eq-peak"></div>
|
||||||
<div class="rate-eq-value">0</div>
|
<div class="rate-eq-value">0</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="rate-eq-meta">
|
<div class="rate-eq-meta">
|
||||||
|
|
@ -275,6 +276,26 @@ function _renderEqualizerBars(grid, data) {
|
||||||
const fill = bar.querySelector('.rate-eq-fill');
|
const fill = bar.querySelector('.rate-eq-fill');
|
||||||
if (fill) fill.style.height = `${pct * 100}%`;
|
if (fill) fill.style.height = `${pct * 100}%`;
|
||||||
|
|
||||||
|
// Peak-hold tick — the VU-meter idiom: a thin marker sticks at the
|
||||||
|
// recent maximum, holds ~1.2s, then falls a few %/update until it
|
||||||
|
// rests on the live fill. A burst stays readable after it's over.
|
||||||
|
const nowTs = performance.now();
|
||||||
|
let peak = prev.peak ?? pct;
|
||||||
|
let peakAt = prev.peakAt ?? nowTs;
|
||||||
|
if (pct >= peak) {
|
||||||
|
peak = pct;
|
||||||
|
peakAt = nowTs;
|
||||||
|
} else if (nowTs - peakAt > 1200) {
|
||||||
|
peak = Math.max(pct, peak - 0.045);
|
||||||
|
}
|
||||||
|
const peakEl = bar.querySelector('.rate-eq-peak');
|
||||||
|
if (peakEl) {
|
||||||
|
peakEl.style.bottom = `${peak * 100}%`;
|
||||||
|
// Only show while meaningfully above the live fill — idle bars
|
||||||
|
// shouldn't carry a stray line.
|
||||||
|
peakEl.classList.toggle('visible', peak > pct + 0.015 && peak > 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
// The reflection puddle (CSS ::after on the track) fades in
|
// The reflection puddle (CSS ::after on the track) fades in
|
||||||
// proportional to the real (unclamped) rate so idle services
|
// proportional to the real (unclamped) rate so idle services
|
||||||
// don't pollute the row with a floor of glow. Bound to a
|
// don't pollute the row with a floor of glow. Bound to a
|
||||||
|
|
@ -329,7 +350,7 @@ function _renderEqualizerBars(grid, data) {
|
||||||
bar.classList.toggle('active', value > 0 || wStatus === 'running');
|
bar.classList.toggle('active', value > 0 || wStatus === 'running');
|
||||||
bar.classList.toggle('rate-limited', isRateLimited);
|
bar.classList.toggle('rate-limited', isRateLimited);
|
||||||
|
|
||||||
_eqDisplay[svc] = { value, pct };
|
_eqDisplay[svc] = { value, pct, peak, peakAt };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63242,6 +63242,29 @@ body.reduce-effects .dash-card::after {
|
||||||
opacity: 0.85;
|
opacity: 0.85;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Peak-hold tick — sticks at the recent maximum and slowly falls, like a
|
||||||
|
* hardware VU meter's peak LED. Position (bottom %) is driven from JS;
|
||||||
|
* only visible while it's meaningfully above the live fill so idle bars
|
||||||
|
* don't carry a stray line. */
|
||||||
|
.rate-eq-peak {
|
||||||
|
position: absolute;
|
||||||
|
left: 10%;
|
||||||
|
right: 10%;
|
||||||
|
bottom: 4%;
|
||||||
|
height: 2px;
|
||||||
|
border-radius: 1px;
|
||||||
|
background: color-mix(in srgb, var(--eq-accent) 55%, white 45%);
|
||||||
|
box-shadow: 0 0 6px color-mix(in srgb, var(--eq-accent) 70%, transparent);
|
||||||
|
opacity: 0;
|
||||||
|
transition: bottom 0.9s linear, opacity 0.4s;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rate-eq-peak.visible {
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
|
||||||
/* Vertical shimmer scan — runs continuously when active */
|
/* Vertical shimmer scan — runs continuously when active */
|
||||||
.rate-eq-shimmer {
|
.rate-eq-shimmer {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue