@uimaxbai/am-lyrics 1.5.5 → 1.5.6
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/dist/src/AmLyrics.d.ts.map +1 -1
- package/dist/src/am-lyrics.js +150 -69
- package/dist/src/am-lyrics.js.map +1 -1
- package/dist/src/react.js +150 -69
- package/dist/src/react.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/AmLyrics.ts +189 -67
package/src/AmLyrics.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { css, html, LitElement, svg } from 'lit';
|
|
|
2
2
|
import { property, query, state } from 'lit/decorators.js';
|
|
3
3
|
import { GoogleService } from './GoogleService.js';
|
|
4
4
|
|
|
5
|
-
const VERSION = '1.5.
|
|
5
|
+
const VERSION = '1.5.6';
|
|
6
6
|
const INSTRUMENTAL_THRESHOLD_MS = 7000; // Show dots for gaps >= 7s
|
|
7
7
|
const FETCH_TIMEOUT_MS = 8000; // Timeout for all lyrics fetch requests
|
|
8
8
|
const SEEK_THRESHOLD_MS = 500;
|
|
@@ -19,7 +19,7 @@ const LONG_WORD_WIPE_EXTRA_EM = 0.45;
|
|
|
19
19
|
const LONG_WORD_WIPE_EXTRA_RATIO = 0.35;
|
|
20
20
|
const SHORT_WORD_DRAG_MIN_DURATION_MS = 760;
|
|
21
21
|
const SHORT_WORD_GLOW_MIN_DURATION_MS = 1320;
|
|
22
|
-
const WORD_PRE_WIPE_HANDOFF_LEAD_MS =
|
|
22
|
+
const WORD_PRE_WIPE_HANDOFF_LEAD_MS = 100;
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Fetch with an automatic timeout via AbortSignal.
|
|
@@ -320,6 +320,18 @@ export class AmLyrics extends LitElement {
|
|
|
320
320
|
opacity: 1;
|
|
321
321
|
}
|
|
322
322
|
|
|
323
|
+
/* Predictive scrolling begins before the next timestamp. Start dimming
|
|
324
|
+
the outgoing line at the same moment so it settles with the scroll. */
|
|
325
|
+
.lyrics-line.scroll-exiting {
|
|
326
|
+
opacity: 0.8;
|
|
327
|
+
color: var(--lyplus-text-secondary);
|
|
328
|
+
transition:
|
|
329
|
+
opacity var(--scroll-duration, 400ms) cubic-bezier(0.41, 0, 0.12, 0.99),
|
|
330
|
+
transform var(--scroll-duration, 400ms)
|
|
331
|
+
cubic-bezier(0.41, 0, 0.12, 0.99) var(--lyrics-line-delay, 0ms),
|
|
332
|
+
filter var(--scroll-duration, 400ms) ease;
|
|
333
|
+
}
|
|
334
|
+
|
|
323
335
|
.lyrics-line.persist-highlight {
|
|
324
336
|
filter: none !important;
|
|
325
337
|
opacity: 1;
|
|
@@ -750,15 +762,24 @@ export class AmLyrics extends LitElement {
|
|
|
750
762
|
background-clip: text;
|
|
751
763
|
-webkit-background-clip: text;
|
|
752
764
|
background-repeat: no-repeat;
|
|
753
|
-
background-image:
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
765
|
+
background-image:
|
|
766
|
+
linear-gradient(
|
|
767
|
+
90deg,
|
|
768
|
+
#ffffff00 0%,
|
|
769
|
+
var(--lyplus-text-primary, #fff) 50%,
|
|
770
|
+
#0000 100%
|
|
771
|
+
),
|
|
772
|
+
linear-gradient(
|
|
773
|
+
90deg,
|
|
774
|
+
var(--lyplus-text-primary, #fff) 100%,
|
|
775
|
+
#0000 100%
|
|
776
|
+
);
|
|
777
|
+
background-size:
|
|
778
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
779
|
+
0% 100%;
|
|
780
|
+
background-position:
|
|
781
|
+
calc(-1 * var(--wipe-gradient-width, 0.75em)) 0%,
|
|
782
|
+
left;
|
|
762
783
|
transition:
|
|
763
784
|
transform 0.7s ease,
|
|
764
785
|
color 0.18s;
|
|
@@ -777,20 +798,11 @@ export class AmLyrics extends LitElement {
|
|
|
777
798
|
}
|
|
778
799
|
|
|
779
800
|
.lyrics-line.active .lyrics-syllable span.char.pre-wipe-lead {
|
|
780
|
-
animation-name: pre-wipe
|
|
801
|
+
animation-name: char-pre-wipe;
|
|
781
802
|
animation-duration: var(--pre-wipe-duration);
|
|
782
803
|
animation-delay: var(--pre-wipe-delay);
|
|
783
804
|
animation-timing-function: linear;
|
|
784
805
|
animation-fill-mode: forwards;
|
|
785
|
-
background-image: linear-gradient(
|
|
786
|
-
90deg,
|
|
787
|
-
var(--lyplus-text-primary, #fff) 0%,
|
|
788
|
-
var(--lyplus-text-primary, #fff)
|
|
789
|
-
calc(100% - var(--wipe-gradient-width, 0.75em)),
|
|
790
|
-
#0000 100%
|
|
791
|
-
);
|
|
792
|
-
background-size: 0% 100%;
|
|
793
|
-
background-position: var(--char-wipe-position, left) 0%;
|
|
794
806
|
}
|
|
795
807
|
|
|
796
808
|
/* ==========================================================================
|
|
@@ -1327,30 +1339,63 @@ export class AmLyrics extends LitElement {
|
|
|
1327
1339
|
}
|
|
1328
1340
|
}
|
|
1329
1341
|
|
|
1330
|
-
|
|
1342
|
+
/* Character-rendered words use a separate moving gradient in front of
|
|
1343
|
+
their solid fill. This makes the individual glyph wipes read as one
|
|
1344
|
+
continuous word-level wipe. */
|
|
1345
|
+
@keyframes char-pre-wipe {
|
|
1331
1346
|
from {
|
|
1332
|
-
background-size:
|
|
1333
|
-
|
|
1347
|
+
background-size:
|
|
1348
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
1349
|
+
0% 100%;
|
|
1350
|
+
background-position:
|
|
1351
|
+
calc(-1 * var(--wipe-gradient-width, 0.75em)) 0%,
|
|
1352
|
+
left;
|
|
1334
1353
|
}
|
|
1335
1354
|
to {
|
|
1336
|
-
background-size:
|
|
1337
|
-
100
|
|
1338
|
-
|
|
1355
|
+
background-size:
|
|
1356
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
1357
|
+
0% 100%;
|
|
1358
|
+
background-position:
|
|
1359
|
+
calc(-1 * var(--wipe-gradient-half, 0.375em)) 0%,
|
|
1360
|
+
left;
|
|
1339
1361
|
}
|
|
1340
1362
|
}
|
|
1341
1363
|
|
|
1342
|
-
@keyframes
|
|
1364
|
+
@keyframes char-start-wipe {
|
|
1343
1365
|
from {
|
|
1344
|
-
background-size:
|
|
1345
|
-
100
|
|
1346
|
-
|
|
1366
|
+
background-size:
|
|
1367
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
1368
|
+
0% 100%;
|
|
1369
|
+
background-position:
|
|
1370
|
+
calc(-1 * var(--wipe-gradient-width, 0.75em)) 0%,
|
|
1371
|
+
left;
|
|
1347
1372
|
}
|
|
1348
1373
|
to {
|
|
1349
|
-
background-size:
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1374
|
+
background-size:
|
|
1375
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
1376
|
+
100% 100%;
|
|
1377
|
+
background-position:
|
|
1378
|
+
calc(100% + var(--wipe-gradient-half, 0.375em)) 0%,
|
|
1379
|
+
left;
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
@keyframes char-wipe {
|
|
1384
|
+
from {
|
|
1385
|
+
background-size:
|
|
1386
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
1387
|
+
0% 100%;
|
|
1388
|
+
background-position:
|
|
1389
|
+
calc(-1 * var(--wipe-gradient-half, 0.375em)) 0%,
|
|
1390
|
+
left;
|
|
1391
|
+
}
|
|
1392
|
+
to {
|
|
1393
|
+
background-size:
|
|
1394
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
1395
|
+
100% 100%;
|
|
1396
|
+
background-position:
|
|
1397
|
+
calc(100% + var(--wipe-gradient-half, 0.375em)) 0%,
|
|
1398
|
+
left;
|
|
1354
1399
|
}
|
|
1355
1400
|
}
|
|
1356
1401
|
|
|
@@ -1703,10 +1748,15 @@ export class AmLyrics extends LitElement {
|
|
|
1703
1748
|
// Stop all running animations and clear highlights immediately
|
|
1704
1749
|
if (this.lyricsContainer) {
|
|
1705
1750
|
const activeLines = this.lyricsContainer.querySelectorAll(
|
|
1706
|
-
'.lyrics-line.active, .lyrics-line.pre-active, .lyrics-line.bg-expanded',
|
|
1751
|
+
'.lyrics-line.active, .lyrics-line.pre-active, .lyrics-line.bg-expanded, .lyrics-line.scroll-exiting',
|
|
1707
1752
|
);
|
|
1708
1753
|
activeLines.forEach(line => {
|
|
1709
|
-
line.classList.remove(
|
|
1754
|
+
line.classList.remove(
|
|
1755
|
+
'active',
|
|
1756
|
+
'pre-active',
|
|
1757
|
+
'bg-expanded',
|
|
1758
|
+
'scroll-exiting',
|
|
1759
|
+
);
|
|
1710
1760
|
AmLyrics.resetSyllables(line as HTMLElement);
|
|
1711
1761
|
});
|
|
1712
1762
|
|
|
@@ -3647,7 +3697,11 @@ export class AmLyrics extends LitElement {
|
|
|
3647
3697
|
AmLyrics.finishSyllablesUpToTime(lineElement, newTime);
|
|
3648
3698
|
}
|
|
3649
3699
|
|
|
3650
|
-
lineElement.classList.remove(
|
|
3700
|
+
lineElement.classList.remove(
|
|
3701
|
+
'active',
|
|
3702
|
+
'bg-expanded',
|
|
3703
|
+
'scroll-exiting',
|
|
3704
|
+
);
|
|
3651
3705
|
|
|
3652
3706
|
if (lineElement.classList.contains('pre-active')) {
|
|
3653
3707
|
lineElement.classList.remove('pre-active');
|
|
@@ -3665,7 +3719,7 @@ export class AmLyrics extends LitElement {
|
|
|
3665
3719
|
const lineElement = this._getLineElement(lineIndex);
|
|
3666
3720
|
if (lineElement) {
|
|
3667
3721
|
lineElement.classList.add('active');
|
|
3668
|
-
lineElement.classList.remove('pre-active');
|
|
3722
|
+
lineElement.classList.remove('pre-active', 'scroll-exiting');
|
|
3669
3723
|
const preIdx = this.preActiveLineElements.indexOf(lineElement);
|
|
3670
3724
|
if (preIdx !== -1) this.preActiveLineElements.splice(preIdx, 1);
|
|
3671
3725
|
}
|
|
@@ -3914,7 +3968,13 @@ export class AmLyrics extends LitElement {
|
|
|
3914
3968
|
}
|
|
3915
3969
|
|
|
3916
3970
|
updated(changedProperties: Map<string | number | symbol, unknown>) {
|
|
3917
|
-
|
|
3971
|
+
const lyricsDomBecameRenderable =
|
|
3972
|
+
changedProperties.has('lyrics') ||
|
|
3973
|
+
(changedProperties.has('isLoading') &&
|
|
3974
|
+
!this.isLoading &&
|
|
3975
|
+
Boolean(this.lyrics));
|
|
3976
|
+
|
|
3977
|
+
if (lyricsDomBecameRenderable) {
|
|
3918
3978
|
this._invalidateCaches();
|
|
3919
3979
|
this._ensureLineDataCache();
|
|
3920
3980
|
this._updateCachedIsUnsynced();
|
|
@@ -4112,7 +4172,12 @@ export class AmLyrics extends LitElement {
|
|
|
4112
4172
|
}
|
|
4113
4173
|
|
|
4114
4174
|
const scrollDuration = scrollLookAheadMs;
|
|
4115
|
-
targetElement.
|
|
4175
|
+
if (targetElement !== this.currentPrimaryActiveLine || forceScroll) {
|
|
4176
|
+
targetElement.style.setProperty(
|
|
4177
|
+
'--scroll-duration',
|
|
4178
|
+
`${scrollDuration}ms`,
|
|
4179
|
+
);
|
|
4180
|
+
}
|
|
4116
4181
|
this.setBackgroundExpandedLine(targetElement);
|
|
4117
4182
|
|
|
4118
4183
|
// Unblur the upcoming target line early while the separate bg-expanded
|
|
@@ -4383,6 +4448,7 @@ export class AmLyrics extends LitElement {
|
|
|
4383
4448
|
|
|
4384
4449
|
const computedStyle = getComputedStyle(referenceSyllable);
|
|
4385
4450
|
const { font } = computedStyle; // Full font string
|
|
4451
|
+
const fontSize = Number.parseFloat(computedStyle.fontSize) || 16;
|
|
4386
4452
|
|
|
4387
4453
|
const charTimedWords = Array.from(
|
|
4388
4454
|
this.shadowRoot.querySelectorAll(
|
|
@@ -4466,6 +4532,15 @@ export class AmLyrics extends LitElement {
|
|
|
4466
4532
|
Number.isFinite(virtualWordStart) &&
|
|
4467
4533
|
Number.isFinite(virtualWordEnd) &&
|
|
4468
4534
|
virtualWordDuration > 0;
|
|
4535
|
+
const wordVelocityPxPerMs = hasTimedSyllables
|
|
4536
|
+
? totalWordWidth / virtualWordDuration
|
|
4537
|
+
: 0;
|
|
4538
|
+
const gradientLeadWidthPx =
|
|
4539
|
+
(BASE_WIPE_GRADIENT_EM * Math.max(1, fontSize)) / 2;
|
|
4540
|
+
const measuredPreWipeDuration =
|
|
4541
|
+
wordVelocityPxPerMs > 0
|
|
4542
|
+
? gradientLeadWidthPx / wordVelocityPxPerMs
|
|
4543
|
+
: 100;
|
|
4469
4544
|
|
|
4470
4545
|
let cumulativeCharWidth = 0;
|
|
4471
4546
|
syllableEntries.forEach(entry => {
|
|
@@ -4504,6 +4579,7 @@ export class AmLyrics extends LitElement {
|
|
|
4504
4579
|
|
|
4505
4580
|
target.dataset.wipeStart = startPercent.toFixed(4);
|
|
4506
4581
|
target.dataset.wipeDuration = durationPercent.toFixed(4);
|
|
4582
|
+
target.dataset.preWipeDuration = measuredPreWipeDuration.toFixed(2);
|
|
4507
4583
|
target.style.setProperty('--word-wipe-width', `${totalWordWidth}px`);
|
|
4508
4584
|
target.style.setProperty(
|
|
4509
4585
|
'--char-wipe-position',
|
|
@@ -4727,7 +4803,15 @@ export class AmLyrics extends LitElement {
|
|
|
4727
4803
|
// effectiveEndTimes). Lines stay active until their extended end,
|
|
4728
4804
|
// so we no longer need to remove .active here.
|
|
4729
4805
|
this.lastPrimaryActiveLine = this.currentPrimaryActiveLine;
|
|
4806
|
+
if (this.lastPrimaryActiveLine) {
|
|
4807
|
+
this.lastPrimaryActiveLine.style.setProperty(
|
|
4808
|
+
'--scroll-duration',
|
|
4809
|
+
`${scrollDuration ?? SCROLL_ANIMATION_DURATION_MS}ms`,
|
|
4810
|
+
);
|
|
4811
|
+
this.lastPrimaryActiveLine.classList.add('scroll-exiting');
|
|
4812
|
+
}
|
|
4730
4813
|
this.currentPrimaryActiveLine = lineElement;
|
|
4814
|
+
this.currentPrimaryActiveLine.classList.remove('scroll-exiting');
|
|
4731
4815
|
const lineIndex = AmLyrics.getLineIndexFromElement(lineElement);
|
|
4732
4816
|
if (lineIndex !== null) {
|
|
4733
4817
|
this.lastActiveIndex = lineIndex;
|
|
@@ -5095,7 +5179,7 @@ export class AmLyrics extends LitElement {
|
|
|
5095
5179
|
allLines.forEach(lineEl => {
|
|
5096
5180
|
AmLyrics.resetSyllables(lineEl as HTMLElement);
|
|
5097
5181
|
// Remove scroll-animate class and properties to stop any scroll animations
|
|
5098
|
-
lineEl.classList.remove('scroll-animate');
|
|
5182
|
+
lineEl.classList.remove('scroll-animate', 'scroll-exiting');
|
|
5099
5183
|
(lineEl as HTMLElement).style.removeProperty('--scroll-delta');
|
|
5100
5184
|
(lineEl as HTMLElement).style.removeProperty('--lyrics-line-delay');
|
|
5101
5185
|
});
|
|
@@ -5379,6 +5463,7 @@ export class AmLyrics extends LitElement {
|
|
|
5379
5463
|
scrollDuration ?? SCROLL_ANIMATION_DURATION_MS,
|
|
5380
5464
|
);
|
|
5381
5465
|
const delayIncrement = duration * 0.1;
|
|
5466
|
+
const maxStaggerSteps = 4;
|
|
5382
5467
|
const lookAhead = 20;
|
|
5383
5468
|
const len = lineArray.length;
|
|
5384
5469
|
|
|
@@ -5387,13 +5472,17 @@ export class AmLyrics extends LitElement {
|
|
|
5387
5472
|
|
|
5388
5473
|
let maxAnimationDuration = 0;
|
|
5389
5474
|
const newAnimatingLines: HTMLElement[] = [];
|
|
5475
|
+
const lineDelays = new Map<HTMLElement, number>();
|
|
5390
5476
|
const scrollingDown = delta >= 0;
|
|
5391
5477
|
|
|
5392
5478
|
if (scrollingDown) {
|
|
5393
5479
|
let delayCounter = 0;
|
|
5394
5480
|
for (let i = start; i < end; i += 1) {
|
|
5395
5481
|
const line = lineArray[i];
|
|
5396
|
-
const delay =
|
|
5482
|
+
const delay =
|
|
5483
|
+
i >= referenceIndex
|
|
5484
|
+
? Math.min(delayCounter, maxStaggerSteps) * delayIncrement
|
|
5485
|
+
: 0;
|
|
5397
5486
|
|
|
5398
5487
|
if (i >= referenceIndex && !line.classList.contains('lyrics-gap')) {
|
|
5399
5488
|
delayCounter += 1;
|
|
@@ -5401,11 +5490,11 @@ export class AmLyrics extends LitElement {
|
|
|
5401
5490
|
|
|
5402
5491
|
line.style.setProperty('--scroll-delta', `${delta}px`);
|
|
5403
5492
|
line.style.setProperty('--lyrics-line-delay', `${delay}ms`);
|
|
5404
|
-
|
|
5493
|
+
lineDelays.set(line, delay);
|
|
5405
5494
|
|
|
5406
5495
|
newAnimatingLines.push(line);
|
|
5407
5496
|
|
|
5408
|
-
const lineDuration = duration + delay;
|
|
5497
|
+
const lineDuration = duration + 100 + delay;
|
|
5409
5498
|
if (lineDuration > maxAnimationDuration) {
|
|
5410
5499
|
maxAnimationDuration = lineDuration;
|
|
5411
5500
|
}
|
|
@@ -5414,7 +5503,10 @@ export class AmLyrics extends LitElement {
|
|
|
5414
5503
|
let delayCounter = 0;
|
|
5415
5504
|
for (let i = end - 1; i >= start; i -= 1) {
|
|
5416
5505
|
const line = lineArray[i];
|
|
5417
|
-
const delay =
|
|
5506
|
+
const delay =
|
|
5507
|
+
i <= referenceIndex
|
|
5508
|
+
? Math.min(delayCounter, maxStaggerSteps) * delayIncrement
|
|
5509
|
+
: 0;
|
|
5418
5510
|
|
|
5419
5511
|
if (i <= referenceIndex && !line.classList.contains('lyrics-gap')) {
|
|
5420
5512
|
delayCounter += 1;
|
|
@@ -5422,17 +5514,27 @@ export class AmLyrics extends LitElement {
|
|
|
5422
5514
|
|
|
5423
5515
|
line.style.setProperty('--scroll-delta', `${delta}px`);
|
|
5424
5516
|
line.style.setProperty('--lyrics-line-delay', `${delay}ms`);
|
|
5425
|
-
|
|
5517
|
+
lineDelays.set(line, delay);
|
|
5426
5518
|
|
|
5427
5519
|
newAnimatingLines.push(line);
|
|
5428
5520
|
|
|
5429
|
-
const lineDuration = duration + delay;
|
|
5521
|
+
const lineDuration = duration + 100 + delay;
|
|
5430
5522
|
if (lineDuration > maxAnimationDuration) {
|
|
5431
5523
|
maxAnimationDuration = lineDuration;
|
|
5432
5524
|
}
|
|
5433
5525
|
}
|
|
5434
5526
|
}
|
|
5435
5527
|
|
|
5528
|
+
/* Preserve the staggered starts, but make every line settle together.
|
|
5529
|
+
This keeps the selected line from drifting after its neighbours. */
|
|
5530
|
+
for (const line of newAnimatingLines) {
|
|
5531
|
+
const delay = lineDelays.get(line) ?? 0;
|
|
5532
|
+
line.style.setProperty(
|
|
5533
|
+
'--scroll-duration',
|
|
5534
|
+
`${Math.max(100, maxAnimationDuration - delay)}ms`,
|
|
5535
|
+
);
|
|
5536
|
+
}
|
|
5537
|
+
|
|
5436
5538
|
// --- Step 3: Force reflow so the browser sees the class removal ---
|
|
5437
5539
|
// Use offsetHeight which is cheaper than getBoundingClientRect
|
|
5438
5540
|
// eslint-disable-next-line no-void
|
|
@@ -5810,16 +5912,18 @@ export class AmLyrics extends LitElement {
|
|
|
5810
5912
|
);
|
|
5811
5913
|
preWipeSyllable.classList.add('pre-highlight');
|
|
5812
5914
|
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5915
|
+
// Character-animated words still need a single word-leading gradient.
|
|
5916
|
+
// Giving every glyph this state creates one gradient per character and
|
|
5917
|
+
// makes the whole word enter the pre-wipe continuation simultaneously.
|
|
5918
|
+
if (leadChar) {
|
|
5919
|
+
AmLyrics.applyWipeShape(leadChar, charCount);
|
|
5920
|
+
leadChar.style.setProperty(
|
|
5921
|
+
'--pre-wipe-duration',
|
|
5922
|
+
`${preWipeDurationMs}ms`,
|
|
5923
|
+
);
|
|
5924
|
+
leadChar.style.setProperty('--pre-wipe-delay', `${-elapsedPreWipe}ms`);
|
|
5925
|
+
leadChar.classList.add('pre-wipe-lead');
|
|
5816
5926
|
}
|
|
5817
|
-
leadSpans.forEach(span => {
|
|
5818
|
-
AmLyrics.applyWipeShape(span, charCount);
|
|
5819
|
-
span.style.setProperty('--pre-wipe-duration', `${preWipeDurationMs}ms`);
|
|
5820
|
-
span.style.setProperty('--pre-wipe-delay', `${-elapsedPreWipe}ms`);
|
|
5821
|
-
span.classList.add('pre-wipe-lead');
|
|
5822
|
-
});
|
|
5823
5927
|
|
|
5824
5928
|
wordElements.forEach(element => {
|
|
5825
5929
|
const target = element as any;
|
|
@@ -6152,22 +6256,18 @@ export class AmLyrics extends LitElement {
|
|
|
6152
6256
|
0,
|
|
6153
6257
|
charWipeDurationMs - charStartMs,
|
|
6154
6258
|
);
|
|
6155
|
-
|
|
6156
|
-
|
|
6259
|
+
const wipeDelay = charStartMs - wordElapsedTimeMs;
|
|
6260
|
+
const wipeDuration = Math.min(
|
|
6157
6261
|
charWipeDurationMs * durationPct * wipeScale,
|
|
6158
6262
|
remainingWordWipeMs,
|
|
6159
6263
|
);
|
|
6160
6264
|
const useStartAnimation =
|
|
6161
6265
|
isFirstInContainer && globalCharIndex === 0 && !hadCharPreWipe;
|
|
6162
|
-
let charWipeAnimation = 'wipe';
|
|
6266
|
+
let charWipeAnimation = 'char-wipe';
|
|
6163
6267
|
if (hadCharPreWipe) {
|
|
6164
|
-
charWipeAnimation = 'wipe
|
|
6165
|
-
wipeDelay = -wordElapsedTimeMs;
|
|
6166
|
-
wipeDuration = charWipeDurationMs;
|
|
6268
|
+
charWipeAnimation = 'char-wipe';
|
|
6167
6269
|
} else if (useStartAnimation) {
|
|
6168
|
-
charWipeAnimation =
|
|
6169
|
-
} else {
|
|
6170
|
-
charWipeAnimation = isRTL ? 'wipe-rtl' : 'wipe';
|
|
6270
|
+
charWipeAnimation = 'char-start-wipe';
|
|
6171
6271
|
}
|
|
6172
6272
|
|
|
6173
6273
|
const existingAnimation =
|
|
@@ -6183,6 +6283,28 @@ export class AmLyrics extends LitElement {
|
|
|
6183
6283
|
) {
|
|
6184
6284
|
animationParts.push(existingAnimation.split(',')[0].trim());
|
|
6185
6285
|
}
|
|
6286
|
+
if (
|
|
6287
|
+
globalCharIndex > 0 &&
|
|
6288
|
+
!hadCharPreWipe &&
|
|
6289
|
+
wipeDelay > 0 &&
|
|
6290
|
+
wipeDuration > 0
|
|
6291
|
+
) {
|
|
6292
|
+
const measuredDuration = Number.parseFloat(
|
|
6293
|
+
span.dataset.preWipeDuration || '100',
|
|
6294
|
+
);
|
|
6295
|
+
const preWipeDuration = Math.min(
|
|
6296
|
+
measuredDuration,
|
|
6297
|
+
wipeDuration * 0.9,
|
|
6298
|
+
charWipeDurationMs * 0.08,
|
|
6299
|
+
wipeDelay,
|
|
6300
|
+
);
|
|
6301
|
+
|
|
6302
|
+
if (preWipeDuration >= 16) {
|
|
6303
|
+
animationParts.push(
|
|
6304
|
+
`char-pre-wipe ${preWipeDuration}ms linear ${wipeDelay - preWipeDuration}ms none`,
|
|
6305
|
+
);
|
|
6306
|
+
}
|
|
6307
|
+
}
|
|
6186
6308
|
if (wipeDuration > 0) {
|
|
6187
6309
|
const wipeFillMode = hadCharPreWipe ? 'both' : 'forwards';
|
|
6188
6310
|
animationParts.push(
|