improve: add more comments to lyrics component
This commit is contained in:
parent
e1aa87ece0
commit
5cd9abdcc0
@ -4,10 +4,13 @@
|
|||||||
import progressBarRaw from '$lib/state/progressBarRaw';
|
import progressBarRaw from '$lib/state/progressBarRaw';
|
||||||
import type { LrcJsonData } from 'lrc-parser-ts';
|
import type { LrcJsonData } from 'lrc-parser-ts';
|
||||||
import progressBarSlideValue from '$lib/state/progressBarSlideValue';
|
import progressBarSlideValue from '$lib/state/progressBarSlideValue';
|
||||||
|
|
||||||
|
// Component input properties
|
||||||
export let lyrics: string[];
|
export let lyrics: string[];
|
||||||
export let originalLyrics: LrcJsonData;
|
export let originalLyrics: LrcJsonData;
|
||||||
export let progress: number;
|
export let progress: number;
|
||||||
|
|
||||||
|
// Local state and variables
|
||||||
let getLyricIndex: Function;
|
let getLyricIndex: Function;
|
||||||
const debugMode = false;
|
const debugMode = false;
|
||||||
let currentLyricIndex = -1;
|
let currentLyricIndex = -1;
|
||||||
@ -21,11 +24,13 @@
|
|||||||
let scrolling = false;
|
let scrolling = false;
|
||||||
let scriptScrolling = false;
|
let scriptScrolling = false;
|
||||||
|
|
||||||
|
// References to lyric elements
|
||||||
let refs: HTMLParagraphElement[] = [];
|
let refs: HTMLParagraphElement[] = [];
|
||||||
let _refs: any[] = [];
|
let _refs: any[] = [];
|
||||||
$: refs = _refs.filter(Boolean);
|
$: refs = _refs.filter(Boolean);
|
||||||
$: getLyricIndex = createLyricsSearcher(originalLyrics);
|
$: getLyricIndex = createLyricsSearcher(originalLyrics);
|
||||||
|
|
||||||
|
// Helper function to get CSS class for a lyric based on its index and progress
|
||||||
function getClass(lyricIndex: number, progress: number) {
|
function getClass(lyricIndex: number, progress: number) {
|
||||||
if (!originalLyrics.scripts) return 'previous-lyric';
|
if (!originalLyrics.scripts) return 'previous-lyric';
|
||||||
if (currentLyricIndex === lyricIndex) return 'current-lyric';
|
if (currentLyricIndex === lyricIndex) return 'current-lyric';
|
||||||
@ -33,7 +38,7 @@
|
|||||||
else return 'previous-lyric';
|
else return 'previous-lyric';
|
||||||
}
|
}
|
||||||
|
|
||||||
// scroll to correspoding lyric while adjusting progress
|
// Scroll to corresponding lyric while adjusting progress
|
||||||
$: {
|
$: {
|
||||||
if ($userAdjustingProgress == true) {
|
if ($userAdjustingProgress == true) {
|
||||||
const currentLyric = refs[getLyricIndex(progress)];
|
const currentLyric = refs[getLyricIndex(progress)];
|
||||||
@ -41,14 +46,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the current lyric and apply blur effect based on the progress
|
||||||
$: {
|
$: {
|
||||||
(() => {
|
(() => {
|
||||||
if (lyricsContainer === undefined || originalLyrics.scripts === undefined) {
|
if (!lyricsContainer || !originalLyrics.scripts) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
const scripts = originalLyrics.scripts;
|
const scripts = originalLyrics.scripts;
|
||||||
currentPositionIndex = getLyricIndex(progress);
|
currentPositionIndex = getLyricIndex(progress);
|
||||||
const cl = scripts[currentPositionIndex];
|
const cl = scripts[currentPositionIndex];
|
||||||
|
|
||||||
if (cl.start <= progress && progress <= cl.end) {
|
if (cl.start <= progress && progress <= cl.end) {
|
||||||
currentLyricIndex = currentPositionIndex;
|
currentLyricIndex = currentPositionIndex;
|
||||||
nextUpdate = cl.end;
|
nextUpdate = cl.end;
|
||||||
@ -56,10 +62,10 @@
|
|||||||
currentLyricIndex = -1;
|
currentLyricIndex = -1;
|
||||||
nextUpdate = cl.start;
|
nextUpdate = cl.start;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentLyric = refs[currentPositionIndex];
|
const currentLyric = refs[currentPositionIndex];
|
||||||
if ($userAdjustingProgress === true || scrolling || currentLyric.getBoundingClientRect().top < 0) {
|
if ($userAdjustingProgress || scrolling || currentLyric.getBoundingClientRect().top < 0) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (let i = 0; i < scripts.length; i++) {
|
for (let i = 0; i < scripts.length; i++) {
|
||||||
const offset = Math.abs(i - currentPositionIndex);
|
const offset = Math.abs(i - currentPositionIndex);
|
||||||
const blurRadius = Math.min(offset * 1.5, 16);
|
const blurRadius = Math.min(offset * 1.5, 16);
|
||||||
@ -70,10 +76,12 @@
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Utility function to create a sleep/delay
|
||||||
function sleep(ms: number) {
|
function sleep(ms: number) {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to move the lyrics up smoothly
|
||||||
async function moveToNextLine(h: number) {
|
async function moveToNextLine(h: number) {
|
||||||
let pos = currentPositionIndex + 2;
|
let pos = currentPositionIndex + 2;
|
||||||
for (let i = currentPositionIndex + 2; i < refs.length; i++) {
|
for (let i = currentPositionIndex + 2; i < refs.length; i++) {
|
||||||
@ -85,7 +93,7 @@
|
|||||||
await sleep(75);
|
await sleep(75);
|
||||||
if (refs[i - 2].getBoundingClientRect().top > lyricsContainer.getBoundingClientRect().height) break;
|
if (refs[i - 2].getBoundingClientRect().top > lyricsContainer.getBoundingClientRect().height) break;
|
||||||
}
|
}
|
||||||
// 特判,鬼知道为什么
|
|
||||||
if (refs.length - pos < 3) {
|
if (refs.length - pos < 3) {
|
||||||
for (let i = pos; i < refs.length; i++) {
|
for (let i = pos; i < refs.length; i++) {
|
||||||
const lyric = refs[i];
|
const lyric = refs[i];
|
||||||
@ -99,8 +107,8 @@
|
|||||||
for (let i = pos; i < refs.length; i++) {
|
for (let i = pos; i < refs.length; i++) {
|
||||||
refs[i].style.transition =
|
refs[i].style.transition =
|
||||||
'transform 0s, filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
|
'transform 0s, filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
|
||||||
const h = refs[i].getBoundingClientRect().height;
|
const height = refs[i].getBoundingClientRect().height;
|
||||||
refs[i].style.transform = `translateY(${-h}px)`;
|
refs[i].style.transform = `translateY(${-height}px)`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +127,7 @@
|
|||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scroll the lyrics container to the given lyric
|
||||||
async function scrollToLyric(currentLyric: HTMLParagraphElement) {
|
async function scrollToLyric(currentLyric: HTMLParagraphElement) {
|
||||||
if (!originalLyrics || !originalLyrics.scripts || !lyricsContainer) return;
|
if (!originalLyrics || !originalLyrics.scripts || !lyricsContainer) return;
|
||||||
scriptScrolling = true;
|
scriptScrolling = true;
|
||||||
@ -128,6 +137,7 @@
|
|||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle user adjusting progress state changes
|
||||||
userAdjustingProgress.subscribe((v) => {
|
userAdjustingProgress.subscribe((v) => {
|
||||||
if (!originalLyrics) return;
|
if (!originalLyrics) return;
|
||||||
const scripts = originalLyrics.scripts;
|
const scripts = originalLyrics.scripts;
|
||||||
@ -147,10 +157,9 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// progressBarRaw is used to detect progress changes at system-level (not in AquaVox)
|
// Handle progress changes at system level
|
||||||
progressBarRaw.subscribe((progress: number) => {
|
progressBarRaw.subscribe((progress: number) => {
|
||||||
if ($userAdjustingProgress === false && getLyricIndex) {
|
if ($userAdjustingProgress === false && getLyricIndex) {
|
||||||
// prevent calling too frequent
|
|
||||||
if (Math.abs(localProgress - progress) > 0.6) {
|
if (Math.abs(localProgress - progress) > 0.6) {
|
||||||
const currentLyric = refs[getLyricIndex(progress)];
|
const currentLyric = refs[getLyricIndex(progress)];
|
||||||
scrollToLyric(currentLyric);
|
scrollToLyric(currentLyric);
|
||||||
@ -159,13 +168,14 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// progressBarSlideValue is to detect progress bar sliding event
|
// Handle progress bar sliding events
|
||||||
progressBarSlideValue.subscribe((_) => {
|
progressBarSlideValue.subscribe((_) => {
|
||||||
if ($userAdjustingProgress === false && getLyricIndex) {
|
if ($userAdjustingProgress === false && getLyricIndex) {
|
||||||
lastAdjustProgress = currentPositionIndex;
|
lastAdjustProgress = currentPositionIndex;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Handle scroll events in the lyrics container
|
||||||
function scrollHandler() {
|
function scrollHandler() {
|
||||||
scrolling = !scriptScrolling;
|
scrolling = !scriptScrolling;
|
||||||
if (scrolling && originalLyrics.scripts) {
|
if (scrolling && originalLyrics.scripts) {
|
||||||
@ -183,6 +193,7 @@
|
|||||||
}, 5500);
|
}, 5500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update lyrics position based on progress
|
||||||
$: {
|
$: {
|
||||||
(() => {
|
(() => {
|
||||||
if ($userAdjustingProgress) {
|
if ($userAdjustingProgress) {
|
||||||
@ -190,22 +201,18 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextUpdate - progress >= 0.05) {
|
if (nextUpdate - progress >= 0.05) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (
|
if (
|
||||||
currentPositionIndex < 0 ||
|
currentPositionIndex < 0 ||
|
||||||
currentPositionIndex === currentAnimationIndex ||
|
currentPositionIndex === currentAnimationIndex ||
|
||||||
currentPositionIndex === lastAdjustProgress ||
|
currentPositionIndex === lastAdjustProgress ||
|
||||||
scrolling
|
scrolling
|
||||||
) {
|
)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
const currentLyric = refs[currentPositionIndex];
|
const currentLyric = refs[currentPositionIndex];
|
||||||
|
|
||||||
if (originalLyrics.scripts && currentLyric.getBoundingClientRect().top < 0) {
|
if (originalLyrics.scripts && currentLyric.getBoundingClientRect().top < 0) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const offsetHeight =
|
const offsetHeight =
|
||||||
refs[currentPositionIndex].getBoundingClientRect().height +
|
refs[currentPositionIndex].getBoundingClientRect().height +
|
||||||
@ -219,7 +226,7 @@
|
|||||||
for (let i = currentPositionIndex - 1; i >= 0; i--) {
|
for (let i = currentPositionIndex - 1; i >= 0; i--) {
|
||||||
refs[i].style.transition =
|
refs[i].style.transition =
|
||||||
'transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
|
'transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
|
||||||
const h = refs[i].getBoundingClientRect().height;
|
const height = refs[i].getBoundingClientRect().height;
|
||||||
refs[i].style.transform = `translateY(${-offsetHeight}px)`;
|
refs[i].style.transform = `translateY(${-offsetHeight}px)`;
|
||||||
}
|
}
|
||||||
if (currentPositionIndex + 1 < refs.length) {
|
if (currentPositionIndex + 1 < refs.length) {
|
||||||
|
Loading…
Reference in New Issue
Block a user