.
\ No newline at end of file
diff --git a/package.json b/package.json
index 040ec52..1b99d1e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "aquavox",
- "version": "1.12.13",
+ "version": "1.12.14",
"private": false,
"scripts": {
"dev": "vite dev",
diff --git a/src/lib/components/interactiveBox.svelte b/src/lib/components/interactiveBox.svelte
index 0bbf0e5..1d55162 100644
--- a/src/lib/components/interactiveBox.svelte
+++ b/src/lib/components/interactiveBox.svelte
@@ -3,6 +3,7 @@
import { onMount } from 'svelte';
import userAdjustingProgress from '$lib/state/userAdjustingProgress';
import progressBarSlideValue from '$lib/state/progressBarSlideValue';
+ import truncate from '$lib/truncate';
export let name: string;
export let singer: string = '';
@@ -49,10 +50,6 @@
progressBarSlideValue.set((e.offsetX / progressBar.getBoundingClientRect().width) * duration);
}
- function truncate(value: number, min: number, max: number) {
- return Math.min(Math.max(value, min), max);
- }
-
function progressBarMouseUp(offsetX: number) {
adjustDisplayProgress(offsetX / progressBar.getBoundingClientRect().width);
}
diff --git a/src/lib/components/lyrics.svelte b/src/lib/components/lyrics.svelte
index 92cd78f..59135ca 100644
--- a/src/lib/components/lyrics.svelte
+++ b/src/lib/components/lyrics.svelte
@@ -5,6 +5,7 @@
import type { LrcJsonData } from 'lrc-parser-ts';
import progressBarSlideValue from '$lib/state/progressBarSlideValue';
import nextUpdate from '$lib/state/nextUpdate';
+ import truncate from '$lib/truncate';
// Component input properties
export let lyrics: string[];
@@ -38,6 +39,22 @@
$: refs = _refs.filter(Boolean);
$: getLyricIndex = createLyricsSearcher(originalLyrics);
+
+ // handle KeyDown event
+ function onKeyDown(e: KeyboardEvent) {
+ if (e.altKey && e.shiftKey && (e.metaKey || e.key === 'OS') && e.key === 'Enter') {
+ debugMode = !debugMode;
+ localStorage.setItem('debugMode', debugMode ? 'true' : 'false');
+ }
+ }
+
+ // using for debug mode
+ function extractTranslateValue(s: string): string | null {
+ const regex = /translateY\((-?\d*px)\)/;
+ let arr = regex.exec(s);
+ return arr==null ? null : arr[1];
+ }
+
// Helper function to get CSS class for a lyric based on its index and progress
function getClass(lyricIndex: number, progress: number) {
if (!originalLyrics.scripts) return 'previous-lyric';
@@ -117,7 +134,110 @@
}, 500);
}
- // Handle user adjusting progress state changes
+ // Handle scroll events in the lyrics container
+ function scrollHandler() {
+ scrolling = !scriptScrolling;
+ if (scrolling && originalLyrics.scripts) {
+ lastScroll = new Date().getTime();
+ for (let i = 0; i < originalLyrics.scripts.length; i++) {
+ if (refs[i]) {
+ refs[i].style.filter = 'blur(0px)';
+ }
+ }
+ }
+ setTimeout(() => {
+ if (new Date().getTime() - lastScroll > 5000) {
+ scrolling = false;
+ }
+ }, 5500);
+ }
+
+ // Utility function to create a sleep/delay
+ function sleep(ms: number) {
+ return new Promise((resolve) => setTimeout(resolve, ms));
+ }
+
+ // Scroll to corresponding lyric while adjusting progress
+ $: {
+ if ($userAdjustingProgress == true) {
+ const currentLyric = refs[getLyricIndex(progress)];
+ scrollToLyric(currentLyric);
+ }
+ }
+
+ // Update the current lyric and apply blur effect based on the progress
+ // worked in real-time.
+ $: {
+ (() => {
+ if (!lyricsContainer || !originalLyrics.scripts) return;
+
+ const scripts = originalLyrics.scripts;
+ currentPositionIndex = getLyricIndex(progress);
+ const cl = scripts[currentPositionIndex];
+
+ if (cl.start <= progress && progress <= cl.end) {
+ currentLyricIndex = currentPositionIndex;
+ nextUpdate.set(cl.end);
+ } else {
+ currentLyricIndex = -1;
+ nextUpdate.set(cl.start);
+ }
+
+ const currentLyric = refs[currentPositionIndex];
+ if ($userAdjustingProgress || scrolling || currentLyric.getBoundingClientRect().top < 0) return;
+
+ for (let i = 0; i < scripts.length; i++) {
+ const offset = Math.abs(i - currentPositionIndex);
+ const blurRadius = Math.min(offset * 0.96, 16);
+ if (refs[i]) {
+ refs[i].style.filter = `blur(${blurRadius}px)`;
+ }
+ }
+ })();
+ }
+
+ // Main function that control's lyrics update during playing
+ // triggered by nextUpdate's update
+ async function lyricsUpdate(){
+ if (
+ currentPositionIndex < 0 ||
+ currentPositionIndex === currentAnimationIndex ||
+ currentPositionIndex === lastAdjustProgress ||
+ $userAdjustingProgress === true ||
+ scrolling
+ ) return;
+
+ const currentLyric = refs[currentPositionIndex];
+ const currentLyricRect = currentLyric.getBoundingClientRect();
+
+ if (originalLyrics.scripts && currentLyricRect.top < 0) return;
+
+ const offsetHeight = truncate(currentLyricRect.top - currentLyricTopMargin, 0, Infinity);
+
+ // prepare current line
+ currentLyric.style.transition = `transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease,
+ opacity 200ms ease, font-size 200ms ease, scale 250ms ease`;
+ currentLyric.style.transform = `translateY(${-offsetHeight}px)`;
+
+ for (let i = currentPositionIndex - 1; i >= 0; i--) {
+ 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`;
+ refs[i].style.transform = `translateY(${-offsetHeight}px)`;
+ }
+ if (currentPositionIndex + 1 < refs.length) {
+ const nextLyric = refs[currentPositionIndex + 1];
+ nextLyric.style.transition = `transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease,
+ opacity 200ms ease, font-size 200ms ease, scale 250ms ease`;
+ nextLyric.style.transform = `translateY(${-offsetHeight}px)`;
+ await moveToNextLine(offsetHeight);
+ }
+ currentAnimationIndex = currentPositionIndex;
+ }
+
+
+ nextUpdate.subscribe(lyricsUpdate)
+
+ // Process while user is adjusting progress
userAdjustingProgress.subscribe((adjusting) => {
if (!originalLyrics) return;
const scripts = originalLyrics.scripts;
@@ -155,117 +275,6 @@
}
});
- // Handle scroll events in the lyrics container
- function scrollHandler() {
- scrolling = !scriptScrolling;
- if (scrolling && originalLyrics.scripts) {
- lastScroll = new Date().getTime();
- for (let i = 0; i < originalLyrics.scripts.length; i++) {
- if (refs[i]) {
- refs[i].style.filter = 'blur(0px)';
- }
- }
- }
- setTimeout(() => {
- if (new Date().getTime() - lastScroll > 5000) {
- scrolling = false;
- }
- }, 5500);
- }
-
- // Utility function to create a sleep/delay
- function sleep(ms: number) {
- return new Promise((resolve) => setTimeout(resolve, ms));
- }
-
- // Scroll to corresponding lyric while adjusting progress
- $: {
- if ($userAdjustingProgress == true) {
- const currentLyric = refs[getLyricIndex(progress)];
- scrollToLyric(currentLyric);
- }
- }
-
- // Update the current lyric and apply blur effect based on the progress
- $: {
- (() => {
- if (!lyricsContainer || !originalLyrics.scripts) return;
-
- const scripts = originalLyrics.scripts;
- currentPositionIndex = getLyricIndex(progress);
- const cl = scripts[currentPositionIndex];
-
- if (cl.start <= progress && progress <= cl.end) {
- currentLyricIndex = currentPositionIndex;
- nextUpdate.set(cl.end);
- } else {
- currentLyricIndex = -1;
- nextUpdate.set(cl.start);
- }
-
- const currentLyric = refs[currentPositionIndex];
- if ($userAdjustingProgress || scrolling || currentLyric.getBoundingClientRect().top < 0) return;
-
- for (let i = 0; i < scripts.length; i++) {
- const offset = Math.abs(i - currentPositionIndex);
- const blurRadius = Math.min(offset * 0.96, 16);
- if (refs[i]) {
- refs[i].style.filter = `blur(${blurRadius}px)`;
- }
- }
- })();
- }
-
- nextUpdate.subscribe(async (nextUpdate) => {
- if (
- currentPositionIndex < 0 ||
- currentPositionIndex === currentAnimationIndex ||
- currentPositionIndex === lastAdjustProgress ||
- $userAdjustingProgress === true ||
- scrolling
- ) return;
-
- const currentLyric = refs[currentPositionIndex];
-
- if (originalLyrics.scripts && currentLyric.getBoundingClientRect().top < 0) return;
-
- const offsetHeight =
- refs[currentPositionIndex].getBoundingClientRect().top -
- currentLyricTopMargin;
-
- // prepare current line
- currentLyric.style.transition = `transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease,
- opacity 200ms ease, font-size 200ms ease, scale 250ms ease`;
- currentLyric.style.transform = `translateY(${-offsetHeight}px)`;
-
- for (let i = currentPositionIndex - 1; i >= 0; i--) {
- 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`;
- refs[i].style.transform = `translateY(${-offsetHeight}px)`;
- }
- if (currentPositionIndex + 1 < refs.length) {
- const nextLyric = refs[currentPositionIndex + 1];
- nextLyric.style.transition = `transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease,
- opacity 200ms ease, font-size 200ms ease, scale 250ms ease`;
- nextLyric.style.transform = `translateY(${-offsetHeight}px)`;
- await moveToNextLine(offsetHeight);
- }
- currentAnimationIndex = currentPositionIndex;
- })
-
- function onKeyDown(e: KeyboardEvent) {
- if (e.altKey && e.shiftKey && (e.metaKey || e.key === 'OS') && e.key === 'Enter') {
- debugMode = !debugMode;
- localStorage.setItem('debugMode', debugMode ? 'true' : 'false');
- }
- }
-
- function extractTranslateValue(s: string): string | null {
- const regex = /translateY\((-?\d*px)\)/;
- let arr = regex.exec(s);
- return arr==null ? null : arr[1];
- }
-
@@ -290,6 +299,7 @@
class="absolute top-[6.5rem] md:top-36 xl:top-0 w-screen xl:w-[52vw] px-6 md:px-12 lg:px-[7.5rem] xl:left-[45vw] xl:px-[3vw] h-[calc(100vh-17rem)] xl:h-screen font-sans
text-left no-scrollbar overflow-y-auto z-[1] pt-16 lyrics"
bind:this={lyricsContainer}
+ on:scroll={scrollHandler}
>
{#each lyrics as lyric, i}
diff --git a/src/lib/truncate.ts b/src/lib/truncate.ts
new file mode 100644
index 0000000..c10b4a4
--- /dev/null
+++ b/src/lib/truncate.ts
@@ -0,0 +1,3 @@
+export default function truncate(value: number, min: number, max: number) {
+ return Math.min(Math.max(value, min), max);
+}
\ No newline at end of file
diff --git a/src/routes/play/[id]/+page.svelte b/src/routes/play/[id]/+page.svelte
index 9c2c853..a68d275 100644
--- a/src/routes/play/[id]/+page.svelte
+++ b/src/routes/play/[id]/+page.svelte
@@ -11,6 +11,8 @@
import lrcParser, { type LrcJsonData } from 'lrc-parser-ts';
import userAdjustingProgress from '$lib/state/userAdjustingProgress';
import type { IAudioMetadata } from 'music-metadata-browser';
+ import { onMount } from 'svelte';
+ import progressBarRaw from '$lib/state/progressBarRaw';
const audioId = $page.params.id;
let audioPlayer: HTMLAudioElement;
@@ -150,20 +152,12 @@
$: {
clearInterval(mainInterval);
mainInterval = setInterval(() => {
- if (
- audioPlayer !== null &&
- audioPlayer.currentTime !== undefined
- ) {
- if ($userAdjustingProgress === false)
- currentProgress = audioPlayer.currentTime;
- progressBarRaw.set(audioPlayer.currentTime);
- }
+ if ($userAdjustingProgress === false)
+ currentProgress = audioPlayer.currentTime;
+ progressBarRaw.set(audioPlayer.currentTime);
}, 50);
}
- import { onMount } from 'svelte';
- import progressBarRaw from '$lib/state/progressBarRaw';
-
onMount(() => {
audioPlayer.volume = localStorage.getItem('volume') ? Number(localStorage.getItem('volume')) : 1;
});
@@ -175,13 +169,7 @@
}
}
- $: {
- if (originalLyrics) {
- hasLyrics = true;
- } else {
- hasLyrics = false;
- }
- }
+ $: hasLyrics = !!originalLyrics;
readDB();