Now Playing: click-to-seek synced lyrics
Click any synced lyric line to jump playback to that line's timestamp (and
resume if paused). Reuses the existing _npLyricsState.lines {time,text} data.
Hover affordance: accent-tinted line + pointer cursor. Synced lyrics only
(plain lyrics have no timestamps).
This commit is contained in:
parent
a8985b317f
commit
843f4081cf
2 changed files with 17 additions and 2 deletions
|
|
@ -1038,8 +1038,21 @@ function _npLyricsRenderSynced(lines) {
|
|||
}
|
||||
content.innerHTML = lines.map((line, idx) => {
|
||||
const safe = (line.text || '').replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])) || ' ';
|
||||
return `<div class="np-lyrics-line" data-idx="${idx}">${safe}</div>`;
|
||||
return `<div class="np-lyrics-line" data-idx="${idx}" title="Jump to this line">${safe}</div>`;
|
||||
}).join('');
|
||||
|
||||
// Click a line → seek playback to its timestamp (synced lyrics only).
|
||||
content.querySelectorAll('.np-lyrics-line').forEach(el => {
|
||||
el.addEventListener('click', () => {
|
||||
const idx = Number(el.dataset.idx);
|
||||
const line = _npLyricsState.lines[idx];
|
||||
if (!line || !audioPlayer || !isFinite(line.time)) return;
|
||||
try {
|
||||
audioPlayer.currentTime = line.time;
|
||||
if (audioPlayer.paused) audioPlayer.play().catch(() => {});
|
||||
} catch (_) {}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function _npLyricsRenderPlain(text) {
|
||||
|
|
|
|||
|
|
@ -48702,9 +48702,11 @@ textarea.enhanced-meta-field-input {
|
|||
.np-queue-item.active .np-queue-item-title { color: rgb(var(--accent-light-rgb)) !important; }
|
||||
.np-radio-btn.active, .np-queue-toggle.active { color: rgb(var(--accent-light-rgb)) !important; }
|
||||
|
||||
/* ── Close button + lyrics active line ── */
|
||||
/* ── Close button + lyrics (active line + click-to-seek affordance) ── */
|
||||
.np-close-btn:hover { color: #fff !important; background: rgba(255,255,255,0.1) !important; }
|
||||
.np-lyrics-line.active { color: rgb(var(--accent-light-rgb)) !important; font-weight: 700 !important; }
|
||||
.np-lyrics-line { cursor: pointer; border-radius: 6px; transition: background 0.12s, color 0.12s; }
|
||||
.np-lyrics-line:hover { background: rgba(var(--accent-rgb),0.10); color: rgb(var(--accent-light-rgb)); }
|
||||
|
||||
/* ── Crafted entrance: controls stagger-fade in when modal opens ──
|
||||
(Art container is intentionally excluded — its transform is reserved for the
|
||||
|
|
|
|||
Loading…
Reference in a new issue