fix: restore lyrics sync in FocusMode and add shimmer effect

- Add explicit effect in FocusMode to ensure lyrics updates run
- Increase immersive mode font size by 2pts (24px/30px)
- Smoother easing with cubic-bezier curves (400ms)
- Add shimmer gradient effect for karaoke-style highlighting
- Add subtle accent glow on active lyrics line
This commit is contained in:
vicrodh committed 2026-01-11 01:04:23 -06:00
1 parent 99c157d100
commit 87b89f0709
2 files changed
+33 -12

No files matched your search

+12 -1
View File
@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import { X, SkipBack, Play, Pause, SkipForward, ChevronDown } from 'lucide-svelte'; import { SkipBack, Play, Pause, SkipForward, ChevronDown } from 'lucide-svelte';
import LyricsLines from './lyrics/LyricsLines.svelte'; import LyricsLines from './lyrics/LyricsLines.svelte';
import { startActiveLineUpdates, stopActiveLineUpdates } from '$lib/stores/lyricsStore';
interface LyricsLine { interface LyricsLine {
text: string; text: string;
@@ -49,6 +50,16 @@
lyricsError = null lyricsError = null
}: Props = $props(); }: Props = $props();
// Ensure lyrics updates run when FocusMode is open with synced lyrics
$effect(() => {
if (isOpen && isPlaying && lyricsSynced) {
startActiveLineUpdates();
}
return () => {
// Cleanup is handled by the main page effect
};
});
let showControls = $state(true); let showControls = $state(true);
let hideTimeout: ReturnType<typeof setTimeout> | null = null; let hideTimeout: ReturnType<typeof setTimeout> | null = null;
let progressRef: HTMLDivElement | null = $state(null); let progressRef: HTMLDivElement | null = $state(null);
+21 -11
View File
@@ -197,12 +197,12 @@
} }
.lyrics-lines.immersive .lyrics-line { .lyrics-lines.immersive .lyrics-line {
font-size: 22px; font-size: 24px;
font-weight: 500; font-weight: 500;
} }
.lyrics-lines.immersive .lyrics-line.active { .lyrics-lines.immersive .lyrics-line.active {
font-size: 28px; font-size: 30px;
font-weight: 700; font-weight: 700;
} }
@@ -215,11 +215,11 @@
letter-spacing: 0.01em; letter-spacing: 0.01em;
opacity: var(--line-opacity, 1); opacity: var(--line-opacity, 1);
transition: transition:
opacity 150ms ease-out, opacity 400ms cubic-bezier(0.4, 0, 0.2, 1),
transform 150ms ease-out, transform 400ms cubic-bezier(0.4, 0, 0.2, 1),
font-size 120ms ease-out, font-size 300ms cubic-bezier(0.4, 0, 0.2, 1),
font-weight 120ms ease-out, font-weight 300ms cubic-bezier(0.4, 0, 0.2, 1),
color 150ms ease-out; color 500ms cubic-bezier(0.4, 0, 0.2, 1);
transform-origin: left center; transform-origin: left center;
will-change: opacity, transform; will-change: opacity, transform;
} }
@@ -238,23 +238,33 @@
font-weight: 700; font-weight: 700;
opacity: 1; opacity: 1;
transform: scale(1.02); transform: scale(1.02);
text-shadow: 0 0 30px rgba(255, 255, 255, 0.15); text-shadow:
0 0 40px rgba(99, 102, 241, 0.3),
0 0 80px rgba(99, 102, 241, 0.15);
} }
.lyrics-lines.center .lyrics-line.active { .lyrics-lines.center .lyrics-line.active {
transform: scale(1.05); transform: scale(1.05);
} }
/* Karaoke progress effect on active line */ /* Shimmer karaoke effect on active line */
.lyrics-line.active .line-text { .lyrics-line.active .line-text {
--shimmer-width: 8%;
--progress-pos: calc(var(--line-progress, 0) * 100%);
background: linear-gradient( background: linear-gradient(
90deg, 90deg,
var(--accent-primary) calc(var(--line-progress, 0) * 100%), var(--accent-primary) 0%,
var(--text-primary) calc(var(--line-progress, 0) * 100%) var(--accent-primary) calc(var(--progress-pos) - var(--shimmer-width)),
rgba(255, 255, 255, 0.95) calc(var(--progress-pos) - 2%),
rgba(255, 255, 255, 0.95) var(--progress-pos),
var(--text-primary) calc(var(--progress-pos) + 2%),
var(--text-primary) 100%
); );
background-size: 100% 100%;
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
color: transparent; color: transparent;
transition: background 50ms linear;
} }
.lyrics-empty { .lyrics-empty {