@uimaxbai/am-lyrics 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -5
- package/dist/src/AmLyrics.d.ts +5 -7
- package/dist/src/AmLyrics.d.ts.map +1 -1
- package/dist/src/am-lyrics.js +468 -348
- package/dist/src/am-lyrics.js.map +1 -1
- package/dist/src/react.js +468 -348
- package/dist/src/react.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/AmLyrics.ts +547 -399
- package/fix.cjs +0 -7
- package/patch.diff +0 -210
- package/patch2.diff +0 -26
package/dist/src/am-lyrics.js
CHANGED
|
@@ -319,7 +319,7 @@ class GoogleService {
|
|
|
319
319
|
}
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
const VERSION = '1.
|
|
322
|
+
const VERSION = '1.4.0';
|
|
323
323
|
const INSTRUMENTAL_THRESHOLD_MS = 7000; // Show dots for gaps >= 7s
|
|
324
324
|
const FETCH_TIMEOUT_MS = 8000; // Timeout for all lyrics fetch requests
|
|
325
325
|
const SEEK_THRESHOLD_MS = 500;
|
|
@@ -342,32 +342,17 @@ function fetchWithTimeout(url, options = {}, timeoutMs = FETCH_TIMEOUT_MS) {
|
|
|
342
342
|
}
|
|
343
343
|
const KPOE_SERVERS = [
|
|
344
344
|
'https://lyricsplus.binimum.org',
|
|
345
|
-
'https://lyricsplus.atomix.one',
|
|
346
345
|
'https://lyricsplus-seven.vercel.app',
|
|
347
346
|
'https://lyricsplus.prjktla.workers.dev',
|
|
348
347
|
'https://lyrics-plus-backend.vercel.app',
|
|
349
348
|
];
|
|
350
349
|
const DEFAULT_KPOE_SOURCE_ORDER = 'apple,lyricsplus,musixmatch,spotify,qq,deezer,musixmatch-word';
|
|
351
|
-
const TIDAL_SERVERS = [
|
|
352
|
-
'https://arran.monochrome.tf',
|
|
353
|
-
'https://api.monochrome.tf/',
|
|
354
|
-
'https://triton.squid.wtf',
|
|
355
|
-
'https://wolf.qqdl.site',
|
|
356
|
-
'https://maus.qqdl.site',
|
|
357
|
-
'https://vogel.qqdl.site',
|
|
358
|
-
'https://katze.qqdl.site',
|
|
359
|
-
'https://hund.qqdl.site',
|
|
360
|
-
'https://tidal.kinoplus.online',
|
|
361
|
-
'https://hifi-one.spotisaver.net',
|
|
362
|
-
'https://hifi-two.spotisaver.net',
|
|
363
|
-
];
|
|
364
350
|
const GENIUS_WORKER_URL = 'https://fetch-genius.samidy.workers.dev/';
|
|
365
351
|
class AmLyrics extends i {
|
|
366
352
|
constructor() {
|
|
367
353
|
super(...arguments);
|
|
368
354
|
this.downloadFormat = 'auto';
|
|
369
355
|
this.highlightColor = '#ffffff';
|
|
370
|
-
this.hoverBackgroundColor = 'rgba(255, 255, 255, 0.13)';
|
|
371
356
|
this.autoScroll = true;
|
|
372
357
|
this.interpolate = true;
|
|
373
358
|
this.showRomanization = false;
|
|
@@ -412,6 +397,10 @@ class AmLyrics extends i {
|
|
|
412
397
|
// Syllable animation tracking
|
|
413
398
|
this.lastActiveIndex = 0;
|
|
414
399
|
this.visibleLineIds = new Set();
|
|
400
|
+
// Cached element tracking to avoid repeated querySelectorAll calls
|
|
401
|
+
this.preActiveLineElements = [];
|
|
402
|
+
this.positionedLineElements = [];
|
|
403
|
+
this.activeGapLineElements = [];
|
|
415
404
|
// Bound handler references for proper event listener removal
|
|
416
405
|
this._boundHandleUserScroll = this.handleUserScroll.bind(this);
|
|
417
406
|
this._boundAnimateProgress = this.animateProgress.bind(this);
|
|
@@ -484,6 +473,31 @@ class AmLyrics extends i {
|
|
|
484
473
|
}
|
|
485
474
|
set currentTime(value) {
|
|
486
475
|
const oldValue = this._currentTime;
|
|
476
|
+
// If the new time is significantly smaller than the old time (e.g. song looped)
|
|
477
|
+
if (value < oldValue && oldValue - value > 1000 && this.lyrics) {
|
|
478
|
+
this.activeLineIndices = [];
|
|
479
|
+
this.activeMainWordIndices.clear();
|
|
480
|
+
this.activeBackgroundWordIndices.clear();
|
|
481
|
+
this.mainWordProgress.clear();
|
|
482
|
+
this.backgroundWordProgress.clear();
|
|
483
|
+
this.mainWordAnimations.clear();
|
|
484
|
+
this.backgroundWordAnimations.clear();
|
|
485
|
+
this.preActiveLineElements = [];
|
|
486
|
+
this.positionedLineElements = [];
|
|
487
|
+
this.activeGapLineElements = [];
|
|
488
|
+
// Stop all running animations and clear highlights immediately
|
|
489
|
+
if (this.lyricsContainer) {
|
|
490
|
+
const activeLines = this.lyricsContainer.querySelectorAll('.lyrics-line.active, .lyrics-line.pre-active');
|
|
491
|
+
activeLines.forEach(line => {
|
|
492
|
+
line.classList.remove('active', 'pre-active');
|
|
493
|
+
AmLyrics.resetSyllables(line);
|
|
494
|
+
});
|
|
495
|
+
const activeGaps = this.lyricsContainer.querySelectorAll('.lyrics-gap.active, .lyrics-gap.gap-exiting');
|
|
496
|
+
activeGaps.forEach(gap => gap.classList.remove('active', 'gap-exiting'));
|
|
497
|
+
// Reset gap cache since we manually messed with the elements
|
|
498
|
+
this.gapElementCache.clear();
|
|
499
|
+
}
|
|
500
|
+
}
|
|
487
501
|
this._currentTime = value;
|
|
488
502
|
if (oldValue !== value && this.lyrics) {
|
|
489
503
|
this._onTimeChanged(oldValue, value);
|
|
@@ -545,6 +559,9 @@ class AmLyrics extends i {
|
|
|
545
559
|
this.lyricsContainer.removeEventListener('wheel', this._boundHandleUserScroll);
|
|
546
560
|
this.lyricsContainer.removeEventListener('touchmove', this._boundHandleUserScroll);
|
|
547
561
|
}
|
|
562
|
+
this.preActiveLineElements = [];
|
|
563
|
+
this.positionedLineElements = [];
|
|
564
|
+
this.activeGapLineElements = [];
|
|
548
565
|
}
|
|
549
566
|
async fetchLyrics() {
|
|
550
567
|
// Cancel any in-flight fetch to prevent stale results from racing
|
|
@@ -579,16 +596,7 @@ class AmLyrics extends i {
|
|
|
579
596
|
}
|
|
580
597
|
}
|
|
581
598
|
if (collectedSources.length === 0 && resolvedMetadata?.metadata) {
|
|
582
|
-
|
|
583
|
-
if (tidalResult && tidalResult.lines.length > 0) {
|
|
584
|
-
collectedSources.push({
|
|
585
|
-
lines: tidalResult.lines,
|
|
586
|
-
source: 'Tidal',
|
|
587
|
-
});
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
// Fallback: LRCLIB
|
|
591
|
-
if (collectedSources.length === 0 && resolvedMetadata?.metadata) {
|
|
599
|
+
// Fallback: LRCLIB
|
|
592
600
|
const lrclibResult = await AmLyrics.fetchLyricsFromLrclib(resolvedMetadata.metadata);
|
|
593
601
|
if (lrclibResult && lrclibResult.lines.length > 0) {
|
|
594
602
|
collectedSources.push({
|
|
@@ -608,15 +616,17 @@ class AmLyrics extends i {
|
|
|
608
616
|
}
|
|
609
617
|
this.hasFetchedAllProviders =
|
|
610
618
|
collectedSources.length === 0 ||
|
|
611
|
-
collectedSources.some(s => s.source === 'LRCLIB' ||
|
|
612
|
-
s.source === 'Tidal' ||
|
|
613
|
-
s.source === 'Genius');
|
|
619
|
+
collectedSources.some(s => s.source === 'LRCLIB' || s.source === 'Genius');
|
|
614
620
|
this._updateFooter();
|
|
615
621
|
if (collectedSources.length > 0) {
|
|
616
622
|
this.availableSources = AmLyrics.mergeAndSortSources(collectedSources);
|
|
617
623
|
this.currentSourceIndex = 0;
|
|
618
|
-
|
|
619
|
-
this.
|
|
624
|
+
const sourceResult = this.availableSources[0];
|
|
625
|
+
this.lyrics = sourceResult.lines;
|
|
626
|
+
this.lyricsSource = sourceResult.source;
|
|
627
|
+
if (sourceResult.songwriters) {
|
|
628
|
+
this.songwriters = sourceResult.songwriters;
|
|
629
|
+
}
|
|
620
630
|
await this.onLyricsLoaded();
|
|
621
631
|
return;
|
|
622
632
|
}
|
|
@@ -638,6 +648,9 @@ class AmLyrics extends i {
|
|
|
638
648
|
this.backgroundWordProgress.clear();
|
|
639
649
|
this.mainWordAnimations.clear();
|
|
640
650
|
this.backgroundWordAnimations.clear();
|
|
651
|
+
this.preActiveLineElements = [];
|
|
652
|
+
this.positionedLineElements = [];
|
|
653
|
+
this.activeGapLineElements = [];
|
|
641
654
|
if (this.lyricsContainer) {
|
|
642
655
|
this.isProgrammaticScroll = true;
|
|
643
656
|
this.lyricsContainer.scrollTop = 0;
|
|
@@ -667,36 +680,30 @@ class AmLyrics extends i {
|
|
|
667
680
|
return 2;
|
|
668
681
|
if (lower.includes('musixmatch') && hasWordSync)
|
|
669
682
|
return 3;
|
|
670
|
-
if (lower.includes('tidal') && hasWordSync)
|
|
671
|
-
return 4;
|
|
672
683
|
if (lower.includes('lrclib') && hasWordSync)
|
|
673
|
-
return
|
|
684
|
+
return 4;
|
|
674
685
|
if (hasWordSync)
|
|
675
|
-
return
|
|
686
|
+
return 5;
|
|
676
687
|
if (lower.includes('apple') && !hasWordSync && !isUnsynced)
|
|
677
|
-
return
|
|
688
|
+
return 6;
|
|
678
689
|
if (isQQ && !hasWordSync && !isUnsynced)
|
|
679
|
-
return
|
|
690
|
+
return 7;
|
|
680
691
|
if (lower.includes('musixmatch') && !hasWordSync && !isUnsynced)
|
|
681
|
-
return
|
|
682
|
-
if (lower.includes('tidal') && !hasWordSync && !isUnsynced)
|
|
683
|
-
return 10;
|
|
692
|
+
return 8;
|
|
684
693
|
if (lower.includes('lrclib') && !hasWordSync && !isUnsynced)
|
|
685
|
-
return
|
|
694
|
+
return 9;
|
|
686
695
|
if (!hasWordSync && !isUnsynced)
|
|
687
|
-
return
|
|
696
|
+
return 10;
|
|
688
697
|
if (lower.includes('apple') && isUnsynced)
|
|
689
|
-
return
|
|
698
|
+
return 11;
|
|
690
699
|
if (isQQ && isUnsynced)
|
|
691
|
-
return
|
|
700
|
+
return 12;
|
|
692
701
|
if (lower.includes('musixmatch') && isUnsynced)
|
|
693
|
-
return
|
|
694
|
-
if (lower.includes('tidal') && isUnsynced)
|
|
695
|
-
return 16;
|
|
702
|
+
return 13;
|
|
696
703
|
if (lower.includes('lrclib') && isUnsynced)
|
|
697
|
-
return
|
|
704
|
+
return 14;
|
|
698
705
|
if (lower.includes('genius'))
|
|
699
|
-
return
|
|
706
|
+
return 15;
|
|
700
707
|
return 20;
|
|
701
708
|
}
|
|
702
709
|
static mergeAndSortSources(collectedSources) {
|
|
@@ -727,13 +734,6 @@ class AmLyrics extends i {
|
|
|
727
734
|
const resolvedMetadata = await this.resolveSongMetadata();
|
|
728
735
|
if (resolvedMetadata?.metadata) {
|
|
729
736
|
const newSources = [];
|
|
730
|
-
// Try Tidal if not fetched
|
|
731
|
-
if (!this.availableSources.some(s => s.source.toLowerCase().includes('tidal'))) {
|
|
732
|
-
const tidalResult = await AmLyrics.fetchLyricsFromTidal(resolvedMetadata.metadata, resolvedMetadata.catalogIsrc);
|
|
733
|
-
if (tidalResult && tidalResult.lines.length > 0) {
|
|
734
|
-
newSources.push({ lines: tidalResult.lines, source: 'Tidal' });
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
737
|
// Try LRCLIB if not fetched
|
|
738
738
|
if (!this.availableSources.some(s => s.source.toLowerCase().includes('lrclib'))) {
|
|
739
739
|
const lrclibResult = await AmLyrics.fetchLyricsFromLrclib(resolvedMetadata.metadata);
|
|
@@ -768,8 +768,12 @@ class AmLyrics extends i {
|
|
|
768
768
|
if (this.availableSources.length > 1) {
|
|
769
769
|
this.currentSourceIndex =
|
|
770
770
|
(this.currentSourceIndex + 1) % this.availableSources.length;
|
|
771
|
-
|
|
772
|
-
this.
|
|
771
|
+
const sourceResult = this.availableSources[this.currentSourceIndex];
|
|
772
|
+
this.lyrics = sourceResult.lines;
|
|
773
|
+
this.lyricsSource = sourceResult.source;
|
|
774
|
+
if (sourceResult.songwriters) {
|
|
775
|
+
this.songwriters = sourceResult.songwriters;
|
|
776
|
+
}
|
|
773
777
|
await this.onLyricsLoaded();
|
|
774
778
|
}
|
|
775
779
|
}
|
|
@@ -778,6 +782,7 @@ class AmLyrics extends i {
|
|
|
778
782
|
title: this.songTitle?.trim() ?? '',
|
|
779
783
|
artist: this.songArtist?.trim() ?? '',
|
|
780
784
|
album: this.songAlbum?.trim() || undefined,
|
|
785
|
+
songwriters: this.songwriters?.trim() || undefined,
|
|
781
786
|
durationMs: undefined,
|
|
782
787
|
};
|
|
783
788
|
if (typeof this.songDurationMs === 'number' && this.songDurationMs > 0) {
|
|
@@ -817,6 +822,9 @@ class AmLyrics extends i {
|
|
|
817
822
|
if (!metadata.album && catalogResult.album) {
|
|
818
823
|
metadata.album = catalogResult.album;
|
|
819
824
|
}
|
|
825
|
+
if (!metadata.songwriters && catalogResult.songwriters) {
|
|
826
|
+
metadata.songwriters = catalogResult.songwriters;
|
|
827
|
+
}
|
|
820
828
|
if (metadata.durationMs == null &&
|
|
821
829
|
typeof catalogResult.durationMs === 'number' &&
|
|
822
830
|
catalogResult.durationMs > 0) {
|
|
@@ -1007,9 +1015,13 @@ class AmLyrics extends i {
|
|
|
1007
1015
|
const ttmlRes = await fetchWithTimeout(result.lyricsUrl);
|
|
1008
1016
|
if (ttmlRes.ok) {
|
|
1009
1017
|
const ttmlText = await ttmlRes.text();
|
|
1010
|
-
const
|
|
1011
|
-
if (
|
|
1012
|
-
allResults.push({
|
|
1018
|
+
const parseResult = AmLyrics.parseTTML(ttmlText);
|
|
1019
|
+
if (parseResult && parseResult.lines.length > 0) {
|
|
1020
|
+
allResults.push({
|
|
1021
|
+
lines: parseResult.lines,
|
|
1022
|
+
source: 'BiniLyrics',
|
|
1023
|
+
songwriters: parseResult.songwriters,
|
|
1024
|
+
});
|
|
1013
1025
|
return allResults;
|
|
1014
1026
|
}
|
|
1015
1027
|
}
|
|
@@ -1041,11 +1053,12 @@ class AmLyrics extends i {
|
|
|
1041
1053
|
const ttmlRes = await fetchWithTimeout(result.lyricsUrl);
|
|
1042
1054
|
if (ttmlRes.ok) {
|
|
1043
1055
|
const ttmlText = await ttmlRes.text();
|
|
1044
|
-
const
|
|
1045
|
-
if (
|
|
1056
|
+
const parseResult = AmLyrics.parseTTML(ttmlText);
|
|
1057
|
+
if (parseResult && parseResult.lines.length > 0) {
|
|
1046
1058
|
allResults.push({
|
|
1047
|
-
lines,
|
|
1059
|
+
lines: parseResult.lines,
|
|
1048
1060
|
source: 'BiniLyrics',
|
|
1061
|
+
songwriters: parseResult.songwriters,
|
|
1049
1062
|
});
|
|
1050
1063
|
return allResults;
|
|
1051
1064
|
}
|
|
@@ -1178,77 +1191,6 @@ class AmLyrics extends i {
|
|
|
1178
1191
|
}
|
|
1179
1192
|
return lines;
|
|
1180
1193
|
}
|
|
1181
|
-
/**
|
|
1182
|
-
* Fetch lyrics from Tidal API.
|
|
1183
|
-
* Picks 2 random servers, tries search + lyrics on each.
|
|
1184
|
-
*/
|
|
1185
|
-
static async fetchLyricsFromTidal(metadata, isrc) {
|
|
1186
|
-
const title = metadata.title?.trim();
|
|
1187
|
-
const artist = metadata.artist?.trim();
|
|
1188
|
-
if (!title || !artist)
|
|
1189
|
-
return null;
|
|
1190
|
-
// Pick 3 random unique servers for better reliability
|
|
1191
|
-
const shuffled = [...TIDAL_SERVERS].sort(() => Math.random() - 0.5);
|
|
1192
|
-
const serversToTry = shuffled.slice(0, 3);
|
|
1193
|
-
for (const base of serversToTry) {
|
|
1194
|
-
try {
|
|
1195
|
-
const normalizedBase = base.endsWith('/') ? base.slice(0, -1) : base;
|
|
1196
|
-
// Step 1: Search for the track
|
|
1197
|
-
const searchQuery = `${title} ${artist}`;
|
|
1198
|
-
const searchParams = new URLSearchParams({ s: searchQuery });
|
|
1199
|
-
// eslint-disable-next-line no-await-in-loop
|
|
1200
|
-
const searchResponse = await fetchWithTimeout(`${normalizedBase}/search/?${searchParams.toString()}`);
|
|
1201
|
-
if (!searchResponse.ok) {
|
|
1202
|
-
// eslint-disable-next-line no-continue
|
|
1203
|
-
continue;
|
|
1204
|
-
}
|
|
1205
|
-
// eslint-disable-next-line no-await-in-loop
|
|
1206
|
-
const searchData = await searchResponse.json();
|
|
1207
|
-
const items = searchData?.data?.items;
|
|
1208
|
-
if (!Array.isArray(items) || items.length === 0) {
|
|
1209
|
-
// eslint-disable-next-line no-continue
|
|
1210
|
-
continue;
|
|
1211
|
-
}
|
|
1212
|
-
// Find best match: prefer ISRC match, then first result
|
|
1213
|
-
let bestTrack = items[0];
|
|
1214
|
-
if (isrc) {
|
|
1215
|
-
const isrcMatch = items.find((item) => item.isrc && item.isrc.toLowerCase() === isrc.toLowerCase());
|
|
1216
|
-
if (isrcMatch) {
|
|
1217
|
-
bestTrack = isrcMatch;
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
const trackId = bestTrack?.id;
|
|
1221
|
-
if (!trackId) {
|
|
1222
|
-
// eslint-disable-next-line no-continue
|
|
1223
|
-
continue;
|
|
1224
|
-
}
|
|
1225
|
-
// Step 2: Fetch lyrics
|
|
1226
|
-
// eslint-disable-next-line no-await-in-loop
|
|
1227
|
-
const lyricsResponse = await fetchWithTimeout(`${normalizedBase}/lyrics/?id=${trackId}`);
|
|
1228
|
-
if (!lyricsResponse.ok) {
|
|
1229
|
-
// eslint-disable-next-line no-continue
|
|
1230
|
-
continue;
|
|
1231
|
-
}
|
|
1232
|
-
// eslint-disable-next-line no-await-in-loop
|
|
1233
|
-
const lyricsData = await lyricsResponse.json();
|
|
1234
|
-
const subtitles = lyricsData?.lyrics?.subtitles;
|
|
1235
|
-
if (subtitles && typeof subtitles === 'string') {
|
|
1236
|
-
const lines = AmLyrics.parseLrcSubtitles(subtitles);
|
|
1237
|
-
if (lines.length > 0) {
|
|
1238
|
-
const provider = lyricsData?.lyrics?.lyricsProvider || 'Tidal';
|
|
1239
|
-
return {
|
|
1240
|
-
lines,
|
|
1241
|
-
source: `Tidal (${provider})`,
|
|
1242
|
-
};
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
catch {
|
|
1247
|
-
// Try next server
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
return null;
|
|
1251
|
-
}
|
|
1252
1194
|
/**
|
|
1253
1195
|
* Fetch lyrics from LRCLIB.
|
|
1254
1196
|
* Uses search endpoint, prefers synced lyrics.
|
|
@@ -1431,6 +1373,19 @@ class AmLyrics extends i {
|
|
|
1431
1373
|
agentMap[id] = type;
|
|
1432
1374
|
}
|
|
1433
1375
|
}
|
|
1376
|
+
let songwriters;
|
|
1377
|
+
const songwritersNodes = doc.getElementsByTagName('songwriter');
|
|
1378
|
+
if (songwritersNodes.length > 0) {
|
|
1379
|
+
const names = [];
|
|
1380
|
+
for (let i = 0; i < songwritersNodes.length; i += 1) {
|
|
1381
|
+
if (songwritersNodes[i].textContent) {
|
|
1382
|
+
names.push(songwritersNodes[i].textContent);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
if (names.length > 0) {
|
|
1386
|
+
songwriters = names.join(', ');
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1434
1389
|
const translationNodes = doc.getElementsByTagName('translation');
|
|
1435
1390
|
for (let i = 0; i < translationNodes.length; i += 1) {
|
|
1436
1391
|
const texts = translationNodes[i].getElementsByTagName('text');
|
|
@@ -1547,7 +1502,7 @@ class AmLyrics extends i {
|
|
|
1547
1502
|
text: bgText,
|
|
1548
1503
|
timestamp: timeToMs(bgSpan.getAttribute('begin')),
|
|
1549
1504
|
endtime: timeToMs(bgSpan.getAttribute('end')),
|
|
1550
|
-
part:
|
|
1505
|
+
part: !/\s$/.test(bgText),
|
|
1551
1506
|
});
|
|
1552
1507
|
}
|
|
1553
1508
|
// eslint-disable-next-line no-continue
|
|
@@ -1570,7 +1525,7 @@ class AmLyrics extends i {
|
|
|
1570
1525
|
text,
|
|
1571
1526
|
timestamp: timeToMs(span.getAttribute('begin')),
|
|
1572
1527
|
endtime: timeToMs(span.getAttribute('end')),
|
|
1573
|
-
part:
|
|
1528
|
+
part: !/\s$/.test(text),
|
|
1574
1529
|
});
|
|
1575
1530
|
}
|
|
1576
1531
|
}
|
|
@@ -1656,7 +1611,7 @@ class AmLyrics extends i {
|
|
|
1656
1611
|
oppositeTurn: alignment === 'end',
|
|
1657
1612
|
});
|
|
1658
1613
|
}
|
|
1659
|
-
return lines;
|
|
1614
|
+
return { lines, songwriters };
|
|
1660
1615
|
}
|
|
1661
1616
|
catch (e) {
|
|
1662
1617
|
// eslint-disable-next-line no-console
|
|
@@ -1821,7 +1776,10 @@ class AmLyrics extends i {
|
|
|
1821
1776
|
if (!newActiveLines.includes(lineIndex)) {
|
|
1822
1777
|
const lineElement = this._getLineElement(lineIndex);
|
|
1823
1778
|
if (lineElement) {
|
|
1824
|
-
lineElement.classList.remove('active');
|
|
1779
|
+
lineElement.classList.remove('active', 'pre-active');
|
|
1780
|
+
const preIdx = this.preActiveLineElements.indexOf(lineElement);
|
|
1781
|
+
if (preIdx !== -1)
|
|
1782
|
+
this.preActiveLineElements.splice(preIdx, 1);
|
|
1825
1783
|
AmLyrics.resetSyllables(lineElement);
|
|
1826
1784
|
}
|
|
1827
1785
|
}
|
|
@@ -1833,6 +1791,9 @@ class AmLyrics extends i {
|
|
|
1833
1791
|
if (lineElement) {
|
|
1834
1792
|
lineElement.classList.add('active');
|
|
1835
1793
|
lineElement.classList.remove('pre-active');
|
|
1794
|
+
const preIdx = this.preActiveLineElements.indexOf(lineElement);
|
|
1795
|
+
if (preIdx !== -1)
|
|
1796
|
+
this.preActiveLineElements.splice(preIdx, 1);
|
|
1836
1797
|
}
|
|
1837
1798
|
}
|
|
1838
1799
|
}
|
|
@@ -1852,10 +1813,9 @@ class AmLyrics extends i {
|
|
|
1852
1813
|
}
|
|
1853
1814
|
}
|
|
1854
1815
|
// Also update syllables in active gap lines (breathing dots)
|
|
1855
|
-
const
|
|
1856
|
-
activeGaps.forEach(gapLine => {
|
|
1816
|
+
for (const gapLine of this.activeGapLineElements) {
|
|
1857
1817
|
AmLyrics.updateSyllablesForLine(gapLine, newTime);
|
|
1858
|
-
}
|
|
1818
|
+
}
|
|
1859
1819
|
// Imperatively manage gap active state
|
|
1860
1820
|
if (this.gapElementCache.size > 0) {
|
|
1861
1821
|
for (const [, gap] of this.gapElementCache) {
|
|
@@ -1866,9 +1826,21 @@ class AmLyrics extends i {
|
|
|
1866
1826
|
const isExiting = gap.classList.contains('gap-exiting');
|
|
1867
1827
|
const exitLeadMs = GAP_EXIT_LEAD_MS;
|
|
1868
1828
|
const shouldStartExiting = isActive && !isExiting && newTime >= gapEndTime - exitLeadMs;
|
|
1869
|
-
if (shouldBeActive && !isActive && !isExiting) {
|
|
1829
|
+
if (shouldBeActive && (!isActive || isSeek) && !isExiting) {
|
|
1870
1830
|
gap.classList.remove('gap-exiting');
|
|
1831
|
+
if (isSeek && isActive) {
|
|
1832
|
+
gap.classList.remove('active');
|
|
1833
|
+
// eslint-disable-next-line no-void
|
|
1834
|
+
void gap.offsetWidth; // Force reflow
|
|
1835
|
+
}
|
|
1836
|
+
const gapDuration = gapEndTime - gapStartTime;
|
|
1837
|
+
const baseLoopDelay = AmLyrics.getGapLoopDelay(gapDuration);
|
|
1838
|
+
const totalDelay = baseLoopDelay + (newTime - gapStartTime);
|
|
1839
|
+
gap.style.setProperty('--gap-loop-delay', `-${totalDelay}ms`);
|
|
1871
1840
|
gap.classList.add('active');
|
|
1841
|
+
if (!this.activeGapLineElements.includes(gap)) {
|
|
1842
|
+
this.activeGapLineElements.push(gap);
|
|
1843
|
+
}
|
|
1872
1844
|
const dotSyllables = gap.querySelectorAll('.lyrics-syllable');
|
|
1873
1845
|
dotSyllables.forEach(dot => {
|
|
1874
1846
|
const dotStart = parseFloat(dot.getAttribute('data-start-time') || '0');
|
|
@@ -1876,24 +1848,34 @@ class AmLyrics extends i {
|
|
|
1876
1848
|
if (newTime > dotEnd) {
|
|
1877
1849
|
dot.classList.add('finished');
|
|
1878
1850
|
if (!dot.classList.contains('highlight')) {
|
|
1879
|
-
AmLyrics.updateSyllableAnimation(dot);
|
|
1851
|
+
AmLyrics.updateSyllableAnimation(dot, newTime - dotStart);
|
|
1880
1852
|
}
|
|
1881
1853
|
}
|
|
1882
1854
|
else if (newTime >= dotStart && newTime <= dotEnd) {
|
|
1883
|
-
AmLyrics.updateSyllableAnimation(dot);
|
|
1855
|
+
AmLyrics.updateSyllableAnimation(dot, newTime - dotStart);
|
|
1884
1856
|
}
|
|
1885
1857
|
});
|
|
1886
1858
|
}
|
|
1887
1859
|
else if (shouldStartExiting) {
|
|
1888
|
-
gap
|
|
1860
|
+
// Cancel gap-loop first, force reflow, then start gap-ended
|
|
1861
|
+
// so the browser sees a clean animation swap
|
|
1889
1862
|
gap.classList.remove('active');
|
|
1863
|
+
// eslint-disable-next-line no-void
|
|
1864
|
+
void gap.offsetWidth;
|
|
1865
|
+
gap.classList.add('gap-exiting');
|
|
1866
|
+
const gapIdx = this.activeGapLineElements.indexOf(gap);
|
|
1867
|
+
if (gapIdx !== -1)
|
|
1868
|
+
this.activeGapLineElements.splice(gapIdx, 1);
|
|
1890
1869
|
setTimeout(() => {
|
|
1891
1870
|
gap.classList.remove('gap-exiting');
|
|
1892
1871
|
}, GAP_EXIT_LEAD_MS);
|
|
1893
1872
|
}
|
|
1894
|
-
else if (
|
|
1873
|
+
else if (!shouldBeActive && (isActive || isExiting)) {
|
|
1895
1874
|
gap.classList.remove('active');
|
|
1896
1875
|
gap.classList.remove('gap-exiting');
|
|
1876
|
+
const gapIdx = this.activeGapLineElements.indexOf(gap);
|
|
1877
|
+
if (gapIdx !== -1)
|
|
1878
|
+
this.activeGapLineElements.splice(gapIdx, 1);
|
|
1897
1879
|
}
|
|
1898
1880
|
else if (isExiting && newTime < gapEndTime - exitLeadMs) {
|
|
1899
1881
|
gap.classList.remove('gap-exiting');
|
|
@@ -1911,20 +1893,41 @@ class AmLyrics extends i {
|
|
|
1911
1893
|
const isExiting = gap.classList.contains('gap-exiting');
|
|
1912
1894
|
const exitLeadMs = GAP_EXIT_LEAD_MS;
|
|
1913
1895
|
const shouldStartExiting = isActive && !isExiting && newTime >= gapEndTime - exitLeadMs;
|
|
1914
|
-
if (shouldBeActive && !isActive && !isExiting) {
|
|
1896
|
+
if (shouldBeActive && (!isActive || isSeek) && !isExiting) {
|
|
1915
1897
|
gap.classList.remove('gap-exiting');
|
|
1898
|
+
if (isSeek && isActive) {
|
|
1899
|
+
gap.classList.remove('active');
|
|
1900
|
+
// eslint-disable-next-line no-void
|
|
1901
|
+
void gap.offsetWidth; // Force reflow
|
|
1902
|
+
}
|
|
1903
|
+
const gapDuration = gapEndTime - gapStartTime;
|
|
1904
|
+
const baseLoopDelay = AmLyrics.getGapLoopDelay(gapDuration);
|
|
1905
|
+
const totalDelay = baseLoopDelay + (newTime - gapStartTime);
|
|
1906
|
+
gap.style.setProperty('--gap-loop-delay', `-${totalDelay}ms`);
|
|
1916
1907
|
gap.classList.add('active');
|
|
1908
|
+
if (!this.activeGapLineElements.includes(gap)) {
|
|
1909
|
+
this.activeGapLineElements.push(gap);
|
|
1910
|
+
}
|
|
1917
1911
|
}
|
|
1918
1912
|
else if (shouldStartExiting) {
|
|
1919
|
-
gap
|
|
1913
|
+
// Cancel gap-loop first, force reflow, then start gap-ended
|
|
1920
1914
|
gap.classList.remove('active');
|
|
1915
|
+
// eslint-disable-next-line no-void
|
|
1916
|
+
void gap.offsetWidth;
|
|
1917
|
+
gap.classList.add('gap-exiting');
|
|
1918
|
+
const gapIdx = this.activeGapLineElements.indexOf(gap);
|
|
1919
|
+
if (gapIdx !== -1)
|
|
1920
|
+
this.activeGapLineElements.splice(gapIdx, 1);
|
|
1921
1921
|
setTimeout(() => {
|
|
1922
1922
|
gap.classList.remove('gap-exiting');
|
|
1923
1923
|
}, GAP_EXIT_LEAD_MS);
|
|
1924
1924
|
}
|
|
1925
|
-
else if (
|
|
1925
|
+
else if (!shouldBeActive && (isActive || isExiting)) {
|
|
1926
1926
|
gap.classList.remove('active');
|
|
1927
1927
|
gap.classList.remove('gap-exiting');
|
|
1928
|
+
const gapIdx = this.activeGapLineElements.indexOf(gap);
|
|
1929
|
+
if (gapIdx !== -1)
|
|
1930
|
+
this.activeGapLineElements.splice(gapIdx, 1);
|
|
1928
1931
|
}
|
|
1929
1932
|
else if (isExiting && newTime < gapEndTime - exitLeadMs) {
|
|
1930
1933
|
gap.classList.remove('gap-exiting');
|
|
@@ -1939,6 +1942,25 @@ class AmLyrics extends i {
|
|
|
1939
1942
|
else if (this.lastInstrumentalIndex !== null) {
|
|
1940
1943
|
this.lastInstrumentalIndex = null;
|
|
1941
1944
|
}
|
|
1945
|
+
// Check footer active state
|
|
1946
|
+
const lastLyric = this.lyrics && this.lyrics.length > 0
|
|
1947
|
+
? this.lyrics[this.lyrics.length - 1]
|
|
1948
|
+
: null;
|
|
1949
|
+
const footer = this.lyricsContainer.querySelector('.lyrics-footer');
|
|
1950
|
+
if (footer && lastLyric && lastLyric.endtime > 0) {
|
|
1951
|
+
const isFooterActive = newTime > lastLyric.endtime + 200; // Snappier 200ms buffer
|
|
1952
|
+
if (isFooterActive && !footer.classList.contains('active')) {
|
|
1953
|
+
footer.classList.add('active');
|
|
1954
|
+
if (this.autoScroll &&
|
|
1955
|
+
!this.isUserScrolling &&
|
|
1956
|
+
!this.isClickSeeking) {
|
|
1957
|
+
this.focusLine(footer);
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
else if (!isFooterActive && footer.classList.contains('active')) {
|
|
1961
|
+
footer.classList.remove('active');
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1942
1964
|
// Pre-scroll: scroll to upcoming line ~0.5s before it starts
|
|
1943
1965
|
if (this.autoScroll &&
|
|
1944
1966
|
!this.isUserScrolling &&
|
|
@@ -1961,6 +1983,9 @@ class AmLyrics extends i {
|
|
|
1961
1983
|
preActiveLineIndex = i;
|
|
1962
1984
|
if (!isBackToBack) {
|
|
1963
1985
|
nextLineEl.classList.add('pre-active');
|
|
1986
|
+
if (!this.preActiveLineElements.includes(nextLineEl)) {
|
|
1987
|
+
this.preActiveLineElements.push(nextLineEl);
|
|
1988
|
+
}
|
|
1964
1989
|
}
|
|
1965
1990
|
this.clearPreActiveClasses(i);
|
|
1966
1991
|
const slowScrollDuration = Math.max(SCROLL_ANIMATION_DURATION_MS, timeUntilStart);
|
|
@@ -1990,6 +2015,9 @@ class AmLyrics extends i {
|
|
|
1990
2015
|
if (lineEl)
|
|
1991
2016
|
lineEl.classList.add('active');
|
|
1992
2017
|
}
|
|
2018
|
+
// Trigger a faux time-change so that updateSyllablesForLine fires
|
|
2019
|
+
// to setup inline syllable CSS wipe animations for whatever the current time is
|
|
2020
|
+
this._onTimeChanged(0, this.currentTime);
|
|
1993
2021
|
}
|
|
1994
2022
|
}
|
|
1995
2023
|
// Handle duration reset (-1 stops playback and resets currentTime to 0)
|
|
@@ -2002,6 +2030,9 @@ class AmLyrics extends i {
|
|
|
2002
2030
|
this.backgroundWordProgress.clear();
|
|
2003
2031
|
this.mainWordAnimations.clear();
|
|
2004
2032
|
this.backgroundWordAnimations.clear();
|
|
2033
|
+
this.preActiveLineElements = [];
|
|
2034
|
+
this.positionedLineElements = [];
|
|
2035
|
+
this.activeGapLineElements = [];
|
|
2005
2036
|
this.setUserScrolling(false);
|
|
2006
2037
|
// Cancel any running animations
|
|
2007
2038
|
if (this.animationFrameId) {
|
|
@@ -2055,7 +2086,7 @@ class AmLyrics extends i {
|
|
|
2055
2086
|
const gap = this.lyrics[targetLineIndex].timestamp -
|
|
2056
2087
|
this.lyrics[prevPrimaryIndex].endtime;
|
|
2057
2088
|
if (gap > 200) {
|
|
2058
|
-
scrollDuration = Math.min(Math.max(gap * 0.
|
|
2089
|
+
scrollDuration = Math.min(Math.max(gap * 0.85, SCROLL_ANIMATION_DURATION_MS), 4000);
|
|
2059
2090
|
}
|
|
2060
2091
|
}
|
|
2061
2092
|
this.focusLine(targetLine, forceScroll, scrollDuration);
|
|
@@ -2117,6 +2148,9 @@ class AmLyrics extends i {
|
|
|
2117
2148
|
this.cachedLineData = null;
|
|
2118
2149
|
this.lineElementCache.clear();
|
|
2119
2150
|
this.gapElementCache.clear();
|
|
2151
|
+
this.preActiveLineElements = [];
|
|
2152
|
+
this.positionedLineElements = [];
|
|
2153
|
+
this.activeGapLineElements = [];
|
|
2120
2154
|
}
|
|
2121
2155
|
_updateCachedIsUnsynced() {
|
|
2122
2156
|
this.cachedIsUnsynced =
|
|
@@ -2129,13 +2163,23 @@ class AmLyrics extends i {
|
|
|
2129
2163
|
return;
|
|
2130
2164
|
this.cachedLineData = this.lyrics.map(line => {
|
|
2131
2165
|
const wordGroups = [];
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2166
|
+
let currentGroupBuffer = [];
|
|
2167
|
+
line.text.forEach((syllable, idx) => {
|
|
2168
|
+
currentGroupBuffer.push(syllable);
|
|
2169
|
+
const nextSyllable = line.text[idx + 1];
|
|
2170
|
+
const endsWithDelimiter = !nextSyllable ||
|
|
2171
|
+
syllable.part === false ||
|
|
2172
|
+
/\s$/.test(syllable.text) ||
|
|
2173
|
+
(nextSyllable &&
|
|
2174
|
+
syllable.isBackground !==
|
|
2175
|
+
nextSyllable.isBackground);
|
|
2176
|
+
if (endsWithDelimiter) {
|
|
2177
|
+
wordGroups.push(currentGroupBuffer);
|
|
2178
|
+
currentGroupBuffer = [];
|
|
2138
2179
|
}
|
|
2180
|
+
});
|
|
2181
|
+
if (currentGroupBuffer.length > 0) {
|
|
2182
|
+
wordGroups.push(currentGroupBuffer);
|
|
2139
2183
|
}
|
|
2140
2184
|
const groupGrowable = new Array(wordGroups.length).fill(false);
|
|
2141
2185
|
const groupGlowing = new Array(wordGroups.length).fill(false);
|
|
@@ -2144,6 +2188,7 @@ class AmLyrics extends i {
|
|
|
2144
2188
|
const vwCharOffset = new Array(wordGroups.length).fill(0);
|
|
2145
2189
|
const vwStartMs = new Array(wordGroups.length).fill(0);
|
|
2146
2190
|
const vwEndMs = new Array(wordGroups.length).fill(0);
|
|
2191
|
+
let lineIsRTL = false;
|
|
2147
2192
|
let vwStart = 0;
|
|
2148
2193
|
while (vwStart < wordGroups.length) {
|
|
2149
2194
|
let vwEnd = vwStart;
|
|
@@ -2165,9 +2210,11 @@ class AmLyrics extends i {
|
|
|
2165
2210
|
const combinedDuration = combinedEnd - combinedStart;
|
|
2166
2211
|
const isCJK = /[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/.test(combinedText);
|
|
2167
2212
|
const isRTL = /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\u0590-\u05FF]/.test(combinedText);
|
|
2213
|
+
if (isRTL)
|
|
2214
|
+
lineIsRTL = true;
|
|
2168
2215
|
const hasHyphen = combinedText.includes('-');
|
|
2169
2216
|
const wordLen = combinedText.length;
|
|
2170
|
-
let isGrowableVW = !isCJK && !isRTL && !hasHyphen && wordLen > 0 && wordLen <=
|
|
2217
|
+
let isGrowableVW = !isCJK && !isRTL && !hasHyphen && wordLen > 0 && wordLen <= 7;
|
|
2171
2218
|
if (isGrowableVW) {
|
|
2172
2219
|
if (wordLen < 3) {
|
|
2173
2220
|
isGrowableVW =
|
|
@@ -2178,7 +2225,8 @@ class AmLyrics extends i {
|
|
|
2178
2225
|
combinedDuration >= 850 && combinedDuration >= wordLen * 190;
|
|
2179
2226
|
}
|
|
2180
2227
|
}
|
|
2181
|
-
const
|
|
2228
|
+
const isLineSynced = line.isWordSynced === false || line.text.some(s => s.lineSynced);
|
|
2229
|
+
const isGlowingVW = isGrowableVW && !isLineSynced;
|
|
2182
2230
|
let charOff = 0;
|
|
2183
2231
|
for (let gi = vwStart; gi <= vwEnd; gi += 1) {
|
|
2184
2232
|
groupGrowable[gi] = isGrowableVW;
|
|
@@ -2202,6 +2250,7 @@ class AmLyrics extends i {
|
|
|
2202
2250
|
vwCharOffset,
|
|
2203
2251
|
vwStartMs,
|
|
2204
2252
|
vwEndMs,
|
|
2253
|
+
lineIsRTL,
|
|
2205
2254
|
};
|
|
2206
2255
|
});
|
|
2207
2256
|
}
|
|
@@ -2282,15 +2331,17 @@ class AmLyrics extends i {
|
|
|
2282
2331
|
clearPreActiveClasses(exceptLineIndex = null) {
|
|
2283
2332
|
if (!this.lyricsContainer)
|
|
2284
2333
|
return;
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
.forEach(element => {
|
|
2288
|
-
const lineElement = element;
|
|
2334
|
+
const keptLines = [];
|
|
2335
|
+
for (const lineElement of this.preActiveLineElements) {
|
|
2289
2336
|
const lineIndex = AmLyrics.getLineIndexFromElement(lineElement);
|
|
2290
|
-
if (lineIndex
|
|
2337
|
+
if (lineIndex === exceptLineIndex) {
|
|
2338
|
+
keptLines.push(lineElement);
|
|
2339
|
+
}
|
|
2340
|
+
else {
|
|
2291
2341
|
lineElement.classList.remove('pre-active');
|
|
2292
2342
|
}
|
|
2293
|
-
}
|
|
2343
|
+
}
|
|
2344
|
+
this.preActiveLineElements = keptLines;
|
|
2294
2345
|
}
|
|
2295
2346
|
getPrimaryActiveLineIndex(activeIndices) {
|
|
2296
2347
|
if (activeIndices.length === 0)
|
|
@@ -2740,6 +2791,7 @@ class AmLyrics extends i {
|
|
|
2740
2791
|
// Clean up any lingering scroll animations before smooth scroll
|
|
2741
2792
|
for (const line of animatingLines) {
|
|
2742
2793
|
line.classList.remove('scroll-animate');
|
|
2794
|
+
line.style.removeProperty('will-change');
|
|
2743
2795
|
line.style.removeProperty('--scroll-delta');
|
|
2744
2796
|
line.style.removeProperty('--lyrics-line-delay');
|
|
2745
2797
|
line.style.removeProperty('--scroll-duration');
|
|
@@ -2798,6 +2850,7 @@ class AmLyrics extends i {
|
|
|
2798
2850
|
// --- Step 4: Re-add scroll-animate class to start fresh animations ---
|
|
2799
2851
|
for (const line of newAnimatingLines) {
|
|
2800
2852
|
line.classList.add('scroll-animate');
|
|
2853
|
+
line.style.willChange = 'transform';
|
|
2801
2854
|
animatingLines.push(line);
|
|
2802
2855
|
}
|
|
2803
2856
|
animState.isAnimating = true;
|
|
@@ -2814,6 +2867,7 @@ class AmLyrics extends i {
|
|
|
2814
2867
|
for (let i = 0; i < animatingLines.length; i += 1) {
|
|
2815
2868
|
const line = animatingLines[i];
|
|
2816
2869
|
line.classList.remove('scroll-animate');
|
|
2870
|
+
line.style.removeProperty('will-change');
|
|
2817
2871
|
line.style.removeProperty('--scroll-delta');
|
|
2818
2872
|
line.style.removeProperty('--lyrics-line-delay');
|
|
2819
2873
|
line.style.removeProperty('--scroll-duration');
|
|
@@ -2842,12 +2896,14 @@ class AmLyrics extends i {
|
|
|
2842
2896
|
'next-3',
|
|
2843
2897
|
'next-4',
|
|
2844
2898
|
];
|
|
2845
|
-
// Remove old position classes
|
|
2846
|
-
this.
|
|
2847
|
-
.
|
|
2848
|
-
|
|
2899
|
+
// Remove old position classes from tracked elements
|
|
2900
|
+
for (const el of this.positionedLineElements) {
|
|
2901
|
+
el.classList.remove(...positionClasses);
|
|
2902
|
+
}
|
|
2903
|
+
this.positionedLineElements = [];
|
|
2849
2904
|
// Add new position classes
|
|
2850
2905
|
lineToScroll.classList.add('lyrics-activest');
|
|
2906
|
+
this.positionedLineElements.push(lineToScroll);
|
|
2851
2907
|
const lineElements = Array.from(this.lyricsContainer.querySelectorAll('.lyrics-line'));
|
|
2852
2908
|
const scrollLineIndex = lineElements.indexOf(lineToScroll);
|
|
2853
2909
|
for (let i = Math.max(0, scrollLineIndex - 4); i <= Math.min(lineElements.length - 1, scrollLineIndex + 4); i += 1) {
|
|
@@ -2862,6 +2918,7 @@ class AmLyrics extends i {
|
|
|
2862
2918
|
element.classList.add(`prev-${Math.abs(position)}`);
|
|
2863
2919
|
else
|
|
2864
2920
|
element.classList.add(`next-${position}`);
|
|
2921
|
+
this.positionedLineElements.push(element);
|
|
2865
2922
|
}
|
|
2866
2923
|
}
|
|
2867
2924
|
}
|
|
@@ -2882,7 +2939,7 @@ class AmLyrics extends i {
|
|
|
2882
2939
|
return;
|
|
2883
2940
|
}
|
|
2884
2941
|
// Skip scroll if near the bottom of content (prevents footer jitter)
|
|
2885
|
-
if (!forceScroll) {
|
|
2942
|
+
if (!forceScroll && !activeLine.classList.contains('lyrics-footer')) {
|
|
2886
2943
|
const parent = this.lyricsContainer;
|
|
2887
2944
|
const atBottom = parent.scrollTop + parent.clientHeight >= parent.scrollHeight - 50;
|
|
2888
2945
|
if (atBottom) {
|
|
@@ -2906,7 +2963,7 @@ class AmLyrics extends i {
|
|
|
2906
2963
|
* Update syllable highlight animation - apply CSS wipe animation
|
|
2907
2964
|
* (Exact copy from YouLyPlus _updateSyllableAnimation)
|
|
2908
2965
|
*/
|
|
2909
|
-
static updateSyllableAnimation(syllable) {
|
|
2966
|
+
static updateSyllableAnimation(syllable, elapsedTimeMs = 0) {
|
|
2910
2967
|
if (syllable.classList.contains('highlight'))
|
|
2911
2968
|
return;
|
|
2912
2969
|
const { classList } = syllable;
|
|
@@ -2934,8 +2991,8 @@ class AmLyrics extends i {
|
|
|
2934
2991
|
const baseDelayPerChar = finalDuration * 0.09;
|
|
2935
2992
|
const growDurationMs = finalDuration * 1.5;
|
|
2936
2993
|
allWordCharSpans.forEach(span => {
|
|
2937
|
-
const
|
|
2938
|
-
const
|
|
2994
|
+
const matrixScale = span.dataset.matrixScale || '1.1';
|
|
2995
|
+
const charOffsetX = span.dataset.charOffsetX || '0';
|
|
2939
2996
|
const shadowIntensity = span.dataset.shadowIntensity || '0.6';
|
|
2940
2997
|
const translateYPeak = span.dataset.translateYPeak || '-2';
|
|
2941
2998
|
const syllableCharIndex = parseFloat(span.dataset.syllableCharIndex || '0');
|
|
@@ -2943,13 +3000,13 @@ class AmLyrics extends i {
|
|
|
2943
3000
|
charAnimationsMap.set(span, `grow-dynamic ${growDurationMs}ms ease-in-out ${growDelay}ms forwards`);
|
|
2944
3001
|
styleUpdates.push({
|
|
2945
3002
|
element: span,
|
|
2946
|
-
property: '--
|
|
2947
|
-
value:
|
|
3003
|
+
property: '--matrix-scale',
|
|
3004
|
+
value: matrixScale,
|
|
2948
3005
|
});
|
|
2949
3006
|
styleUpdates.push({
|
|
2950
3007
|
element: span,
|
|
2951
|
-
property: '--
|
|
2952
|
-
value:
|
|
3008
|
+
property: '--char-offset-x',
|
|
3009
|
+
value: `${charOffsetX}px`,
|
|
2953
3010
|
});
|
|
2954
3011
|
styleUpdates.push({
|
|
2955
3012
|
element: span,
|
|
@@ -2959,7 +3016,7 @@ class AmLyrics extends i {
|
|
|
2959
3016
|
styleUpdates.push({
|
|
2960
3017
|
element: span,
|
|
2961
3018
|
property: '--translate-y-peak',
|
|
2962
|
-
value: `${translateYPeak}`,
|
|
3019
|
+
value: `${translateYPeak}px`,
|
|
2963
3020
|
});
|
|
2964
3021
|
});
|
|
2965
3022
|
}
|
|
@@ -2968,7 +3025,7 @@ class AmLyrics extends i {
|
|
|
2968
3025
|
charSpans.forEach((span, charIndex) => {
|
|
2969
3026
|
const startPct = parseFloat(span.dataset.wipeStart || '0');
|
|
2970
3027
|
const durationPct = parseFloat(span.dataset.wipeDuration || '0');
|
|
2971
|
-
const wipeDelay = syllableDurationMs * startPct;
|
|
3028
|
+
const wipeDelay = syllableDurationMs * startPct - elapsedTimeMs;
|
|
2972
3029
|
const wipeDuration = syllableDurationMs * durationPct;
|
|
2973
3030
|
const useStartAnimation = isFirstInContainer && charIndex === 0;
|
|
2974
3031
|
let charWipeAnimation = 'wipe';
|
|
@@ -2984,9 +3041,9 @@ class AmLyrics extends i {
|
|
|
2984
3041
|
animationParts.push(existingAnimation.split(',')[0].trim());
|
|
2985
3042
|
}
|
|
2986
3043
|
if (charIndex > 0) {
|
|
2987
|
-
const arrivalTime = span.dataset.preWipeArrival
|
|
3044
|
+
const arrivalTime = (span.dataset.preWipeArrival
|
|
2988
3045
|
? parseFloat(span.dataset.preWipeArrival)
|
|
2989
|
-
:
|
|
3046
|
+
: syllableDurationMs * startPct) - elapsedTimeMs;
|
|
2990
3047
|
const constantDuration = parseFloat(span.dataset.preWipeDuration || '100');
|
|
2991
3048
|
const animDelay = arrivalTime - constantDuration;
|
|
2992
3049
|
if (constantDuration > 0) {
|
|
@@ -3016,12 +3073,13 @@ class AmLyrics extends i {
|
|
|
3016
3073
|
return;
|
|
3017
3074
|
const currentWipeAnimation = isGap ? 'fade-gap' : wipeAnimation;
|
|
3018
3075
|
// eslint-disable-next-line no-param-reassign
|
|
3019
|
-
syllable.style.animation = `${currentWipeAnimation} ${visualDuration}ms ${isGap ? 'ease-out' : 'linear'} forwards`;
|
|
3076
|
+
syllable.style.animation = `${currentWipeAnimation} ${visualDuration}ms ${isGap ? 'ease-out' : 'linear'} ${-elapsedTimeMs}ms forwards`;
|
|
3020
3077
|
}
|
|
3021
3078
|
// --- WRITE PHASE ---
|
|
3022
3079
|
classList.remove('pre-highlight');
|
|
3023
3080
|
classList.add('highlight');
|
|
3024
3081
|
for (const [span, animationString] of charAnimationsMap.entries()) {
|
|
3082
|
+
span.style.willChange = 'transform';
|
|
3025
3083
|
span.style.animation = animationString;
|
|
3026
3084
|
}
|
|
3027
3085
|
// Apply style updates
|
|
@@ -3048,6 +3106,7 @@ class AmLyrics extends i {
|
|
|
3048
3106
|
syllable.querySelectorAll('span.char').forEach(span => {
|
|
3049
3107
|
const el = span;
|
|
3050
3108
|
el.style.animation = '';
|
|
3109
|
+
el.style.willChange = '';
|
|
3051
3110
|
el.style.transition = 'none';
|
|
3052
3111
|
el.style.backgroundColor = 'var(--lyplus-text-secondary)';
|
|
3053
3112
|
});
|
|
@@ -3061,6 +3120,7 @@ class AmLyrics extends i {
|
|
|
3061
3120
|
const el = span;
|
|
3062
3121
|
el.style.removeProperty('background-color');
|
|
3063
3122
|
el.style.removeProperty('transition');
|
|
3123
|
+
el.style.removeProperty('will-change');
|
|
3064
3124
|
});
|
|
3065
3125
|
});
|
|
3066
3126
|
}
|
|
@@ -3090,7 +3150,7 @@ class AmLyrics extends i {
|
|
|
3090
3150
|
const syllable = syllables[i];
|
|
3091
3151
|
const startTime = parseFloat(syllable.getAttribute('data-start-time') || '0');
|
|
3092
3152
|
const endTime = parseFloat(syllable.getAttribute('data-end-time') || '0');
|
|
3093
|
-
if (startTime) {
|
|
3153
|
+
if (Number.isFinite(startTime) && Number.isFinite(endTime)) {
|
|
3094
3154
|
const { classList } = syllable;
|
|
3095
3155
|
const hasHighlight = classList.contains('highlight');
|
|
3096
3156
|
const hasFinished = classList.contains('finished');
|
|
@@ -3114,7 +3174,7 @@ class AmLyrics extends i {
|
|
|
3114
3174
|
if (currentTimeMs >= startTime && currentTimeMs <= endTime) {
|
|
3115
3175
|
// Currently active
|
|
3116
3176
|
if (!hasHighlight) {
|
|
3117
|
-
AmLyrics.updateSyllableAnimation(syllable);
|
|
3177
|
+
AmLyrics.updateSyllableAnimation(syllable, currentTimeMs - startTime);
|
|
3118
3178
|
}
|
|
3119
3179
|
if (hasFinished) {
|
|
3120
3180
|
classList.remove('finished');
|
|
@@ -3124,7 +3184,7 @@ class AmLyrics extends i {
|
|
|
3124
3184
|
// Finished
|
|
3125
3185
|
if (!hasFinished) {
|
|
3126
3186
|
if (!hasHighlight) {
|
|
3127
|
-
AmLyrics.updateSyllableAnimation(syllable);
|
|
3187
|
+
AmLyrics.updateSyllableAnimation(syllable, currentTimeMs - startTime);
|
|
3128
3188
|
}
|
|
3129
3189
|
classList.add('finished');
|
|
3130
3190
|
}
|
|
@@ -3376,7 +3436,6 @@ class AmLyrics extends i {
|
|
|
3376
3436
|
}
|
|
3377
3437
|
// Set both old internal CSS variables (for backward compatibility)
|
|
3378
3438
|
// and new public CSS variables (which take precedence)
|
|
3379
|
-
this.style.setProperty('--hover-background-color', this.hoverBackgroundColor);
|
|
3380
3439
|
this.style.setProperty('--highlight-color', this.highlightColor);
|
|
3381
3440
|
const sourceLabel = this.lyricsSource ?? 'Unavailable';
|
|
3382
3441
|
const isUnsynced = this.cachedIsUnsynced;
|
|
@@ -3429,21 +3488,24 @@ class AmLyrics extends i {
|
|
|
3429
3488
|
>${syllable.romanizedText}</span
|
|
3430
3489
|
>`
|
|
3431
3490
|
: '';
|
|
3432
|
-
return b `<span class="lyrics-word"
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3491
|
+
return b `<span class="lyrics-word"
|
|
3492
|
+
><span
|
|
3493
|
+
class="lyrics-syllable-wrap${bgRomanizedText
|
|
3494
|
+
? ' has-transliteration'
|
|
3495
|
+
: ''}"
|
|
3496
|
+
><span
|
|
3497
|
+
class="lyrics-syllable no-chars${syllable.lineSynced
|
|
3498
|
+
? ' line-synced'
|
|
3437
3499
|
: ''}"
|
|
3438
3500
|
data-start-time="${startTimeMs}"
|
|
3439
3501
|
data-end-time="${endTimeMs}"
|
|
3440
3502
|
data-duration="${durationMs}"
|
|
3441
3503
|
data-syllable-index="${syllableIndex}"
|
|
3504
|
+
data-wipe-ratio="1"
|
|
3442
3505
|
>${syllable.text}</span
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
</span>`;
|
|
3506
|
+
>${bgRomanizedText}</span
|
|
3507
|
+
></span
|
|
3508
|
+
>`;
|
|
3447
3509
|
})}
|
|
3448
3510
|
</p>`
|
|
3449
3511
|
: '';
|
|
@@ -3461,8 +3523,11 @@ class AmLyrics extends i {
|
|
|
3461
3523
|
const vwFullText = lineData?.vwFullText ?? [];
|
|
3462
3524
|
const vwFullDuration = lineData?.vwFullDuration ?? [];
|
|
3463
3525
|
const vwCharOffset = lineData?.vwCharOffset ?? [];
|
|
3526
|
+
const lineIsRTL = lineData?.lineIsRTL ?? false;
|
|
3464
3527
|
// Create main vocals using YouLyPlus syllable structure
|
|
3465
|
-
const mainVocalElement = b `<p
|
|
3528
|
+
const mainVocalElement = b `<p
|
|
3529
|
+
class="main-vocal-container ${lineIsRTL ? 'rtl-text' : ''}"
|
|
3530
|
+
>
|
|
3466
3531
|
${wordGroups.map((group, groupIdx) => {
|
|
3467
3532
|
const isGrowable = groupGrowable[groupIdx];
|
|
3468
3533
|
const isGlowing = groupGlowing[groupIdx];
|
|
@@ -3472,12 +3537,21 @@ class AmLyrics extends i {
|
|
|
3472
3537
|
const wordNumChars = wordText.length;
|
|
3473
3538
|
const groupCharOffset = isGrowable ? vwCharOffset[groupIdx] : 0;
|
|
3474
3539
|
let sylCharAccumulator = 0;
|
|
3540
|
+
const groupText = group.map(s => s.text).join('');
|
|
3541
|
+
const shouldAllowBreak = groupText.trim().length >= 16 ||
|
|
3542
|
+
/[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/.test(groupText);
|
|
3543
|
+
// Calculate dynamic rise duration based on the audio duration of the word
|
|
3544
|
+
const wordStartTimeMs = group[0].timestamp;
|
|
3545
|
+
const wordEndTimeMs = group[group.length - 1].endtime;
|
|
3546
|
+
const actualDurationMs = wordEndTimeMs - wordStartTimeMs;
|
|
3547
|
+
// Base float is 0.8s, plus a portion of the audio duration, capped between 1.0s and 2.5s
|
|
3548
|
+
const riseDuration = Math.max(1.2, Math.min(2.5, 1.2 + (actualDurationMs / 1000) * 0.6));
|
|
3475
3549
|
return b `<span
|
|
3476
|
-
class="lyrics-word
|
|
3477
|
-
? 'glowing'
|
|
3478
|
-
: ''}
|
|
3479
|
-
|
|
3480
|
-
|
|
3550
|
+
class="lyrics-word${isGrowable ? ' growable' : ''}${isGlowing
|
|
3551
|
+
? ' glowing'
|
|
3552
|
+
: ''}${shouldAllowBreak ? ' allow-break' : ''}"
|
|
3553
|
+
style="--rise-duration: ${riseDuration}s"
|
|
3554
|
+
>${group.map((syllable, sylIdx) => {
|
|
3481
3555
|
const startTimeMs = syllable.timestamp;
|
|
3482
3556
|
const endTimeMs = syllable.endtime;
|
|
3483
3557
|
const durationMs = endTimeMs - startTimeMs;
|
|
@@ -3563,17 +3637,22 @@ class AmLyrics extends i {
|
|
|
3563
3637
|
data-wipe-duration="${(1 / numCharsInSyllable).toFixed(4)}"
|
|
3564
3638
|
data-horizontal-offset="${horizontalOffset.toFixed(2)}"
|
|
3565
3639
|
data-max-scale="${charMaxScale.toFixed(3)}"
|
|
3640
|
+
data-matrix-scale="${(charMaxScale * 0.98).toFixed(3)}"
|
|
3641
|
+
data-char-offset-x="${(horizontalOffset * 0.98).toFixed(2)}"
|
|
3566
3642
|
data-shadow-intensity="${charShadowIntensity.toFixed(3)}"
|
|
3567
3643
|
data-translate-y-peak="${charTranslateYPeak.toFixed(3)}"
|
|
3568
3644
|
>${char}</span
|
|
3569
3645
|
>`;
|
|
3570
3646
|
})}`;
|
|
3571
3647
|
}
|
|
3572
|
-
return b `<span
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
? 'line-synced'
|
|
3648
|
+
return b `<span
|
|
3649
|
+
class="lyrics-syllable-wrap${romanizedText
|
|
3650
|
+
? ' has-transliteration'
|
|
3576
3651
|
: ''}"
|
|
3652
|
+
><span
|
|
3653
|
+
class="lyrics-syllable${groupLineSynced
|
|
3654
|
+
? ' line-synced'
|
|
3655
|
+
: ''}${isGrowable ? ' has-chars' : ' no-chars'}"
|
|
3577
3656
|
data-start-time="${startTimeMs}"
|
|
3578
3657
|
data-end-time="${endTimeMs}"
|
|
3579
3658
|
data-duration="${durationMs}"
|
|
@@ -3581,11 +3660,10 @@ class AmLyrics extends i {
|
|
|
3581
3660
|
data-syllable-index="${sylIdx}"
|
|
3582
3661
|
data-wipe-ratio="1"
|
|
3583
3662
|
>${syllableContent}</span
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
</span>`;
|
|
3663
|
+
>${romanizedText}</span
|
|
3664
|
+
>`;
|
|
3665
|
+
})}</span
|
|
3666
|
+
>`;
|
|
3589
3667
|
})}
|
|
3590
3668
|
</p>`;
|
|
3591
3669
|
// Translation container (if enabled)
|
|
@@ -3607,7 +3685,11 @@ class AmLyrics extends i {
|
|
|
3607
3685
|
line.romanizedText &&
|
|
3608
3686
|
!line.text.some(s => s.romanizedText) &&
|
|
3609
3687
|
line.romanizedText.trim() !== fullLineText
|
|
3610
|
-
? b `<div
|
|
3688
|
+
? b `<div
|
|
3689
|
+
class="lyrics-romanization-container ${lineIsRTL
|
|
3690
|
+
? 'rtl-text'
|
|
3691
|
+
: ''}"
|
|
3692
|
+
>
|
|
3611
3693
|
${line.romanizedText}
|
|
3612
3694
|
</div>`
|
|
3613
3695
|
: '';
|
|
@@ -3627,42 +3709,37 @@ class AmLyrics extends i {
|
|
|
3627
3709
|
data-end-time="${gapForLine.gapEnd}"
|
|
3628
3710
|
style="--gap-pulse-duration: ${GAP_PULSE_DURATION_MS}ms; --gap-loop-delay: -${gapLoopDelay}ms; --gap-exit-duration: ${GAP_EXIT_LEAD_MS}ms; --gap-exit-scale: ${GAP_MIN_SCALE};"
|
|
3629
3711
|
>
|
|
3630
|
-
<
|
|
3631
|
-
<
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
></span>
|
|
3662
|
-
</span>
|
|
3663
|
-
</span>
|
|
3664
|
-
</p>
|
|
3665
|
-
</div>
|
|
3712
|
+
<p class="main-vocal-container">
|
|
3713
|
+
<span class="lyrics-word"
|
|
3714
|
+
><span class="lyrics-syllable-wrap"
|
|
3715
|
+
><span
|
|
3716
|
+
class="lyrics-syllable"
|
|
3717
|
+
data-start-time="${gapForLine.gapStart}"
|
|
3718
|
+
data-end-time="${gapForLine.gapStart + dotDuration}"
|
|
3719
|
+
data-duration="${dotDuration}"
|
|
3720
|
+
data-wipe-ratio="1"
|
|
3721
|
+
data-syllable-index="0"
|
|
3722
|
+
></span></span
|
|
3723
|
+
><span class="lyrics-syllable-wrap"
|
|
3724
|
+
><span
|
|
3725
|
+
class="lyrics-syllable"
|
|
3726
|
+
data-start-time="${gapForLine.gapStart + dotDuration}"
|
|
3727
|
+
data-end-time="${gapForLine.gapStart + dotDuration * 2}"
|
|
3728
|
+
data-duration="${dotDuration}"
|
|
3729
|
+
data-wipe-ratio="1"
|
|
3730
|
+
data-syllable-index="1"
|
|
3731
|
+
></span></span
|
|
3732
|
+
><span class="lyrics-syllable-wrap"
|
|
3733
|
+
><span
|
|
3734
|
+
class="lyrics-syllable"
|
|
3735
|
+
data-start-time="${gapForLine.gapStart + dotDuration * 2}"
|
|
3736
|
+
data-end-time="${gapForLine.gapEnd}"
|
|
3737
|
+
data-duration="${dotDuration}"
|
|
3738
|
+
data-wipe-ratio="1"
|
|
3739
|
+
data-syllable-index="2"
|
|
3740
|
+
></span></span
|
|
3741
|
+
></span>
|
|
3742
|
+
</p>
|
|
3666
3743
|
</div>`;
|
|
3667
3744
|
}
|
|
3668
3745
|
return b `
|
|
@@ -3671,7 +3748,7 @@ class AmLyrics extends i {
|
|
|
3671
3748
|
id="${lineId}"
|
|
3672
3749
|
class="lyrics-line ${line.alignment === 'end'
|
|
3673
3750
|
? 'singer-right'
|
|
3674
|
-
: 'singer-left'}"
|
|
3751
|
+
: 'singer-left'} ${lineIsRTL ? 'rtl-text' : ''}"
|
|
3675
3752
|
data-start-time="${lineStartTime}"
|
|
3676
3753
|
data-end-time="${lineEndTime}"
|
|
3677
3754
|
@click=${() => this.handleLineClick(line)}
|
|
@@ -3682,11 +3759,11 @@ class AmLyrics extends i {
|
|
|
3682
3759
|
}
|
|
3683
3760
|
}}
|
|
3684
3761
|
>
|
|
3685
|
-
<div class="lyrics-line-container">
|
|
3762
|
+
<div class="lyrics-line-container ${lineIsRTL ? 'rtl-text' : ''}">
|
|
3686
3763
|
${bgPlacement === 'before' ? backgroundVocalElement : ''}
|
|
3687
3764
|
${mainVocalElement}
|
|
3688
3765
|
${bgPlacement === 'after' ? backgroundVocalElement : ''}
|
|
3689
|
-
${
|
|
3766
|
+
${lineRomanizationElement} ${translationElement}
|
|
3690
3767
|
</div>
|
|
3691
3768
|
</div>
|
|
3692
3769
|
`;
|
|
@@ -3799,13 +3876,13 @@ class AmLyrics extends i {
|
|
|
3799
3876
|
${renderContent()}
|
|
3800
3877
|
${!this.isLoading
|
|
3801
3878
|
? b `
|
|
3802
|
-
<footer class="lyrics-footer">
|
|
3879
|
+
<footer class="lyrics-footer lyrics-line">
|
|
3803
3880
|
<div class="footer-content">
|
|
3804
3881
|
<span
|
|
3805
3882
|
class="source-info"
|
|
3806
3883
|
style="display: flex; align-items: center; gap: 8px;"
|
|
3807
3884
|
>
|
|
3808
|
-
|
|
3885
|
+
<b style="font-weight: 750;">Source</b> ${sourceLabel}
|
|
3809
3886
|
${(this.availableSources &&
|
|
3810
3887
|
this.availableSources.length > 1) ||
|
|
3811
3888
|
!this.hasFetchedAllProviders
|
|
@@ -3848,15 +3925,25 @@ class AmLyrics extends i {
|
|
|
3848
3925
|
`
|
|
3849
3926
|
: ''}
|
|
3850
3927
|
</span>
|
|
3851
|
-
|
|
3852
|
-
|
|
3928
|
+
${this.songwriters
|
|
3929
|
+
? b `<span
|
|
3930
|
+
class="songwriters-info"
|
|
3931
|
+
style="margin-top: 4px; font-weight: normal; font-size: 0.9em;"
|
|
3932
|
+
>
|
|
3933
|
+
<b style="font-weight: 750;">Songwriters</b> ${this
|
|
3934
|
+
.songwriters}
|
|
3935
|
+
</span>`
|
|
3936
|
+
: ''}
|
|
3937
|
+
<span class="version-info" style="margin-top: 8px;">
|
|
3938
|
+
<b style="font-weight: 750;">am-lyrics</b> v${VERSION} •
|
|
3853
3939
|
|
|
3854
3940
|
<a
|
|
3855
3941
|
href="https://github.com/uimaxbai/apple-music-web-components"
|
|
3856
3942
|
target="_blank"
|
|
3857
3943
|
rel="noopener noreferrer"
|
|
3858
|
-
|
|
3859
|
-
|
|
3944
|
+
style="display: inline-flex; align-items: center; gap: 4px;"
|
|
3945
|
+
>Star me on GitHub
|
|
3946
|
+
</a>
|
|
3860
3947
|
</span>
|
|
3861
3948
|
</div>
|
|
3862
3949
|
</footer>
|
|
@@ -3893,6 +3980,7 @@ AmLyrics.styles = i$3 `
|
|
|
3893
3980
|
--lyplus-font-size-base: 32px;
|
|
3894
3981
|
--lyplus-font-size-base-grow: 24.5;
|
|
3895
3982
|
--lyplus-font-size-subtext: 0.6em;
|
|
3983
|
+
--char-rise-y: calc(-0.035 * var(--lyplus-font-size-base));
|
|
3896
3984
|
|
|
3897
3985
|
--lyplus-blur-amount: 0.07em;
|
|
3898
3986
|
--lyplus-blur-amount-near: 0.035em;
|
|
@@ -3926,7 +4014,6 @@ AmLyrics.styles = i$3 `
|
|
|
3926
4014
|
-webkit-overflow-scrolling: touch;
|
|
3927
4015
|
box-sizing: border-box;
|
|
3928
4016
|
scrollbar-width: none;
|
|
3929
|
-
transform: translateZ(0);
|
|
3930
4017
|
}
|
|
3931
4018
|
|
|
3932
4019
|
.lyrics-container::-webkit-scrollbar {
|
|
@@ -3937,11 +4024,13 @@ AmLyrics.styles = i$3 `
|
|
|
3937
4024
|
.lyrics-container.touch-scrolling .lyrics-line,
|
|
3938
4025
|
.lyrics-container.touch-scrolling .lyrics-plus-metadata {
|
|
3939
4026
|
transition: none !important;
|
|
4027
|
+
filter: none !important;
|
|
3940
4028
|
}
|
|
3941
4029
|
|
|
3942
4030
|
/* Apply smooth gliding transition for mouse-wheel scrolling */
|
|
3943
4031
|
.lyrics-container.wheel-scrolling .lyrics-line {
|
|
3944
4032
|
transition: transform 0.3s ease-out !important;
|
|
4033
|
+
filter: none !important;
|
|
3945
4034
|
}
|
|
3946
4035
|
|
|
3947
4036
|
.lyrics-line.scroll-animate {
|
|
@@ -3968,18 +4057,13 @@ AmLyrics.styles = i$3 `
|
|
|
3968
4057
|
font-size: var(--lyplus-font-size-base);
|
|
3969
4058
|
cursor: pointer;
|
|
3970
4059
|
transform-origin: left;
|
|
3971
|
-
transform: translateZ(1px);
|
|
3972
4060
|
transition:
|
|
3973
4061
|
opacity 0.3s ease,
|
|
3974
4062
|
transform 0.4s cubic-bezier(0.41, 0, 0.12, 0.99)
|
|
3975
4063
|
var(--lyrics-line-delay, 0ms),
|
|
3976
4064
|
filter 0.3s ease;
|
|
3977
|
-
will-change: transform, filter, opacity;
|
|
3978
4065
|
content-visibility: auto;
|
|
3979
4066
|
text-rendering: optimizeLegibility;
|
|
3980
|
-
overflow-wrap: break-word;
|
|
3981
|
-
mix-blend-mode: lighten;
|
|
3982
|
-
border-radius: var(--lyplus-border-radius-base);
|
|
3983
4067
|
}
|
|
3984
4068
|
|
|
3985
4069
|
.lyrics-line:not(.scroll-animate) {
|
|
@@ -3999,8 +4083,7 @@ AmLyrics.styles = i$3 `
|
|
|
3999
4083
|
|
|
4000
4084
|
.lyrics-line.active .lyrics-line-container,
|
|
4001
4085
|
.lyrics-line.pre-active .lyrics-line-container {
|
|
4002
|
-
transform: scale3d(1.001, 1.001, 1);
|
|
4003
|
-
will-change: transform;
|
|
4086
|
+
transform: scale3d(1.001, 1.001, 1) translateZ(0);
|
|
4004
4087
|
transition:
|
|
4005
4088
|
transform 0.5s ease,
|
|
4006
4089
|
background-color 0.18s,
|
|
@@ -4045,12 +4128,10 @@ AmLyrics.styles = i$3 `
|
|
|
4045
4128
|
.lyrics-line.active {
|
|
4046
4129
|
opacity: 1;
|
|
4047
4130
|
color: var(--lyplus-text-primary);
|
|
4048
|
-
will-change: transform, opacity;
|
|
4049
4131
|
}
|
|
4050
4132
|
|
|
4051
4133
|
.lyrics-line.pre-active {
|
|
4052
4134
|
opacity: 1;
|
|
4053
|
-
will-change: transform, opacity;
|
|
4054
4135
|
}
|
|
4055
4136
|
|
|
4056
4137
|
.lyrics-line.singer-right {
|
|
@@ -4064,6 +4145,18 @@ AmLyrics.styles = i$3 `
|
|
|
4064
4145
|
|
|
4065
4146
|
.lyrics-line.rtl-text {
|
|
4066
4147
|
direction: rtl;
|
|
4148
|
+
text-align: right !important;
|
|
4149
|
+
transform-origin: right;
|
|
4150
|
+
}
|
|
4151
|
+
|
|
4152
|
+
.lyrics-line.rtl-text .lyrics-line-container,
|
|
4153
|
+
.lyrics-line.rtl-text .main-vocal-container {
|
|
4154
|
+
transform-origin: right;
|
|
4155
|
+
}
|
|
4156
|
+
|
|
4157
|
+
.lyrics-line.rtl-text .lyrics-romanization-container,
|
|
4158
|
+
.lyrics-line.rtl-text .lyrics-translation-container {
|
|
4159
|
+
text-align: right;
|
|
4067
4160
|
}
|
|
4068
4161
|
|
|
4069
4162
|
/* --- Unsynced (Plain Text) Lyrics Overrides --- */
|
|
@@ -4095,7 +4188,8 @@ AmLyrics.styles = i$3 `
|
|
|
4095
4188
|
|
|
4096
4189
|
@media (hover: hover) and (pointer: fine) {
|
|
4097
4190
|
.lyrics-line:hover {
|
|
4098
|
-
|
|
4191
|
+
filter: none !important;
|
|
4192
|
+
opacity: 1 !important;
|
|
4099
4193
|
}
|
|
4100
4194
|
.lyrics-container.is-unsynced .lyrics-line:hover {
|
|
4101
4195
|
background: transparent !important;
|
|
@@ -4125,6 +4219,7 @@ AmLyrics.styles = i$3 `
|
|
|
4125
4219
|
|
|
4126
4220
|
/* Unblur all lines when user is scrolling */
|
|
4127
4221
|
.lyrics-container.user-scrolling .lyrics-line {
|
|
4222
|
+
transition: none !important;
|
|
4128
4223
|
filter: none !important;
|
|
4129
4224
|
opacity: 0.8 !important;
|
|
4130
4225
|
}
|
|
@@ -4141,6 +4236,7 @@ AmLyrics.styles = i$3 `
|
|
|
4141
4236
|
.lyrics-word:not(.allow-break) {
|
|
4142
4237
|
display: inline-block;
|
|
4143
4238
|
vertical-align: baseline;
|
|
4239
|
+
white-space: nowrap;
|
|
4144
4240
|
}
|
|
4145
4241
|
|
|
4146
4242
|
.lyrics-word.allow-break {
|
|
@@ -4151,7 +4247,7 @@ AmLyrics.styles = i$3 `
|
|
|
4151
4247
|
display: inline;
|
|
4152
4248
|
}
|
|
4153
4249
|
|
|
4154
|
-
.lyrics-syllable-wrap
|
|
4250
|
+
.lyrics-syllable-wrap.has-transliteration {
|
|
4155
4251
|
display: inline-flex;
|
|
4156
4252
|
flex-direction: column;
|
|
4157
4253
|
align-items: start;
|
|
@@ -4179,7 +4275,7 @@ AmLyrics.styles = i$3 `
|
|
|
4179
4275
|
transition: transform 1s ease !important;
|
|
4180
4276
|
}
|
|
4181
4277
|
|
|
4182
|
-
.lyrics-syllable.finished
|
|
4278
|
+
.lyrics-syllable.finished.has-chars {
|
|
4183
4279
|
background-color: transparent;
|
|
4184
4280
|
}
|
|
4185
4281
|
|
|
@@ -4188,19 +4284,16 @@ AmLyrics.styles = i$3 `
|
|
|
4188
4284
|
}
|
|
4189
4285
|
|
|
4190
4286
|
.lyrics-line.active:not(.lyrics-gap) .lyrics-syllable {
|
|
4191
|
-
transform: translateY(0.001%) translateZ(1px);
|
|
4192
4287
|
transition:
|
|
4193
4288
|
transform 1s ease,
|
|
4194
4289
|
background-color 0.5s,
|
|
4195
4290
|
color 0.5s;
|
|
4196
|
-
will-change: transform, background;
|
|
4197
4291
|
}
|
|
4198
4292
|
|
|
4199
4293
|
/* --- Wipe Highlight Effect --- */
|
|
4294
|
+
.lyrics-line.active:not(.lyrics-gap) .lyrics-syllable.highlight.no-chars,
|
|
4200
4295
|
.lyrics-line.active:not(.lyrics-gap)
|
|
4201
|
-
.lyrics-syllable.highlight
|
|
4202
|
-
.lyrics-line.active:not(.lyrics-gap)
|
|
4203
|
-
.lyrics-syllable.pre-highlight:not(:has(.char)) {
|
|
4296
|
+
.lyrics-syllable.pre-highlight.no-chars {
|
|
4204
4297
|
background-repeat: no-repeat;
|
|
4205
4298
|
background-image:
|
|
4206
4299
|
linear-gradient(
|
|
@@ -4242,11 +4335,19 @@ AmLyrics.styles = i$3 `
|
|
|
4242
4335
|
right;
|
|
4243
4336
|
}
|
|
4244
4337
|
|
|
4338
|
+
/* Non-growable words float up with a gentle curve */
|
|
4245
4339
|
.lyrics-line.active:not(.lyrics-gap)
|
|
4246
4340
|
.lyrics-word:not(.growable)
|
|
4247
|
-
.lyrics-syllable.highlight
|
|
4341
|
+
.lyrics-syllable.highlight {
|
|
4342
|
+
transform: translateY(-3.5%);
|
|
4343
|
+
transition:
|
|
4344
|
+
transform var(--rise-duration, 1.5s) cubic-bezier(0.22, 1, 0.36, 1),
|
|
4345
|
+
background-color 0.5s,
|
|
4346
|
+
color 0.5s;
|
|
4347
|
+
}
|
|
4348
|
+
|
|
4248
4349
|
.lyrics-word.growable .lyrics-syllable.cleanup .char {
|
|
4249
|
-
transform: translateY(-3.5%)
|
|
4350
|
+
transform: translateY(-3.5%);
|
|
4250
4351
|
}
|
|
4251
4352
|
|
|
4252
4353
|
.lyrics-line.active:not(.lyrics-gap) .lyrics-syllable.highlight.finished {
|
|
@@ -4273,7 +4374,7 @@ AmLyrics.styles = i$3 `
|
|
|
4273
4374
|
}
|
|
4274
4375
|
|
|
4275
4376
|
/* Syllable with chars: make syllable transparent, chars handle color */
|
|
4276
|
-
.lyrics-line .lyrics-syllable
|
|
4377
|
+
.lyrics-line .lyrics-syllable.has-chars:not(.finished) {
|
|
4277
4378
|
background-color: transparent;
|
|
4278
4379
|
color: transparent;
|
|
4279
4380
|
}
|
|
@@ -4286,6 +4387,7 @@ AmLyrics.styles = i$3 `
|
|
|
4286
4387
|
font-feature-settings: 'liga' 0;
|
|
4287
4388
|
background-clip: text;
|
|
4288
4389
|
-webkit-background-clip: text;
|
|
4390
|
+
backface-visibility: hidden;
|
|
4289
4391
|
transition:
|
|
4290
4392
|
color 0.7s,
|
|
4291
4393
|
background-color 0.7s,
|
|
@@ -4321,11 +4423,9 @@ AmLyrics.styles = i$3 `
|
|
|
4321
4423
|
-0.5em 0%,
|
|
4322
4424
|
-0.25em 0%;
|
|
4323
4425
|
transform-origin: 50% 80%;
|
|
4324
|
-
transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
|
|
4325
4426
|
transition:
|
|
4326
4427
|
transform 0.7s ease,
|
|
4327
4428
|
color 0.18s;
|
|
4328
|
-
will-change: background, transform;
|
|
4329
4429
|
}
|
|
4330
4430
|
|
|
4331
4431
|
.lyrics-line.active .lyrics-syllable span.char.highlight {
|
|
@@ -4377,6 +4477,8 @@ AmLyrics.styles = i$3 `
|
|
|
4377
4477
|
box-sizing: content-box;
|
|
4378
4478
|
background-clip: unset;
|
|
4379
4479
|
transform-origin: top;
|
|
4480
|
+
content-visibility: visible !important;
|
|
4481
|
+
contain: none !important;
|
|
4380
4482
|
transition:
|
|
4381
4483
|
opacity 160ms ease-out,
|
|
4382
4484
|
transform var(--scroll-duration, 280ms) var(--lyrics-line-delay, 0ms);
|
|
@@ -4387,41 +4489,35 @@ AmLyrics.styles = i$3 `
|
|
|
4387
4489
|
transition:
|
|
4388
4490
|
opacity 160ms ease-out,
|
|
4389
4491
|
transform var(--scroll-duration, 280ms);
|
|
4390
|
-
will-change: opacity;
|
|
4391
4492
|
}
|
|
4392
4493
|
|
|
4393
4494
|
/* Exiting state: quickly collapse width and height so dots don't distort page, or remove max-height transition */
|
|
4394
4495
|
.lyrics-gap.gap-exiting {
|
|
4395
4496
|
opacity: 1;
|
|
4396
|
-
transition: transform var(--scroll-duration, 280ms);
|
|
4397
4497
|
}
|
|
4398
4498
|
|
|
4399
4499
|
.lyrics-gap .main-vocal-container {
|
|
4400
|
-
transform: translateY(-25%) scale(1)
|
|
4500
|
+
transform: translateY(-25%) scale(1);
|
|
4401
4501
|
transition: transform 400ms cubic-bezier(0.22, 1, 0.36, 1);
|
|
4402
4502
|
}
|
|
4403
4503
|
|
|
4404
|
-
/* Jump animation plays during exit */
|
|
4405
|
-
.lyrics-gap.gap-exiting .main-vocal-container {
|
|
4406
|
-
animation: gap-ended var(--gap-exit-duration, 360ms)
|
|
4407
|
-
cubic-bezier(0.33, 1, 0.68, 1) forwards;
|
|
4408
|
-
}
|
|
4409
|
-
|
|
4410
4504
|
.lyrics-gap:not(.active):not(.gap-exiting) .main-vocal-container {
|
|
4411
|
-
transform: translateY(-25%) scale(0)
|
|
4412
|
-
}
|
|
4413
|
-
|
|
4414
|
-
.lyrics-gap:not(.active):not(.gap-exiting)
|
|
4415
|
-
.main-vocal-container
|
|
4416
|
-
.lyrics-word {
|
|
4417
|
-
animation-play-state: paused;
|
|
4505
|
+
transform: translateY(-25%) scale(0);
|
|
4418
4506
|
}
|
|
4419
4507
|
|
|
4420
|
-
|
|
4508
|
+
/* Pulse — must come BEFORE .gap-exiting so exiting wins via specificity+order */
|
|
4509
|
+
.lyrics-gap.active .main-vocal-container {
|
|
4421
4510
|
animation: gap-loop var(--gap-pulse-duration, 4000ms) ease-in-out infinite
|
|
4422
4511
|
alternate;
|
|
4423
4512
|
animation-delay: var(--gap-loop-delay, 0ms);
|
|
4424
|
-
|
|
4513
|
+
}
|
|
4514
|
+
|
|
4515
|
+
/* Jump animation plays during exit — disable transition so animation wins.
|
|
4516
|
+
Placed AFTER .active so it wins when both classes are present briefly. */
|
|
4517
|
+
.lyrics-gap.gap-exiting .main-vocal-container {
|
|
4518
|
+
animation: gap-ended var(--gap-exit-duration, 360ms)
|
|
4519
|
+
cubic-bezier(0.33, 1, 0.68, 1) forwards;
|
|
4520
|
+
transition: none !important;
|
|
4425
4521
|
}
|
|
4426
4522
|
|
|
4427
4523
|
.lyrics-gap .lyrics-syllable {
|
|
@@ -4472,20 +4568,17 @@ AmLyrics.styles = i$3 `
|
|
|
4472
4568
|
background-clip: unset;
|
|
4473
4569
|
}
|
|
4474
4570
|
|
|
4475
|
-
.lyrics-gap.active .lyrics-syllable.highlight,
|
|
4476
4571
|
.lyrics-gap.active .lyrics-syllable.finished,
|
|
4477
|
-
.lyrics-gap.gap-exiting .lyrics-syllable,
|
|
4478
|
-
.lyrics-gap:not(.active).post-active-line
|
|
4479
|
-
|
|
4572
|
+
.lyrics-gap.gap-exiting .lyrics-syllable.finished,
|
|
4573
|
+
.lyrics-gap:not(.active):not(.gap-exiting).post-active-line
|
|
4574
|
+
.lyrics-syllable,
|
|
4575
|
+
.lyrics-gap:not(.active):not(.gap-exiting).lyrics-activest
|
|
4576
|
+
.lyrics-syllable {
|
|
4480
4577
|
background-color: var(--lyplus-text-primary);
|
|
4481
4578
|
animation: none !important;
|
|
4482
4579
|
opacity: 1;
|
|
4483
4580
|
}
|
|
4484
4581
|
|
|
4485
|
-
.lyrics-gap.active .lyrics-syllable.finished {
|
|
4486
|
-
animation: none !important;
|
|
4487
|
-
}
|
|
4488
|
-
|
|
4489
4582
|
/* ==========================================================================
|
|
4490
4583
|
METADATA & FOOTER STYLES
|
|
4491
4584
|
========================================================================== */
|
|
@@ -4514,12 +4607,49 @@ AmLyrics.styles = i$3 `
|
|
|
4514
4607
|
align-items: center;
|
|
4515
4608
|
flex-wrap: wrap;
|
|
4516
4609
|
text-align: left;
|
|
4517
|
-
font-size:
|
|
4518
|
-
color: rgba(255, 255, 255, 0.
|
|
4519
|
-
padding:
|
|
4520
|
-
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
|
4610
|
+
font-size: 1.2em;
|
|
4611
|
+
color: rgba(255, 255, 255, 0.6);
|
|
4612
|
+
padding: 20px 0 50vh 0;
|
|
4521
4613
|
margin-top: 10px;
|
|
4522
|
-
font-weight:
|
|
4614
|
+
font-weight: 400;
|
|
4615
|
+
opacity: 0.8;
|
|
4616
|
+
transition:
|
|
4617
|
+
opacity 0.3s ease,
|
|
4618
|
+
transform 0.5s cubic-bezier(0.41, 0, 0.12, 0.99),
|
|
4619
|
+
filter 0.3s ease;
|
|
4620
|
+
transform-origin: left;
|
|
4621
|
+
}
|
|
4622
|
+
|
|
4623
|
+
.lyrics-footer.lyrics-line {
|
|
4624
|
+
font-size: 1.2em;
|
|
4625
|
+
padding: 20px var(--lyplus-padding-line) 50vh var(--lyplus-padding-line);
|
|
4626
|
+
cursor: default;
|
|
4627
|
+
}
|
|
4628
|
+
|
|
4629
|
+
.lyrics-footer.active {
|
|
4630
|
+
opacity: 1;
|
|
4631
|
+
color: rgba(255, 255, 255, 0.5); /* Grey instead of primary */
|
|
4632
|
+
}
|
|
4633
|
+
|
|
4634
|
+
.lyrics-footer.scroll-animate {
|
|
4635
|
+
transition: none !important;
|
|
4636
|
+
animation-name: lyrics-scroll;
|
|
4637
|
+
animation-duration: var(--scroll-duration, 280ms);
|
|
4638
|
+
animation-timing-function: cubic-bezier(0.41, 0, 0.12, 0.99);
|
|
4639
|
+
animation-fill-mode: both;
|
|
4640
|
+
animation-delay: var(--lyrics-line-delay, 0ms);
|
|
4641
|
+
}
|
|
4642
|
+
|
|
4643
|
+
.lyrics-container.blur-inactive-enabled:not(.not-focused)
|
|
4644
|
+
.lyrics-footer:not(.active) {
|
|
4645
|
+
filter: blur(var(--lyplus-blur-amount));
|
|
4646
|
+
opacity: 0.5;
|
|
4647
|
+
}
|
|
4648
|
+
|
|
4649
|
+
.lyrics-container.user-scrolling .lyrics-footer {
|
|
4650
|
+
transition: none !important;
|
|
4651
|
+
filter: none !important;
|
|
4652
|
+
opacity: 0.8 !important;
|
|
4523
4653
|
}
|
|
4524
4654
|
|
|
4525
4655
|
.lyrics-footer p {
|
|
@@ -4527,12 +4657,14 @@ AmLyrics.styles = i$3 `
|
|
|
4527
4657
|
}
|
|
4528
4658
|
|
|
4529
4659
|
.lyrics-footer a {
|
|
4530
|
-
color:
|
|
4531
|
-
text-
|
|
4660
|
+
color: var(--lyplus-text-primary); /* Stand out using primary color */
|
|
4661
|
+
text-underline-offset: 2px;
|
|
4662
|
+
opacity: 0.8;
|
|
4663
|
+
transition: opacity 0.2s;
|
|
4532
4664
|
}
|
|
4533
4665
|
|
|
4534
4666
|
.lyrics-footer a:hover {
|
|
4535
|
-
|
|
4667
|
+
opacity: 1;
|
|
4536
4668
|
}
|
|
4537
4669
|
|
|
4538
4670
|
.footer-content {
|
|
@@ -4656,6 +4788,7 @@ AmLyrics.styles = i$3 `
|
|
|
4656
4788
|
|
|
4657
4789
|
.lyrics-romanization-container.rtl-text {
|
|
4658
4790
|
direction: rtl !important;
|
|
4791
|
+
text-align: right;
|
|
4659
4792
|
}
|
|
4660
4793
|
|
|
4661
4794
|
.lyrics-romanization-container .lyrics-syllable {
|
|
@@ -4869,23 +5002,22 @@ AmLyrics.styles = i$3 `
|
|
|
4869
5002
|
/* Gap dot animations */
|
|
4870
5003
|
@keyframes gap-loop {
|
|
4871
5004
|
from {
|
|
4872
|
-
transform: scale(1.12);
|
|
5005
|
+
transform: translateY(-25%) scale(1.12);
|
|
4873
5006
|
}
|
|
4874
5007
|
to {
|
|
4875
|
-
transform: scale(var(--gap-exit-scale, 0.85));
|
|
5008
|
+
transform: translateY(-25%) scale(var(--gap-exit-scale, 0.85));
|
|
4876
5009
|
}
|
|
4877
5010
|
}
|
|
4878
5011
|
|
|
4879
5012
|
@keyframes gap-ended {
|
|
4880
5013
|
0% {
|
|
4881
|
-
transform: translateY(-25%) scale(var(--gap-exit-scale, 0.85))
|
|
4882
|
-
translateZ(0);
|
|
5014
|
+
transform: translateY(-25%) scale(var(--gap-exit-scale, 0.85));
|
|
4883
5015
|
}
|
|
4884
5016
|
35% {
|
|
4885
|
-
transform: translateY(-
|
|
5017
|
+
transform: translateY(-25%) scale(1.2);
|
|
4886
5018
|
}
|
|
4887
5019
|
100% {
|
|
4888
|
-
transform: translateY(-25%) scale(0)
|
|
5020
|
+
transform: translateY(-25%) scale(0);
|
|
4889
5021
|
}
|
|
4890
5022
|
}
|
|
4891
5023
|
|
|
@@ -4902,17 +5034,18 @@ AmLyrics.styles = i$3 `
|
|
|
4902
5034
|
reflow in between) to reliably restart the animation each time */
|
|
4903
5035
|
@keyframes lyrics-scroll {
|
|
4904
5036
|
from {
|
|
4905
|
-
transform:
|
|
5037
|
+
transform: translate3d(0, var(--scroll-delta), 0);
|
|
4906
5038
|
}
|
|
4907
5039
|
to {
|
|
4908
|
-
transform:
|
|
5040
|
+
transform: translate3d(0, 0, 0);
|
|
4909
5041
|
}
|
|
4910
5042
|
}
|
|
4911
5043
|
|
|
4912
|
-
/* Character grow animation
|
|
5044
|
+
/* Character grow animation — translate3d+scale3d for smooth transform,
|
|
5045
|
+
drop-shadow for glow (text-shadow doesn't work with background-clip:text) */
|
|
4913
5046
|
@keyframes grow-dynamic {
|
|
4914
5047
|
0% {
|
|
4915
|
-
transform:
|
|
5048
|
+
transform: translate3d(0, 0, 0) scale3d(1, 1, 1);
|
|
4916
5049
|
filter: drop-shadow(
|
|
4917
5050
|
0 0 0
|
|
4918
5051
|
color-mix(in srgb, var(--lyplus-lyrics-palette), transparent 100%)
|
|
@@ -4920,27 +5053,12 @@ AmLyrics.styles = i$3 `
|
|
|
4920
5053
|
}
|
|
4921
5054
|
25%,
|
|
4922
5055
|
30% {
|
|
4923
|
-
transform:
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
calc(var(--max-scale) * calc(var(--lyplus-font-size-base-grow) / 25)),
|
|
4930
|
-
0,
|
|
4931
|
-
0,
|
|
4932
|
-
0,
|
|
4933
|
-
0,
|
|
4934
|
-
1,
|
|
4935
|
-
0,
|
|
4936
|
-
calc(
|
|
4937
|
-
var(--char-offset-x, 0) *
|
|
4938
|
-
calc(var(--lyplus-font-size-base-grow) / 25)
|
|
4939
|
-
),
|
|
4940
|
-
var(--translate-y-peak, -2),
|
|
4941
|
-
0,
|
|
4942
|
-
1
|
|
4943
|
-
);
|
|
5056
|
+
transform: translate3d(
|
|
5057
|
+
var(--char-offset-x, 0px),
|
|
5058
|
+
var(--translate-y-peak, -2px),
|
|
5059
|
+
0
|
|
5060
|
+
)
|
|
5061
|
+
scale3d(var(--matrix-scale, 1.1), var(--matrix-scale, 1.1), 1);
|
|
4944
5062
|
filter: drop-shadow(
|
|
4945
5063
|
0 0 0.1em
|
|
4946
5064
|
color-mix(
|
|
@@ -4950,8 +5068,10 @@ AmLyrics.styles = i$3 `
|
|
|
4950
5068
|
)
|
|
4951
5069
|
);
|
|
4952
5070
|
}
|
|
5071
|
+
75%,
|
|
4953
5072
|
100% {
|
|
4954
|
-
transform:
|
|
5073
|
+
transform: translate3d(0, var(--char-rise-y, -1.12px), 0)
|
|
5074
|
+
scale3d(1, 1, 1);
|
|
4955
5075
|
filter: drop-shadow(
|
|
4956
5076
|
0 0 0
|
|
4957
5077
|
color-mix(in srgb, var(--lyplus-lyrics-palette), transparent 100%)
|
|
@@ -5083,15 +5203,15 @@ __decorate([
|
|
|
5083
5203
|
__decorate([
|
|
5084
5204
|
n({ type: String, attribute: 'song-album' })
|
|
5085
5205
|
], AmLyrics.prototype, "songAlbum", void 0);
|
|
5206
|
+
__decorate([
|
|
5207
|
+
n({ type: String, attribute: 'songwriters' })
|
|
5208
|
+
], AmLyrics.prototype, "songwriters", void 0);
|
|
5086
5209
|
__decorate([
|
|
5087
5210
|
n({ type: Number, attribute: 'song-duration' })
|
|
5088
5211
|
], AmLyrics.prototype, "songDurationMs", void 0);
|
|
5089
5212
|
__decorate([
|
|
5090
5213
|
n({ type: String, attribute: 'highlight-color' })
|
|
5091
5214
|
], AmLyrics.prototype, "highlightColor", void 0);
|
|
5092
|
-
__decorate([
|
|
5093
|
-
n({ type: String, attribute: 'hover-background-color' })
|
|
5094
|
-
], AmLyrics.prototype, "hoverBackgroundColor", void 0);
|
|
5095
5215
|
__decorate([
|
|
5096
5216
|
n({ type: String, attribute: 'font-family' })
|
|
5097
5217
|
], AmLyrics.prototype, "fontFamily", void 0);
|