diff --git a/package.json b/package.json index 9a3c8ff..2508897 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "aquavox", - "version": "2.3.3", + "version": "2.5.1", "private": false, "module": "index.ts", "type": "module", diff --git a/packages/core/components/lyrics/lyricLine.svelte b/packages/core/components/lyrics/lyricLine.svelte index c4d8b0a..204327a 100644 --- a/packages/core/components/lyrics/lyricLine.svelte +++ b/packages/core/components/lyrics/lyricLine.svelte @@ -4,11 +4,16 @@ import type { LyricPos } from './type'; import type { Spring } from '@core/graphics/spring/spring'; + const viewportWidth = document.documentElement.clientWidth; + const blurRatio = viewportWidth > 640 ? 1 : 1.4; + export let line: ScriptItem; export let index: number; export let debugMode: Boolean; export let lyricClick: Function; export let progress: number; + export let currentLyricIndex: number; + export let scrolling: boolean; let ref: HTMLDivElement; let clickMask: HTMLSpanElement; @@ -75,9 +80,21 @@ opacity = isCurrent ? 1 : 0.36; }; - export const setBlur = (blur: number) => { - ref.style.filter = `blur(${blur}px)`; - }; + $: { + if (ref && ref.style) { + let blurRadius = 0; + const offset = Math.abs(index - currentLyricIndex); + if (progress > line.end) { + blurRadius = Math.min(offset * blurRatio, 16); + } else if (line.start <= progress && progress <= line.end) { + blurRadius = 0; + } else { + blurRadius = Math.min(offset * blurRatio, 16); + } + if (scrolling) blurRadius=0; + ref.style.filter = `blur(${blurRadius}px)`; + } + } export const update = (pos: LyricPos, delay: number = 0) => { if (lastPosX === undefined || lastPosY === undefined) { @@ -140,7 +157,7 @@ {#if debugMode} @@ -148,25 +165,25 @@ {index}: duration: {(line.end - line.start).toFixed(3)}, {line.start.toFixed(3)}~{line.end.toFixed(3)} {/if} - {#if line.words} + {#if line.words !== undefined && line.words.length > 0} {#each line.words as word} {#if word.word} {#each word.word.split("") as chr, i} - (word.endTime - word.startTime) * ((i)/word.word.length) + word.startTime ? "opacity-100" : "opacity-35") + " inline-block duration-300"} - > - {chr} - + (word.endTime - word.startTime) * ((i)/word.word.length) + word.startTime ? "opacity-100 text-glow" : "opacity-35") + " inline-block duration-300"} + > + {chr} + {/each} {/if} {/each} {:else} {line.text} @@ -179,3 +196,14 @@ {/if} + + + \ No newline at end of file diff --git a/packages/core/components/lyrics/newLyrics.svelte b/packages/core/components/lyrics/newLyrics.svelte index 3a62d5f..f643f30 100644 --- a/packages/core/components/lyrics/newLyrics.svelte +++ b/packages/core/components/lyrics/newLyrics.svelte @@ -75,17 +75,15 @@ const relativeOrigin = lyricTopList[currentLyricIndex] - currentLyricTop; for (let i = 0; i < lyricElements.length; i++) { const currentLyricComponent = lyricComponents[i]; + const lyric = originalLyrics.scripts[i]; let delay = 0; - if (i < currentLyricIndex) { + if (progress > lyric.end) { delay = 0; - } else if (i == currentLyricIndex) { + } else if (lyric.start <= progress && progress <= lyric.end) { delay = 0.042; } else { delay = Math.min(Math.min(currentLyricDuration, 0.6), 0.067 * (i - currentLyricIndex + 1.2)); } - const offset = Math.abs(i - currentLyricIndex); - let blurRadius = Math.min(offset * blurRatio, 16); - currentLyricComponent.setBlur(blurRadius); currentLyricComponent.update({ x: 0, y: lyricTopList[i] - relativeOrigin }, delay); } } @@ -107,7 +105,7 @@ for (let i = 0; i < lyricElements.length; i++) { const currentLyricComponent = lyricComponents[i]; const currentY = currentLyricComponent.getInfo().y; - currentLyricComponent.setBlur(0); + scrolling = true; currentLyricComponent.stop(); currentLyricComponent.setY(currentY - deltaY); } @@ -263,7 +261,7 @@ bind:this={lyricsContainer} > {#each lyricLines as lyric, i} - + {/each} {/if} diff --git a/packages/core/lyrics/lrc/parser.ts b/packages/core/lyrics/lrc/parser.ts index 402904c..41f6e94 100644 --- a/packages/core/lyrics/lrc/parser.ts +++ b/packages/core/lyrics/lrc/parser.ts @@ -16,14 +16,13 @@ import { tok, type Token } from 'typescript-parsec'; -import type { LrcJsonData, ParsedLrc, ScriptItem, ScriptWordsItem } from '../type'; +import type { LrcJsonData, ParsedLrc, ScriptItem } from '../type'; import type { IDTag } from './type'; interface ParserScriptItem { start: number; text: string; - words?: ScriptWordsItem[]; translation?: string; singer?: string; } @@ -166,25 +165,10 @@ function lrcLine( .filter((s) => s.trim().length > 0) .join(wordDiv); - const words = mainPart - .filter((s) => joinTokens(s[1]).trim().length > 0) - .map((s) => { - const wordBegin = s[0]; - const word = s[1]; - let ret: Partial = { start: wordBegin }; - if (word[0]) { - ret.beginIndex = word[0].pos.columnBegin - 1; - } - if (word[word.length - 1]) { - ret.endIndex = word[word.length - 1].pos.columnEnd; - } - return ret as ScriptWordsItem; // TODO: Complete this - }); - const singer = singerPart?.text; const translation = translatePart === undefined ? undefined : joinTokens(translatePart); - return ['script_item', { start, text, words, singer, translation } as ParserScriptItem]; + return ['script_item', { start, text, singer, translation } as ParserScriptItem]; }), apply(lrcTag, (r) => ['lrc_tag', r as IDTag]), apply(seq(spaces(), str('#'), unicodeStr), (cmt) => ['comment', cmt[2].join('')] as const), @@ -206,8 +190,6 @@ export function parseLRC( const tokenizer = buildLexer([ [true, /^\[/gu, '['], [true, /^\]/gu, ']'], - [true, /^/gu, '>'], [true, /^\|/gu, '|'], [true, /^./gu, 'char'] ]);