@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AmLyrics.d.ts","sourceRoot":"","sources":["../../src/AmLyrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAO,MAAM,KAAK,CAAC;AAkHjD,qBAAa,QAAS,SAAQ,UAAU;IACtC,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"AmLyrics.d.ts","sourceRoot":"","sources":["../../src/AmLyrics.ts"],"names":[],"mappings":"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"}
|
package/dist/src/am-lyrics.js
CHANGED
|
@@ -319,7 +319,7 @@ class GoogleService {
|
|
|
319
319
|
}
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
const VERSION = '1.5.
|
|
322
|
+
const VERSION = '1.5.6';
|
|
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;
|
|
@@ -336,7 +336,7 @@ const LONG_WORD_WIPE_EXTRA_EM = 0.45;
|
|
|
336
336
|
const LONG_WORD_WIPE_EXTRA_RATIO = 0.35;
|
|
337
337
|
const SHORT_WORD_DRAG_MIN_DURATION_MS = 760;
|
|
338
338
|
const SHORT_WORD_GLOW_MIN_DURATION_MS = 1320;
|
|
339
|
-
const WORD_PRE_WIPE_HANDOFF_LEAD_MS =
|
|
339
|
+
const WORD_PRE_WIPE_HANDOFF_LEAD_MS = 100;
|
|
340
340
|
/**
|
|
341
341
|
* Fetch with an automatic timeout via AbortSignal.
|
|
342
342
|
* Rejects if the request takes longer than `timeoutMs`.
|
|
@@ -499,9 +499,9 @@ class AmLyrics extends i {
|
|
|
499
499
|
this.clearBackgroundExpandedLine();
|
|
500
500
|
// Stop all running animations and clear highlights immediately
|
|
501
501
|
if (this.lyricsContainer) {
|
|
502
|
-
const activeLines = this.lyricsContainer.querySelectorAll('.lyrics-line.active, .lyrics-line.pre-active, .lyrics-line.bg-expanded');
|
|
502
|
+
const activeLines = this.lyricsContainer.querySelectorAll('.lyrics-line.active, .lyrics-line.pre-active, .lyrics-line.bg-expanded, .lyrics-line.scroll-exiting');
|
|
503
503
|
activeLines.forEach(line => {
|
|
504
|
-
line.classList.remove('active', 'pre-active', 'bg-expanded');
|
|
504
|
+
line.classList.remove('active', 'pre-active', 'bg-expanded', 'scroll-exiting');
|
|
505
505
|
AmLyrics.resetSyllables(line);
|
|
506
506
|
});
|
|
507
507
|
const activeGaps = this.lyricsContainer.querySelectorAll('.lyrics-gap.active, .lyrics-gap.gap-exiting');
|
|
@@ -1953,7 +1953,7 @@ class AmLyrics extends i {
|
|
|
1953
1953
|
else {
|
|
1954
1954
|
AmLyrics.finishSyllablesUpToTime(lineElement, newTime);
|
|
1955
1955
|
}
|
|
1956
|
-
lineElement.classList.remove('active', 'bg-expanded');
|
|
1956
|
+
lineElement.classList.remove('active', 'bg-expanded', 'scroll-exiting');
|
|
1957
1957
|
if (lineElement.classList.contains('pre-active')) {
|
|
1958
1958
|
lineElement.classList.remove('pre-active');
|
|
1959
1959
|
}
|
|
@@ -1970,7 +1970,7 @@ class AmLyrics extends i {
|
|
|
1970
1970
|
const lineElement = this._getLineElement(lineIndex);
|
|
1971
1971
|
if (lineElement) {
|
|
1972
1972
|
lineElement.classList.add('active');
|
|
1973
|
-
lineElement.classList.remove('pre-active');
|
|
1973
|
+
lineElement.classList.remove('pre-active', 'scroll-exiting');
|
|
1974
1974
|
const preIdx = this.preActiveLineElements.indexOf(lineElement);
|
|
1975
1975
|
if (preIdx !== -1)
|
|
1976
1976
|
this.preActiveLineElements.splice(preIdx, 1);
|
|
@@ -2175,7 +2175,11 @@ class AmLyrics extends i {
|
|
|
2175
2175
|
}
|
|
2176
2176
|
}
|
|
2177
2177
|
updated(changedProperties) {
|
|
2178
|
-
|
|
2178
|
+
const lyricsDomBecameRenderable = changedProperties.has('lyrics') ||
|
|
2179
|
+
(changedProperties.has('isLoading') &&
|
|
2180
|
+
!this.isLoading &&
|
|
2181
|
+
Boolean(this.lyrics));
|
|
2182
|
+
if (lyricsDomBecameRenderable) {
|
|
2179
2183
|
this._invalidateCaches();
|
|
2180
2184
|
this._ensureLineDataCache();
|
|
2181
2185
|
this._updateCachedIsUnsynced();
|
|
@@ -2334,7 +2338,9 @@ class AmLyrics extends i {
|
|
|
2334
2338
|
return;
|
|
2335
2339
|
}
|
|
2336
2340
|
const scrollDuration = scrollLookAheadMs;
|
|
2337
|
-
targetElement.
|
|
2341
|
+
if (targetElement !== this.currentPrimaryActiveLine || forceScroll) {
|
|
2342
|
+
targetElement.style.setProperty('--scroll-duration', `${scrollDuration}ms`);
|
|
2343
|
+
}
|
|
2338
2344
|
this.setBackgroundExpandedLine(targetElement);
|
|
2339
2345
|
// Unblur the upcoming target line early while the separate bg-expanded
|
|
2340
2346
|
// class starts background vocal height/opacity in sync with scroll.
|
|
@@ -2559,6 +2565,7 @@ class AmLyrics extends i {
|
|
|
2559
2565
|
return;
|
|
2560
2566
|
const computedStyle = getComputedStyle(referenceSyllable);
|
|
2561
2567
|
const { font } = computedStyle; // Full font string
|
|
2568
|
+
const fontSize = Number.parseFloat(computedStyle.fontSize) || 16;
|
|
2562
2569
|
const charTimedWords = Array.from(this.shadowRoot.querySelectorAll('.lyrics-word.growable, .lyrics-word.char-rise, .lyrics-word.char-drag'));
|
|
2563
2570
|
if (charTimedWords.length === 0)
|
|
2564
2571
|
return;
|
|
@@ -2622,6 +2629,13 @@ class AmLyrics extends i {
|
|
|
2622
2629
|
const hasTimedSyllables = Number.isFinite(virtualWordStart) &&
|
|
2623
2630
|
Number.isFinite(virtualWordEnd) &&
|
|
2624
2631
|
virtualWordDuration > 0;
|
|
2632
|
+
const wordVelocityPxPerMs = hasTimedSyllables
|
|
2633
|
+
? totalWordWidth / virtualWordDuration
|
|
2634
|
+
: 0;
|
|
2635
|
+
const gradientLeadWidthPx = (BASE_WIPE_GRADIENT_EM * Math.max(1, fontSize)) / 2;
|
|
2636
|
+
const measuredPreWipeDuration = wordVelocityPxPerMs > 0
|
|
2637
|
+
? gradientLeadWidthPx / wordVelocityPxPerMs
|
|
2638
|
+
: 100;
|
|
2625
2639
|
let cumulativeCharWidth = 0;
|
|
2626
2640
|
syllableEntries.forEach(entry => {
|
|
2627
2641
|
let cumulativeSyllableWidth = 0;
|
|
@@ -2646,6 +2660,7 @@ class AmLyrics extends i {
|
|
|
2646
2660
|
const target = span;
|
|
2647
2661
|
target.dataset.wipeStart = startPercent.toFixed(4);
|
|
2648
2662
|
target.dataset.wipeDuration = durationPercent.toFixed(4);
|
|
2663
|
+
target.dataset.preWipeDuration = measuredPreWipeDuration.toFixed(2);
|
|
2649
2664
|
target.style.setProperty('--word-wipe-width', `${totalWordWidth}px`);
|
|
2650
2665
|
target.style.setProperty('--char-wipe-position', `${-cumulativeCharWidth}px`);
|
|
2651
2666
|
cumulativeCharWidth += charWidth;
|
|
@@ -2810,7 +2825,12 @@ class AmLyrics extends i {
|
|
|
2810
2825
|
// effectiveEndTimes). Lines stay active until their extended end,
|
|
2811
2826
|
// so we no longer need to remove .active here.
|
|
2812
2827
|
this.lastPrimaryActiveLine = this.currentPrimaryActiveLine;
|
|
2828
|
+
if (this.lastPrimaryActiveLine) {
|
|
2829
|
+
this.lastPrimaryActiveLine.style.setProperty('--scroll-duration', `${scrollDuration ?? SCROLL_ANIMATION_DURATION_MS}ms`);
|
|
2830
|
+
this.lastPrimaryActiveLine.classList.add('scroll-exiting');
|
|
2831
|
+
}
|
|
2813
2832
|
this.currentPrimaryActiveLine = lineElement;
|
|
2833
|
+
this.currentPrimaryActiveLine.classList.remove('scroll-exiting');
|
|
2814
2834
|
const lineIndex = AmLyrics.getLineIndexFromElement(lineElement);
|
|
2815
2835
|
if (lineIndex !== null) {
|
|
2816
2836
|
this.lastActiveIndex = lineIndex;
|
|
@@ -3123,7 +3143,7 @@ class AmLyrics extends i {
|
|
|
3123
3143
|
allLines.forEach(lineEl => {
|
|
3124
3144
|
AmLyrics.resetSyllables(lineEl);
|
|
3125
3145
|
// Remove scroll-animate class and properties to stop any scroll animations
|
|
3126
|
-
lineEl.classList.remove('scroll-animate');
|
|
3146
|
+
lineEl.classList.remove('scroll-animate', 'scroll-exiting');
|
|
3127
3147
|
lineEl.style.removeProperty('--scroll-delta');
|
|
3128
3148
|
lineEl.style.removeProperty('--lyrics-line-delay');
|
|
3129
3149
|
});
|
|
@@ -3346,26 +3366,30 @@ class AmLyrics extends i {
|
|
|
3346
3366
|
return;
|
|
3347
3367
|
const duration = Math.min(450, scrollDuration ?? SCROLL_ANIMATION_DURATION_MS);
|
|
3348
3368
|
const delayIncrement = duration * 0.1;
|
|
3369
|
+
const maxStaggerSteps = 4;
|
|
3349
3370
|
const lookAhead = 20;
|
|
3350
3371
|
const len = lineArray.length;
|
|
3351
3372
|
const start = Math.max(0, referenceIndex - lookAhead);
|
|
3352
3373
|
const end = Math.min(len, referenceIndex + lookAhead);
|
|
3353
3374
|
let maxAnimationDuration = 0;
|
|
3354
3375
|
const newAnimatingLines = [];
|
|
3376
|
+
const lineDelays = new Map();
|
|
3355
3377
|
const scrollingDown = delta >= 0;
|
|
3356
3378
|
if (scrollingDown) {
|
|
3357
3379
|
let delayCounter = 0;
|
|
3358
3380
|
for (let i = start; i < end; i += 1) {
|
|
3359
3381
|
const line = lineArray[i];
|
|
3360
|
-
const delay = i >= referenceIndex
|
|
3382
|
+
const delay = i >= referenceIndex
|
|
3383
|
+
? Math.min(delayCounter, maxStaggerSteps) * delayIncrement
|
|
3384
|
+
: 0;
|
|
3361
3385
|
if (i >= referenceIndex && !line.classList.contains('lyrics-gap')) {
|
|
3362
3386
|
delayCounter += 1;
|
|
3363
3387
|
}
|
|
3364
3388
|
line.style.setProperty('--scroll-delta', `${delta}px`);
|
|
3365
3389
|
line.style.setProperty('--lyrics-line-delay', `${delay}ms`);
|
|
3366
|
-
|
|
3390
|
+
lineDelays.set(line, delay);
|
|
3367
3391
|
newAnimatingLines.push(line);
|
|
3368
|
-
const lineDuration = duration + delay;
|
|
3392
|
+
const lineDuration = duration + 100 + delay;
|
|
3369
3393
|
if (lineDuration > maxAnimationDuration) {
|
|
3370
3394
|
maxAnimationDuration = lineDuration;
|
|
3371
3395
|
}
|
|
@@ -3375,20 +3399,28 @@ class AmLyrics extends i {
|
|
|
3375
3399
|
let delayCounter = 0;
|
|
3376
3400
|
for (let i = end - 1; i >= start; i -= 1) {
|
|
3377
3401
|
const line = lineArray[i];
|
|
3378
|
-
const delay = i <= referenceIndex
|
|
3402
|
+
const delay = i <= referenceIndex
|
|
3403
|
+
? Math.min(delayCounter, maxStaggerSteps) * delayIncrement
|
|
3404
|
+
: 0;
|
|
3379
3405
|
if (i <= referenceIndex && !line.classList.contains('lyrics-gap')) {
|
|
3380
3406
|
delayCounter += 1;
|
|
3381
3407
|
}
|
|
3382
3408
|
line.style.setProperty('--scroll-delta', `${delta}px`);
|
|
3383
3409
|
line.style.setProperty('--lyrics-line-delay', `${delay}ms`);
|
|
3384
|
-
|
|
3410
|
+
lineDelays.set(line, delay);
|
|
3385
3411
|
newAnimatingLines.push(line);
|
|
3386
|
-
const lineDuration = duration + delay;
|
|
3412
|
+
const lineDuration = duration + 100 + delay;
|
|
3387
3413
|
if (lineDuration > maxAnimationDuration) {
|
|
3388
3414
|
maxAnimationDuration = lineDuration;
|
|
3389
3415
|
}
|
|
3390
3416
|
}
|
|
3391
3417
|
}
|
|
3418
|
+
/* Preserve the staggered starts, but make every line settle together.
|
|
3419
|
+
This keeps the selected line from drifting after its neighbours. */
|
|
3420
|
+
for (const line of newAnimatingLines) {
|
|
3421
|
+
const delay = lineDelays.get(line) ?? 0;
|
|
3422
|
+
line.style.setProperty('--scroll-duration', `${Math.max(100, maxAnimationDuration - delay)}ms`);
|
|
3423
|
+
}
|
|
3392
3424
|
// --- Step 3: Force reflow so the browser sees the class removal ---
|
|
3393
3425
|
// Use offsetHeight which is cheaper than getBoundingClientRect
|
|
3394
3426
|
// eslint-disable-next-line no-void
|
|
@@ -3648,16 +3680,15 @@ class AmLyrics extends i {
|
|
|
3648
3680
|
preWipeSyllable.style.setProperty('--pre-wipe-duration', `${preWipeDurationMs}ms`);
|
|
3649
3681
|
preWipeSyllable.style.setProperty('--pre-wipe-delay', `${-elapsedPreWipe}ms`);
|
|
3650
3682
|
preWipeSyllable.classList.add('pre-highlight');
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
});
|
|
3683
|
+
// Character-animated words still need a single word-leading gradient.
|
|
3684
|
+
// Giving every glyph this state creates one gradient per character and
|
|
3685
|
+
// makes the whole word enter the pre-wipe continuation simultaneously.
|
|
3686
|
+
if (leadChar) {
|
|
3687
|
+
AmLyrics.applyWipeShape(leadChar, charCount);
|
|
3688
|
+
leadChar.style.setProperty('--pre-wipe-duration', `${preWipeDurationMs}ms`);
|
|
3689
|
+
leadChar.style.setProperty('--pre-wipe-delay', `${-elapsedPreWipe}ms`);
|
|
3690
|
+
leadChar.classList.add('pre-wipe-lead');
|
|
3691
|
+
}
|
|
3661
3692
|
wordElements.forEach(element => {
|
|
3662
3693
|
const target = element;
|
|
3663
3694
|
target._wordPreWipeKey = AmLyrics.getWordPreWipeKey(nextSyllable);
|
|
@@ -3869,20 +3900,15 @@ class AmLyrics extends i {
|
|
|
3869
3900
|
(hadPreHighlight && globalCharIndex === 0);
|
|
3870
3901
|
const charStartMs = charWipeDurationMs * startPct;
|
|
3871
3902
|
const remainingWordWipeMs = Math.max(0, charWipeDurationMs - charStartMs);
|
|
3872
|
-
|
|
3873
|
-
|
|
3903
|
+
const wipeDelay = charStartMs - wordElapsedTimeMs;
|
|
3904
|
+
const wipeDuration = Math.min(charWipeDurationMs * durationPct * wipeScale, remainingWordWipeMs);
|
|
3874
3905
|
const useStartAnimation = isFirstInContainer && globalCharIndex === 0 && !hadCharPreWipe;
|
|
3875
|
-
let charWipeAnimation = 'wipe';
|
|
3906
|
+
let charWipeAnimation = 'char-wipe';
|
|
3876
3907
|
if (hadCharPreWipe) {
|
|
3877
|
-
charWipeAnimation = 'wipe
|
|
3878
|
-
wipeDelay = -wordElapsedTimeMs;
|
|
3879
|
-
wipeDuration = charWipeDurationMs;
|
|
3908
|
+
charWipeAnimation = 'char-wipe';
|
|
3880
3909
|
}
|
|
3881
3910
|
else if (useStartAnimation) {
|
|
3882
|
-
charWipeAnimation =
|
|
3883
|
-
}
|
|
3884
|
-
else {
|
|
3885
|
-
charWipeAnimation = isRTL ? 'wipe-rtl' : 'wipe';
|
|
3911
|
+
charWipeAnimation = 'char-start-wipe';
|
|
3886
3912
|
}
|
|
3887
3913
|
const existingAnimation = charAnimationsMap.get(span) || span.style.animation || '';
|
|
3888
3914
|
const animationParts = [];
|
|
@@ -3892,6 +3918,16 @@ class AmLyrics extends i {
|
|
|
3892
3918
|
existingAnimation.includes('drag-char'))) {
|
|
3893
3919
|
animationParts.push(existingAnimation.split(',')[0].trim());
|
|
3894
3920
|
}
|
|
3921
|
+
if (globalCharIndex > 0 &&
|
|
3922
|
+
!hadCharPreWipe &&
|
|
3923
|
+
wipeDelay > 0 &&
|
|
3924
|
+
wipeDuration > 0) {
|
|
3925
|
+
const measuredDuration = Number.parseFloat(span.dataset.preWipeDuration || '100');
|
|
3926
|
+
const preWipeDuration = Math.min(measuredDuration, wipeDuration * 0.9, charWipeDurationMs * 0.08, wipeDelay);
|
|
3927
|
+
if (preWipeDuration >= 16) {
|
|
3928
|
+
animationParts.push(`char-pre-wipe ${preWipeDuration}ms linear ${wipeDelay - preWipeDuration}ms none`);
|
|
3929
|
+
}
|
|
3930
|
+
}
|
|
3895
3931
|
if (wipeDuration > 0) {
|
|
3896
3932
|
const wipeFillMode = hadCharPreWipe ? 'both' : 'forwards';
|
|
3897
3933
|
animationParts.push(`${charWipeAnimation} ${wipeDuration}ms linear ${wipeDelay}ms ${wipeFillMode}`);
|
|
@@ -5195,6 +5231,18 @@ AmLyrics.styles = i$3 `
|
|
|
5195
5231
|
opacity: 1;
|
|
5196
5232
|
}
|
|
5197
5233
|
|
|
5234
|
+
/* Predictive scrolling begins before the next timestamp. Start dimming
|
|
5235
|
+
the outgoing line at the same moment so it settles with the scroll. */
|
|
5236
|
+
.lyrics-line.scroll-exiting {
|
|
5237
|
+
opacity: 0.8;
|
|
5238
|
+
color: var(--lyplus-text-secondary);
|
|
5239
|
+
transition:
|
|
5240
|
+
opacity var(--scroll-duration, 400ms) cubic-bezier(0.41, 0, 0.12, 0.99),
|
|
5241
|
+
transform var(--scroll-duration, 400ms)
|
|
5242
|
+
cubic-bezier(0.41, 0, 0.12, 0.99) var(--lyrics-line-delay, 0ms),
|
|
5243
|
+
filter var(--scroll-duration, 400ms) ease;
|
|
5244
|
+
}
|
|
5245
|
+
|
|
5198
5246
|
.lyrics-line.persist-highlight {
|
|
5199
5247
|
filter: none !important;
|
|
5200
5248
|
opacity: 1;
|
|
@@ -5625,15 +5673,24 @@ AmLyrics.styles = i$3 `
|
|
|
5625
5673
|
background-clip: text;
|
|
5626
5674
|
-webkit-background-clip: text;
|
|
5627
5675
|
background-repeat: no-repeat;
|
|
5628
|
-
background-image:
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5676
|
+
background-image:
|
|
5677
|
+
linear-gradient(
|
|
5678
|
+
90deg,
|
|
5679
|
+
#ffffff00 0%,
|
|
5680
|
+
var(--lyplus-text-primary, #fff) 50%,
|
|
5681
|
+
#0000 100%
|
|
5682
|
+
),
|
|
5683
|
+
linear-gradient(
|
|
5684
|
+
90deg,
|
|
5685
|
+
var(--lyplus-text-primary, #fff) 100%,
|
|
5686
|
+
#0000 100%
|
|
5687
|
+
);
|
|
5688
|
+
background-size:
|
|
5689
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
5690
|
+
0% 100%;
|
|
5691
|
+
background-position:
|
|
5692
|
+
calc(-1 * var(--wipe-gradient-width, 0.75em)) 0%,
|
|
5693
|
+
left;
|
|
5637
5694
|
transition:
|
|
5638
5695
|
transform 0.7s ease,
|
|
5639
5696
|
color 0.18s;
|
|
@@ -5652,20 +5709,11 @@ AmLyrics.styles = i$3 `
|
|
|
5652
5709
|
}
|
|
5653
5710
|
|
|
5654
5711
|
.lyrics-line.active .lyrics-syllable span.char.pre-wipe-lead {
|
|
5655
|
-
animation-name: pre-wipe
|
|
5712
|
+
animation-name: char-pre-wipe;
|
|
5656
5713
|
animation-duration: var(--pre-wipe-duration);
|
|
5657
5714
|
animation-delay: var(--pre-wipe-delay);
|
|
5658
5715
|
animation-timing-function: linear;
|
|
5659
5716
|
animation-fill-mode: forwards;
|
|
5660
|
-
background-image: linear-gradient(
|
|
5661
|
-
90deg,
|
|
5662
|
-
var(--lyplus-text-primary, #fff) 0%,
|
|
5663
|
-
var(--lyplus-text-primary, #fff)
|
|
5664
|
-
calc(100% - var(--wipe-gradient-width, 0.75em)),
|
|
5665
|
-
#0000 100%
|
|
5666
|
-
);
|
|
5667
|
-
background-size: 0% 100%;
|
|
5668
|
-
background-position: var(--char-wipe-position, left) 0%;
|
|
5669
5717
|
}
|
|
5670
5718
|
|
|
5671
5719
|
/* ==========================================================================
|
|
@@ -6202,30 +6250,63 @@ AmLyrics.styles = i$3 `
|
|
|
6202
6250
|
}
|
|
6203
6251
|
}
|
|
6204
6252
|
|
|
6205
|
-
|
|
6253
|
+
/* Character-rendered words use a separate moving gradient in front of
|
|
6254
|
+
their solid fill. This makes the individual glyph wipes read as one
|
|
6255
|
+
continuous word-level wipe. */
|
|
6256
|
+
@keyframes char-pre-wipe {
|
|
6206
6257
|
from {
|
|
6207
|
-
background-size:
|
|
6208
|
-
|
|
6258
|
+
background-size:
|
|
6259
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
6260
|
+
0% 100%;
|
|
6261
|
+
background-position:
|
|
6262
|
+
calc(-1 * var(--wipe-gradient-width, 0.75em)) 0%,
|
|
6263
|
+
left;
|
|
6209
6264
|
}
|
|
6210
6265
|
to {
|
|
6211
|
-
background-size:
|
|
6212
|
-
100
|
|
6213
|
-
|
|
6266
|
+
background-size:
|
|
6267
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
6268
|
+
0% 100%;
|
|
6269
|
+
background-position:
|
|
6270
|
+
calc(-1 * var(--wipe-gradient-half, 0.375em)) 0%,
|
|
6271
|
+
left;
|
|
6214
6272
|
}
|
|
6215
6273
|
}
|
|
6216
6274
|
|
|
6217
|
-
@keyframes
|
|
6275
|
+
@keyframes char-start-wipe {
|
|
6218
6276
|
from {
|
|
6219
|
-
background-size:
|
|
6220
|
-
100
|
|
6221
|
-
|
|
6277
|
+
background-size:
|
|
6278
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
6279
|
+
0% 100%;
|
|
6280
|
+
background-position:
|
|
6281
|
+
calc(-1 * var(--wipe-gradient-width, 0.75em)) 0%,
|
|
6282
|
+
left;
|
|
6222
6283
|
}
|
|
6223
6284
|
to {
|
|
6224
|
-
background-size:
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6285
|
+
background-size:
|
|
6286
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
6287
|
+
100% 100%;
|
|
6288
|
+
background-position:
|
|
6289
|
+
calc(100% + var(--wipe-gradient-half, 0.375em)) 0%,
|
|
6290
|
+
left;
|
|
6291
|
+
}
|
|
6292
|
+
}
|
|
6293
|
+
|
|
6294
|
+
@keyframes char-wipe {
|
|
6295
|
+
from {
|
|
6296
|
+
background-size:
|
|
6297
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
6298
|
+
0% 100%;
|
|
6299
|
+
background-position:
|
|
6300
|
+
calc(-1 * var(--wipe-gradient-half, 0.375em)) 0%,
|
|
6301
|
+
left;
|
|
6302
|
+
}
|
|
6303
|
+
to {
|
|
6304
|
+
background-size:
|
|
6305
|
+
var(--wipe-gradient-width, 0.75em) 100%,
|
|
6306
|
+
100% 100%;
|
|
6307
|
+
background-position:
|
|
6308
|
+
calc(100% + var(--wipe-gradient-half, 0.375em)) 0%,
|
|
6309
|
+
left;
|
|
6229
6310
|
}
|
|
6230
6311
|
}
|
|
6231
6312
|
|