fix(lyrics): stop the LRC box pre-highlighting the last line at t=0
Deploy / build (push) Successful in 28s
Deploy / build (push) Successful in 28s
findIndex(t > now) - 1 returned -1 before the first line started, which the `if (i < 0) i = lines.length - 1` guard turned into the LAST line — so playback began scrolled to the bottom. Use a last-passed-index scan instead (-1 = before the first line), centre the active line inside the box (so upcoming lyrics are visible), and scroll the box itself rather than scrollIntoView(), which dragged the whole page. Also bumps the box to 250px. Fixes yue2 post + both Suno posts.
This commit is contained in:
1 parent
7a9906ec96
commit
6e2a55fe34
4 files changed
+52
-16
No files matched your search
@@ -88,7 +88,7 @@ Publitio) and embedded with plain HTML5 audio. Press play:
|
||||
<style>
|
||||
.suno-track{margin:2.2rem 0}
|
||||
.suno-track audio{width:100%;max-width:560px}
|
||||
.suno-box{max-height:190px;overflow-y:auto;border:1px solid var(--border,#3a3f47);border-radius:8px;padding:.7rem 1rem;margin-top:.6rem;font-size:.95em;line-height:1.6}
|
||||
.suno-box{max-height:250px;overflow-y:auto;border:1px solid var(--border,#3a3f47);border-radius:8px;padding:.7rem 1rem;margin-top:.6rem;font-size:.95em;line-height:1.6}
|
||||
.suno-box p{margin:.18rem 0;opacity:.55}
|
||||
.suno-box p.on{opacity:1;font-weight:600;color:var(--accent,#22c55e)}
|
||||
</style>
|
||||
@@ -287,12 +287,21 @@ document.querySelectorAll('audio[data-lrc]').forEach((audio) => {
|
||||
let cur = -1;
|
||||
audio.addEventListener('timeupdate', () => {
|
||||
const now = audio.currentTime;
|
||||
let i = lines.findIndex((l) => l.t > now) - 1;
|
||||
if (i < 0) i = lines.length - 1;
|
||||
// last line whose timestamp has passed; -1 before the first line starts
|
||||
// (findIndex()-1 went negative at t=0 and wrapped to the LAST line)
|
||||
let i = -1;
|
||||
for (let k = 0; k < lines.length; k++) { if (lines[k].t <= now) i = k; else break; }
|
||||
if (i !== cur) {
|
||||
if (cur >= 0) box.children[cur].classList.remove('on');
|
||||
cur = i;
|
||||
if (cur >= 0) { box.children[cur].classList.add('on'); box.children[cur].scrollIntoView({ block: 'nearest' }); }
|
||||
if (cur >= 0) {
|
||||
const p = box.children[cur];
|
||||
p.classList.add('on');
|
||||
// scroll the lyric box only (scrollIntoView would drag the whole page)
|
||||
box.scrollTo({ top: p.offsetTop - box.clientHeight / 2 + p.offsetHeight / 2, behavior: 'smooth' });
|
||||
} else {
|
||||
box.scrollTop = 0; // back to the top before the first line
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -227,7 +227,7 @@ against the written lyrics, since the model emits no timestamps.
|
||||
<style>
|
||||
.yue2-track{margin:2.2rem 0}
|
||||
.yue2-track audio{width:100%;max-width:560px}
|
||||
.yue2-box{max-height:190px;overflow-y:auto;border:1px solid var(--border,#3a3f47);border-radius:8px;padding:.7rem 1rem;margin-top:.6rem;font-size:.95em;line-height:1.6}
|
||||
.yue2-box{max-height:250px;overflow-y:auto;border:1px solid var(--border,#3a3f47);border-radius:8px;padding:.7rem 1rem;margin-top:.6rem;font-size:.95em;line-height:1.6}
|
||||
.yue2-box p{margin:.18rem 0;opacity:.55}
|
||||
.yue2-box p.on{opacity:1;font-weight:600;color:var(--accent,#22c55e)}
|
||||
</style>
|
||||
@@ -951,12 +951,21 @@ document.querySelectorAll('audio[data-lrc]').forEach((audio) => {
|
||||
let cur = -1;
|
||||
audio.addEventListener('timeupdate', () => {
|
||||
const now = audio.currentTime;
|
||||
let i = lines.findIndex((l) => l.t > now) - 1;
|
||||
if (i < 0) i = lines.length - 1;
|
||||
// last line whose timestamp has passed; -1 before the first line starts
|
||||
// (findIndex()-1 went negative at t=0 and wrapped to the LAST line)
|
||||
let i = -1;
|
||||
for (let k = 0; k < lines.length; k++) { if (lines[k].t <= now) i = k; else break; }
|
||||
if (i !== cur) {
|
||||
if (cur >= 0) box.children[cur].classList.remove('on');
|
||||
cur = i;
|
||||
if (cur >= 0) { box.children[cur].classList.add('on'); box.children[cur].scrollIntoView({ block: 'nearest' }); }
|
||||
if (cur >= 0) {
|
||||
const p = box.children[cur];
|
||||
p.classList.add('on');
|
||||
// scroll the lyric box only (scrollIntoView would drag the whole page)
|
||||
box.scrollTo({ top: p.offsetTop - box.clientHeight / 2 + p.offsetHeight / 2, behavior: 'smooth' });
|
||||
} else {
|
||||
box.scrollTop = 0; // back to the top before the first line
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -74,7 +74,7 @@ v6 家族新增的控制功能,直接改变了我做事的方式:
|
||||
<style>
|
||||
.suno-track{margin:2.2rem 0}
|
||||
.suno-track audio{width:100%;max-width:560px}
|
||||
.suno-box{max-height:190px;overflow-y:auto;border:1px solid var(--border,#3a3f47);border-radius:8px;padding:.7rem 1rem;margin-top:.6rem;font-size:.95em;line-height:1.6}
|
||||
.suno-box{max-height:250px;overflow-y:auto;border:1px solid var(--border,#3a3f47);border-radius:8px;padding:.7rem 1rem;margin-top:.6rem;font-size:.95em;line-height:1.6}
|
||||
.suno-box p{margin:.18rem 0;opacity:.55}
|
||||
.suno-box p.on{opacity:1;font-weight:600;color:var(--accent,#22c55e)}
|
||||
</style>
|
||||
@@ -266,12 +266,21 @@ document.querySelectorAll('audio[data-lrc]').forEach((audio) => {
|
||||
let cur = -1;
|
||||
audio.addEventListener('timeupdate', () => {
|
||||
const now = audio.currentTime;
|
||||
let i = lines.findIndex((l) => l.t > now) - 1;
|
||||
if (i < 0) i = lines.length - 1;
|
||||
// last line whose timestamp has passed; -1 before the first line starts
|
||||
// (findIndex()-1 went negative at t=0 and wrapped to the LAST line)
|
||||
let i = -1;
|
||||
for (let k = 0; k < lines.length; k++) { if (lines[k].t <= now) i = k; else break; }
|
||||
if (i !== cur) {
|
||||
if (cur >= 0) box.children[cur].classList.remove('on');
|
||||
cur = i;
|
||||
if (cur >= 0) { box.children[cur].classList.add('on'); box.children[cur].scrollIntoView({ block: 'nearest' }); }
|
||||
if (cur >= 0) {
|
||||
const p = box.children[cur];
|
||||
p.classList.add('on');
|
||||
// scroll the lyric box only (scrollIntoView would drag the whole page)
|
||||
box.scrollTo({ top: p.offsetTop - box.clientHeight / 2 + p.offsetHeight / 2, behavior: 'smooth' });
|
||||
} else {
|
||||
box.scrollTop = 0; // back to the top before the first line
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -172,7 +172,7 @@ clean = "\n".join(l for l in raw.split("\n")
|
||||
<style>
|
||||
.yue2-track{margin:2.2rem 0}
|
||||
.yue2-track audio{width:100%;max-width:560px}
|
||||
.yue2-box{max-height:190px;overflow-y:auto;border:1px solid var(--border,#3a3f47);border-radius:8px;padding:.7rem 1rem;margin-top:.6rem;font-size:.95em;line-height:1.6}
|
||||
.yue2-box{max-height:250px;overflow-y:auto;border:1px solid var(--border,#3a3f47);border-radius:8px;padding:.7rem 1rem;margin-top:.6rem;font-size:.95em;line-height:1.6}
|
||||
.yue2-box p{margin:.18rem 0;opacity:.55}
|
||||
.yue2-box p.on{opacity:1;font-weight:600;color:var(--accent,#22c55e)}
|
||||
</style>
|
||||
@@ -896,12 +896,21 @@ document.querySelectorAll('audio[data-lrc]').forEach((audio) => {
|
||||
let cur = -1;
|
||||
audio.addEventListener('timeupdate', () => {
|
||||
const now = audio.currentTime;
|
||||
let i = lines.findIndex((l) => l.t > now) - 1;
|
||||
if (i < 0) i = lines.length - 1;
|
||||
// last line whose timestamp has passed; -1 before the first line starts
|
||||
// (findIndex()-1 went negative at t=0 and wrapped to the LAST line)
|
||||
let i = -1;
|
||||
for (let k = 0; k < lines.length; k++) { if (lines[k].t <= now) i = k; else break; }
|
||||
if (i !== cur) {
|
||||
if (cur >= 0) box.children[cur].classList.remove('on');
|
||||
cur = i;
|
||||
if (cur >= 0) { box.children[cur].classList.add('on'); box.children[cur].scrollIntoView({ block: 'nearest' }); }
|
||||
if (cur >= 0) {
|
||||
const p = box.children[cur];
|
||||
p.classList.add('on');
|
||||
// scroll the lyric box only (scrollIntoView would drag the whole page)
|
||||
box.scrollTo({ top: p.offsetTop - box.clientHeight / 2 + p.offsetHeight / 2, behavior: 'smooth' });
|
||||
} else {
|
||||
box.scrollTop = 0; // back to the top before the first line
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user