Smooth lyrics fade

This commit is contained in:
lucast committed 2026-09-26 22:27:15 +02:00
1 parent e50648e35f
commit 27feb1ce95
1 file changed
+22 -6
@@ -49,6 +49,7 @@ const scrollActiveIndex = computed(() => {
const height = ref<number>() const height = ref<number>()
const top = ref(0) const top = ref(0)
const syncedHeight = ref<number>() const syncedHeight = ref<number>()
const topFadeExtension = 75
const updateLyricsLayout = () => { const updateLyricsLayout = () => {
const trackDisplay = document.querySelector(".track-display") const trackDisplay = document.querySelector(".track-display")
@@ -99,7 +100,7 @@ const onWheel = (event: WheelEvent) => {
if (!containerRef.value || !outerRef.value) return if (!containerRef.value || !outerRef.value) return
if (!isScrolling.value) { if (!isScrolling.value) {
manualOffset.value = transformY.value + offset manualOffset.value = transformY.value + offset + topFadeExtension
} }
isScrolling.value = true isScrolling.value = true
@@ -109,7 +110,7 @@ const onWheel = (event: WheelEvent) => {
manualOffset.value -= delta manualOffset.value -= delta
const maxTranslate = offset const maxTranslate = offset + topFadeExtension
const lowerViewportLimit = Math.max( const lowerViewportLimit = Math.max(
outerRef.value.offsetHeight, outerRef.value.offsetHeight,
window.innerHeight - 300, window.innerHeight - 300,
@@ -134,7 +135,7 @@ const onLyricClick = (time: number) => {
const finalTransform = computed(() => { const finalTransform = computed(() => {
if (isScrolling.value) return manualOffset.value if (isScrolling.value) return manualOffset.value
return transformY.value + offset return transformY.value + offset + topFadeExtension
}) })
</script> </script>
@@ -144,8 +145,8 @@ const finalTransform = computed(() => {
v-if="song && song.lyrics && song.lyrics.synced" v-if="song && song.lyrics && song.lyrics.synced"
class="synced-lyrics-container" class="synced-lyrics-container"
:style="{ :style="{
height: `${syncedHeight}px`, height: `${syncedHeight + topFadeExtension}px`,
marginTop: `${top}px`, marginTop: `${top - topFadeExtension}px`,
}" }"
@wheel.prevent="onWheel" @wheel.prevent="onWheel"
> >
@@ -160,7 +161,10 @@ const finalTransform = computed(() => {
<p <p
v-for="(lyric, i) in parsedLyrics" v-for="(lyric, i) in parsedLyrics"
:key="lyric.time" :key="lyric.time"
:class="{ active: i == scrollActiveIndex }" :class="{
active: i == scrollActiveIndex,
past: i < scrollActiveIndex && !isScrolling,
}"
ref="lyrics" ref="lyrics"
@click="onLyricClick(lyric.time)" @click="onLyricClick(lyric.time)"
> >
@@ -226,6 +230,18 @@ const finalTransform = computed(() => {
opacity: 1; opacity: 1;
filter: initial; filter: initial;
} }
&.past {
opacity: 0;
filter: blur(1.5px);
transition: opacity 0.4s ease;
&:hover {
cursor: default;
opacity: 0;
filter: blur(1.5px);
}
}
} }
} }